From b99ae798062c28e1000d3f9c5abe4a28da2f5ee1 Mon Sep 17 00:00:00 2001 From: kurte Date: Thu, 10 Aug 2023 12:41:57 -0700 Subject: [PATCH] Bounds checking on g_pin_cfg array As I mentioned in the forum thread: https://forum.arduino.cc/t/apis-like-digitalwrite-who-use-g-pinc-cfg-should-do-bounds-checking/1156322 I believe that many of the simple functions should have some form of parameter testing. For example: pinMode(100, OUTPUT); Should fail instead of trying to use random garbage off the end of the array to pass down to the next level. As @per1234 mentioned on the forum thread. This has bounced around for years: https://github.com/arduino/ArduinoCore-avr/pull/302 So decided to at least try to do it for a few of the APIs that have this issue. Most of the other references to this array appear to either check or are driven by pin information in definded in the variant. --- cores/arduino/analog.cpp | 1 + cores/arduino/digital.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/cores/arduino/analog.cpp b/cores/arduino/analog.cpp index cd61c281..ce399572 100644 --- a/cores/arduino/analog.cpp +++ b/cores/arduino/analog.cpp @@ -799,6 +799,7 @@ void analogWrite(pin_size_t pinNumber, int value) if(ptr != nullptr) { //check the pinmux in case it's been modified by a call to pinMode() + if (pinNumber >= (g_pin_cfg_size / sizeof(g_pin_cfg[0]))) return; /* pinNumber > sizeof of pin table */ bool has_peripheral_mux = R_PFS->PORT[g_pin_cfg[pinNumber].pin >> IOPORT_PRV_PORT_OFFSET].PIN[g_pin_cfg[pinNumber].pin & BSP_IO_PRV_8BIT_MASK].PmnPFS & IOPORT_CFG_PERIPHERAL_PIN; if (!has_peripheral_mux) { ptr->end(); diff --git a/cores/arduino/digital.cpp b/cores/arduino/digital.cpp index fceeb5d2..fbb7867b 100644 --- a/cores/arduino/digital.cpp +++ b/cores/arduino/digital.cpp @@ -1,6 +1,7 @@ #include "Arduino.h" void pinMode(pin_size_t pin, const PinMode mode) { + if (pin >= (g_pin_cfg_size / sizeof(g_pin_cfg[0]))) return; /* pinNumber > sizeof of pin table */ switch (mode) { case INPUT: case INPUT_PULLDOWN: // TODO: document the INPUT_PULLDOWN is unavailable @@ -19,10 +20,12 @@ void pinMode(pin_size_t pin, const PinMode mode) { } void digitalWrite(pin_size_t pin, PinStatus val) { + if (pin >= (g_pin_cfg_size / sizeof(g_pin_cfg[0]))) return; /* pinNumber > sizeof of pin table */ R_IOPORT_PinWrite(NULL, g_pin_cfg[pin].pin, val == LOW ? BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH); } PinStatus digitalRead(pin_size_t pin) { + if (pin >= (g_pin_cfg_size / sizeof(g_pin_cfg[0]))) return LOW; /* pinNumber > sizeof of pin table */ bsp_io_level_t ret; R_IOPORT_PinRead(NULL, g_pin_cfg[pin].pin, &ret); return (ret == BSP_IO_LEVEL_LOW ? LOW : HIGH);