Skip to content

Add bounds checking for arduino_pins array access in digital_pin_gpios path#6

Merged
soburi merged 4 commits intoconfigure_by_connector_deffrom
copilot/sub-pr-4-again
Feb 10, 2026
Merged

Add bounds checking for arduino_pins array access in digital_pin_gpios path#6
soburi merged 4 commits intoconfigure_by_connector_deffrom
copilot/sub-pr-4-again

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 10, 2026

Addresses feedback from PR #4 regarding missing bounds validation when accessing arduino_pins[gpin] in the digital_pin_gpios configuration path. Without bounds checking, invalid pin numbers cause out-of-bounds memory access across multiple call sites (digitalWrite/Read, interrupts, tone, etc.).

Changes

  • local_gpio_port(): Return nullptr when gpin >= ARRAY_SIZE(arduino_pins)
  • local_gpio_pin(): Return pin_size_t(-1) when gpin >= ARRAY_SIZE(arduino_pins)
  • global_gpio_pin_configure(): Early return -1 before array access when pinNumber >= ARRAY_SIZE(arduino_pins)

The non-digital_pin_gpios path already had implicit bounds checking through local_gpio_port_r() recursion. find_gpio_port_callback() null checking was added in commit c38fdbb.

// Before
constexpr inline const struct device *local_gpio_port(pin_size_t gpin) {
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
  return arduino_pins[gpin].port;  // Direct access, no bounds check
#else
  return local_gpio_port_r(gpin, gpio_ports, 0, gpio_ngpios, ARRAY_SIZE(gpio_ports));
#endif
}

// After  
constexpr inline const struct device *local_gpio_port(pin_size_t gpin) {
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
  return (gpin < ARRAY_SIZE(arduino_pins)) ? arduino_pins[gpin].port : nullptr;
#else
  return local_gpio_port_r(gpin, gpio_ports, 0, gpio_ngpios, ARRAY_SIZE(gpio_ports));
#endif
}

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits February 10, 2026 22:42
…rray

Co-authored-by: soburi <458281+soburi@users.noreply.github.com>
Co-authored-by: soburi <458281+soburi@users.noreply.github.com>
Co-authored-by: soburi <458281+soburi@users.noreply.github.com>
Copilot AI changed the title [WIP] Update find_gpio_port_callback null checking in connector def config Add bounds checking for arduino_pins array access in digital_pin_gpios path Feb 10, 2026
Copilot AI requested a review from soburi February 10, 2026 22:44
@soburi soburi marked this pull request as ready for review February 10, 2026 22:46
Copilot AI review requested due to automatic review settings February 10, 2026 22:46
@soburi soburi merged commit d652dbd into configure_by_connector_def Feb 10, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds bounds validation for digital_pin_gpios-backed pin mapping to prevent out-of-bounds access of arduino_pins[] in the Zephyr Arduino core.

Changes:

  • Add bounds checks to local_gpio_port() / local_gpio_pin() for digital_pin_gpios builds.
  • Add early return in global_gpio_pin_configure() to avoid out-of-range arduino_pins[] indexing.
  • Ignore CodeQL-generated build/source-root artifacts in .gitignore.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated 2 comments.

File Description
cores/arduino/zephyrCommon.cpp Adds bounds checks for arduino_pins[] access in the digital_pin_gpios path.
.gitignore Ignores CodeQL artifact directories/files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 132 to +136
inline int global_gpio_pin_configure(pin_size_t pinNumber, int flags) {
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
if (pinNumber >= ARRAY_SIZE(arduino_pins)) {
return -1;
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the digital_pin_gpios path, global_gpio_pin_configure() returns -1 for an invalid pinNumber. Elsewhere in this file invalid arguments typically return -EINVAL/-ENOTSUP (e.g. analogRead()), and Zephyr GPIO APIs return negative errno codes. Consider returning -EINVAL here as well to keep error semantics consistent (even if most callers currently ignore the return value).

Copilot uses AI. Check for mistakes.
Comment on lines 116 to +118
constexpr inline const struct device *local_gpio_port(pin_size_t gpin) {
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
return arduino_pins[gpin].port;
return (gpin < ARRAY_SIZE(arduino_pins)) ? arduino_pins[gpin].port : nullptr;
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

local_gpio_port() now returns nullptr and local_gpio_pin() can return pin_size_t(-1) for out-of-range pins, but at least one call site (e.g. attachInterrupt()) assumes a valid port/pin: it asserts pcb != nullptr even when port is nullptr, and then does BIT(local_gpio_pin(pinNumber)) which becomes a shift by -1. Please add consistent guards in callers (or in a shared helper) to early-return when local_gpio_port() is null and/or local_gpio_pin() is -1 before any indexing/bit-shifts/dereferences.

Copilot uses AI. Check for mistakes.
@soburi soburi deleted the copilot/sub-pr-4-again branch February 11, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants