【2019 CWE/SANS 25 大编程错误清单】12越界写入
案例1:
void tonly_aw21036_led_drv_pwm_init(tonly_gpio_pin_t gpio_pin, uint8_t pwm)
{uint8_t pin = gpio_pin - AW21036_GPIO_PIN_START;if (pin < AW21036_LED_MAX_CHANNEL){aw21036_ctx.pwm[pin] = pwm; /* 有效通道号: 0-35 */}else{TONLY_LED_LOG_E("[aw21036] invalid pin init pwm FAIL");}
}
好的,用户指出在函数tonly_aw21036_led_drv_pwm_init中的aw21036_ctx.pwm[pin] = pwm;可能存在越界写入的问题。我需要仔细分析代码,找出潜在的问题所在,并提出修正方案。
首先,查看函数的结构。该函数接收一个gpio_pin参数,并通过减去AW21036_GPIO_PIN_START得到pin。然后检查pin是否小于等于AW21036_LED_MAX_CHANNEL(定义为36)。如果条件满足,就将pwm值写入aw21036_ctx.pwm[pin];否则记录错误。
问题出在条件判断上。AW21036_LED_MAX_CHANNEL是36,数组pwm的大小也是36(从0到35)。因此,当pin等于36时,会访问pwm[36],这会导致越界,因为数组索引最大应该是35。因此,条件判断应该是pin < AW21036_LED_MAX_CHANNEL,而不是<=。
接下来需要确认代码中AW21036_LED_MAX_CHANNEL的定义。根据用户提供的头文件片段,AW21036_LED_MAX_CHANNEL确实被定义为36,而结构体aw21036_ctx_t中的pwm数组大小也是36。因此,当pin为36时,索引36会超出数组范围,造成越界写入。
修正方法是将条件判断从pin <= AW21036_LED_MAX_CHANNEL改为pin < AW21036_LED_MAX_CHANNEL。同时,需要更新错误日志信息,以反映正确的范围。
此外,检查其他相关函数,如tonly_aw21036_led_drv_set_pwm,发现它们也使用了相同的条件判断,可能也存在同样的问题,但用户当前只关注这个特定函数,因此先修正此处。
最后,确保修改后的代码在所有可能的情况下都不会越界,并测试边界条件,如pin为0、35、36的情况,确保35是最大有效索引,36触发错误处理。
在tonly_aw21036_led_drv_pwm_init函数中,确实存在潜在的数组越界风险。问题出在通道号校验逻辑,当前的AW21036_LED_MAX_CHANNEL定义为36,而数组索引应该是0-35。以下是修正方案:
tonly_led_drv_aw21036.c
void tonly_aw21036_led_drv_pwm_init(tonly_gpio_pin_t gpio_pin, uint8_t pwm)
{uint8_t pin = gpio_pin - AW21036_GPIO_PIN_START;// 修正校验条件:通道号应严格小于最大值(0-35)if (pin < AW21036_LED_MAX_CHANNEL) // 将 <= 改为 <{aw21036_ctx.pwm[pin] = pwm;}else{// 更新错误日志包含有效范围信息TONLY_LED_LOG_E("[aw21036] invalid pin(%d) init pwm FAIL, max:%d", pin, AW21036_LED_MAX_CHANNEL-1);}
}
修改说明:
将条件判断从 pin <= AW21036_LED_MAX_CHANNEL 改为 pin < AW21036_LED_MAX_CHANNEL
原36通道定义对应索引0-35
防止当pin=36时访问pwm[36]导致的越界
错误日志添加详细信息输出
显示实际传入的pin值
明确最大有效通道号(35)
配套建议:
在头文件中添加注释说明通道范围:
tonly_led_drv_aw21036.h
Apply
#define AW21036_LED_MAX_CHANNEL 36 /* 有效通道号: 0-35 */
检查其他相关函数(如tonly_aw21036_led_drv_set_pwm)是否存在相同问题