Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

driver: gpio: emul: Add input validation for GPIO calls #82388

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions drivers/gpio/gpio_emul.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,22 @@ int gpio_emul_input_set_masked(const struct device *port, gpio_port_pins_t mask,
gpio_port_value_t values)
{
struct gpio_emul_data *drv_data = (struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config = (const struct gpio_emul_config *)port->config;
gpio_port_pins_t prev_input_values;
gpio_port_pins_t input_values;
k_spinlock_key_t key;
int rv;

if (mask == 0) {
return 0;
}

if (~config->common.port_pin_mask & mask) {
LOG_ERR("Pin not supported port_pin_mask=%x mask=%x",
config->common.port_pin_mask, mask);
return -EINVAL;
}

key = k_spin_lock(&drv_data->lock);
prev_input_values = drv_data->input_vals;
rv = gpio_emul_input_set_masked_int(port, mask, values);
Expand Down Expand Up @@ -473,6 +484,13 @@ static int gpio_emul_pin_get_config(const struct device *port, gpio_pin_t pin,
{
struct gpio_emul_data *drv_data =
(struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config =
(const struct gpio_emul_config *)port->config;

if ((config->common.port_pin_mask & BIT(pin)) == 0) {
return -EINVAL;
}

k_spinlock_key_t key;

key = k_spin_lock(&drv_data->lock);
Expand Down Expand Up @@ -522,9 +540,16 @@ static int gpio_emul_port_set_masked_raw(const struct device *port,
gpio_port_pins_t input_mask;
struct gpio_emul_data *drv_data =
(struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config =
(const struct gpio_emul_config *)port->config;

k_spinlock_key_t key;
int rv;

if (~config->common.port_pin_mask & mask) {
return -EINVAL;
}

key = k_spin_lock(&drv_data->lock);
output_mask = get_output_pins(port);
mask &= output_mask;
Expand Down Expand Up @@ -556,12 +581,19 @@ static int gpio_emul_port_set_bits_raw(const struct device *port,
{
struct gpio_emul_data *drv_data =
(struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config =
(const struct gpio_emul_config *)port->config;

k_spinlock_key_t key;
gpio_port_pins_t prev_input_values;
gpio_port_pins_t input_values;
gpio_port_pins_t input_mask;
int rv;

if (~config->common.port_pin_mask & pins) {
return -EINVAL;
}

key = k_spin_lock(&drv_data->lock);
pins &= get_output_pins(port);
drv_data->output_vals |= pins;
Expand All @@ -584,12 +616,19 @@ static int gpio_emul_port_clear_bits_raw(const struct device *port,
{
struct gpio_emul_data *drv_data =
(struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config =
(const struct gpio_emul_config *)port->config;

k_spinlock_key_t key;
gpio_port_pins_t prev_input_values;
gpio_port_pins_t input_values;
gpio_port_pins_t input_mask;
int rv;

if (~config->common.port_pin_mask & pins) {
return -EINVAL;
}

key = k_spin_lock(&drv_data->lock);
pins &= get_output_pins(port);
drv_data->output_vals &= ~pins;
Expand All @@ -610,9 +649,16 @@ static int gpio_emul_port_toggle_bits(const struct device *port, gpio_port_pins_
{
struct gpio_emul_data *drv_data =
(struct gpio_emul_data *)port->data;
const struct gpio_emul_config *config =
(const struct gpio_emul_config *)port->config;

k_spinlock_key_t key;
int rv;

if (~config->common.port_pin_mask & pins) {
return -EINVAL;
}

key = k_spin_lock(&drv_data->lock);
drv_data->output_vals ^= (pins & get_output_pins(port));
/* in push-pull, set input values but do not fire interrupts (yet) */
Expand Down
Loading