[Bug] RT-Thread HPM ADC indexes channel state without a bounds check
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 67/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- c
- 領域
- backend, embedded-iot
調査の方向性
bsp/hpmicro/libraries/drivers/drv_adc.cのhpm_adc_enabled()とinit_channel_config()の周辺を読み、次にcomponents/drivers/misc/adc.cがどのようにチャネルをドライバーに渡すか確認してください。負の値も含め、無効なチャネルがchn_stateへのあらゆるアクセスより前に拒否されるようにし、issueに記載されたbounds-sanitizerによる再現を実行してください。サポートされていないチャネルが状態配列の範囲外を読み書きせず、安全に戻ることを完了条件とします。
索引モデルが issue の本文から書いたものです。
説明
RT-Thread Version
v5.3.0
Affected area
Other / Not sure
Hardware/BSP vendor
Not applicable / Other
Architecture
Not applicable / Other
Board and hardware details
HPM ADC
Develop Toolchain
Other
Describe the bug
RT-Thread HPM ADC indexes channel state without a bounds check
Affected version
RT-Thread v5.3.0.
Describe the bug
In the checked revision, hpm_adc_enabled() indexes chn_state[16] with the raw signed channel. rt_adc_enable() does not validate that channel first.
typedef struct
{
bool enabled;
} adc_channel_state_t;
typedef struct
{
char *adc_name;
struct rt_adc_device hpm_adc_device;
bool is_adc12;
bool adc_enabled;
uint32_t adc_base;
adc_channel_state_t chn_state[16];
} hpm_rtt_adc;
The enable callback reads hpm_adc->chn_state[channel].enabled and, when that entry is clear, later writes it:
if (enabled == RT_TRUE) {
if (!hpm_adc->chn_state[channel].enabled) {
...
hpm_adc->chn_state[channel].enabled = true;
ret = init_channel_config(hpm_adc, channel);
}
}
Channel 16 is past the sixteen entries. adc_base is the field immediately before chn_state, so a negative channel walks backward into that field before any HAL channel check. A later HAL check cannot protect the earlier array access.
Locations:
bsp/hpmicro/libraries/drivers/drv_adc.c:21
bsp/hpmicro/libraries/drivers/drv_adc.c:26
bsp/hpmicro/libraries/drivers/drv_adc.c:219
bsp/hpmicro/libraries/drivers/drv_adc.c:227
bsp/hpmicro/libraries/drivers/drv_adc.c:239
components/drivers/misc/adc.c:131
Threat model
The boundary is a caller of the public ADC API. This report does not treat a network or physical-bus peer as the attacker. The value that caller controls is the channel argument of rt_adc_enable(dev, channel). dev only selects the ADC instance. adc_base and chn_state belong to the driver object; the caller does not supply those addresses.
channel has type rt_int8_t, so the values defined by the API are -128 through 127. Entries 0 through 15 are the state array. Channel 16 is past that array. The negative constants RT_ADC_INTERN_CH_TEMPER, RT_ADC_INTERN_CH_VREF, and RT_ADC_INTERN_CH_VBAT (-1, -2, and -3) walk backward from the array into the preceding fields. rt_adc_enable() always passes RT_TRUE as the enable flag, which is the path that reads and may write the indexed state. rt_adc_disable() does not take that path.
With RT_USING_FINSH, adc enable <channel> passes atoi(argv[2]) into rt_adc_enable(). The shell is an entry point only when an untrusted user can reach it. A product task that forwards an untrusted channel into the same API is the same boundary.
Steps to reproduce
I have not reproduced this on HPMicro hardware. The reduced check keeps adc_base immediately before a sixteen-entry state array and performs the same read-then-write.
#include <stdbool.h>
#include <stdint.h>
typedef struct { bool enabled; } adc_channel_state_t;
typedef struct {
uint32_t adc_base;
adc_channel_state_t chn_state[16];
} hpm_rtt_adc;
static void enable_channel(hpm_rtt_adc *adc, int8_t channel)
{
if (!adc->chn_state[channel].enabled)
adc->chn_state[channel].enabled = true;
}
int main(void)
{
hpm_rtt_adc adc = {0};
enable_channel(&adc, 16);
return (int)adc.adc_base;
}
Compile it with a bounds sanitizer, for example:
clang -fsanitize=address,undefined -g -O1 repro.c -o repro && ./repro
Checking channel >= 0 && channel < 16 before the first state access avoids the report. Channel -1 should be rejected the same way; on this layout it can change the preceding adc_base field without stopping at the end of a separate allocation.
Relevant log output
runtime error: member access within address ... with insufficient space
for an object of type 'adc_channel_state_t'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
Impact
A caller that can pass a channel to rt_adc_enable(), including the adc shell command when FinSH is enabled, can index outside chn_state. The effect in this model is an out-of-range state read and, when the indexed entry looks disabled, a write. Peripheral misconfiguration or loss of availability is possible. Physical fault behavior depends on the board.
Suggested fix
A later revision of this file, commit fc64f78669b42b35981f97c23c7e952832f3b48b, removes chn_state and checks the channel before use. Trees that still contain the array should validate and map the channel before any state access, size the state for every supported mapped channel, and reject unsupported values without writing adjacent fields.
Other additional context
No response
- 主要言語
- C
- スター
- 12.3k
- フォーク
- 5.5k
- 平均マージ
- 4日 9時間
- マージ済み PR(30日)
- 38
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
RT-Thread/rt-thread のほかの issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
RT-Thread/rt-thread#11949 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] RT-Thread AB32 ADC uses an unchecked channel as a register index対応中かも @usualtreee が 4 日前に担当しました。 オープンbug Component component: drivers
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
RT-Thread/rt-thread#11948 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] [libc] timer_gettime 拆秒前将总纳秒截断为 uint32_t,剩余时间查询错误対応中かも @Yunlk が 11 日前に担当しました。 オープンin progress
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
RT-Thread/rt-thread#11924 · コメント 7 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] dfs_v2 tmpfs: ftruncate(fd, 0) frees the file buffer but reports success — use-after-free read/write and double free from a legal POSIX call対応中かも @remukisama が 15 日前に担当しました。 オープンin progress
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
RT-Thread/rt-thread#11902 · コメント 4 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[bsp][stm32][bluepill] README「快速上手」缺少重新生成 MDK 工程这一步,按文档操作无法编译通过再び着手できるかも @moment-NEW が 32 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンin progress
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
RT-Thread/rt-thread#11818 · コメント 4 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
RT-Thread/rt-thread の issue をすべて見る
似ている issue
-
[compiler-rt] Rtsan-aarch64-NoInstTest: error: no such file or directory: 'NOTFOUND' (libatomic)オープンbuild-problem compiler-rt:rtsan platform:linux
難易度 2/5 1〜3時間 初心者へのやさしさ 63/100
llvm/llvm-project#239039 ·
メンテナーはふだん 1 日以内に返信
-
component:obi contribfest go test
難易度 2/5 1時間未満 初心者へのやさしさ 83/100
open-telemetry/opentelemetry-ebpf-instrumentation#4143 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
Bug :bug:
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
sonic-net/sonic-buildimage#30541 ·
メンテナーはふだん 1 日以内に返信