Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[BUG] drivers/net/lan9250.c: `.bss`/global `pktbuf` overflow in `lan9250_recv_buffer` — RX-status packet length bounded only by `DEBUGASSERT` (SPI path only)

オープン 初心者向け
#21,112 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
c
領域
embedded-iot

調査の方向性

drivers/net/lan9250.c の lan9250_receive() と lan9250_recv_buffer() から始めてください。次に、pktbuf のサイズの決まり方と、SPI および QSPI/SQI の各経路でデータをどのようにコピーするかを確認してください。各コピーの前に常に有効な容量チェックを追加し、大きすぎるフレームを破棄してください。受信した長さによって、どちらの経路でも pktbuf の範囲を超えて書き込まれない状態になれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Arch: all Area: Drivers OS: Linux Type: Bug
Description / Steps to reproduce the issue

In drivers/net/lan9250.c (LAN9250 Ethernet driver over SPI/QSPI) the received frame length taken
from the RX Status FIFO is used as a copy length into priv->pktbuf, bounded on the SPI path only
by an assert that compiles to nothing in the default build, and on the QSPI/SQI path by no capacity
check at all
. priv is a static global object, so this is an out-of-bounds write into .bss
that first clobbers the structure members immediately following pktbuf (a watchdog timer and several
work structures) and then adjacent globals. The attacker is a peer on the same L2 network sending an
oversized frame, or a malicious/faulty LAN9250 PHY.

lan9250_receive() takes the received frame length from the LAN9250 RX Status FIFO register and
passes it as the copy length, with only a non-zero check:

/* drivers/net/lan9250.c:1747-1748  (lan9250_receive) */
regval = lan9250_get_reg(priv, LAN9250_RXSFR);        /* RX Status FIFO register */
pktlen = (regval & RXSFF_PL_M) >> RXSFF_PL_S;         /* 14-bit length field, 0..16383 */
if (pktlen)                                           /* only a non-zero check */
    lan9250_recv_buffer(priv, priv->dev.d_buf, pktlen);  /* buflen = pktlen */

The copy then runs into priv->pktbuf. On the SPI path the length is bounded only by a
DEBUGASSERT; on the QSPI/SQI path there is no capacity check:

/* drivers/net/lan9250.c:853 (inside #ifdef CONFIG_LAN9250_SPI) */
DEBUGASSERT(buflen <= sizeof(priv->pktbuf));          /* SPI path: default-off assert */
...
SPI_RECVBLOCK(priv->spi, buffer, buflen);             /* buffer = priv->dev.d_buf = priv->pktbuf */

/* drivers/net/lan9250.c:881-899 (#else — QSPI/SQI path) */
meminfo.buflen = buflen;                               /* no capacity check at all */
QSPI_MEMORY(priv->qspi, &meminfo);

priv->pktbuf is uint32_t pktbuf[LAN9250_PKTBUF_SIZE / 4] (:212), with
LAN9250_PKTBUF_SIZE = LAN9250_ALIGN(MAX_NETDEV_PKTSIZE + CONFIG_NET_GUARDSIZE + 4) (:142). In the
default IPv4/Ethernet config (CONFIG_NET_ETH_PKTSIZE = 590, CONFIG_NET_GUARDSIZE = 2) that is
ALIGN(596) = 596 bytes — about one max Ethernet frame. Any ordinary frame larger than ~596 bytes
(a normal 1514/1518-byte Ethernet frame already qualifies) therefore overflows it. pktlen is a
14-bit RX-status register field (max 16383); that width is the hardware status-field size, not a
demonstration that a peer can inject a 16 KB frame — the practically reachable and sufficient case is
simply "frame > ~596 bytes".

Memory class: the driver state is a static global, not a heap allocation:

/* drivers/net/lan9250.c:230 */
static struct lan9250_driver_s g_lan9250;
/* :2440 / :2512 */  priv = &g_lan9250;   /* no kmm_malloc/kmm_zalloc of the driver state */

pktbuf (:212) is immediately followed in the struct by txtout_timer (struct wdog_s),
txtout_work / txpoll_work / irq_work (struct work_s), and dev (:214-224). So the overflow
is a .bss/global-buffer overflow that corrupts those sibling members (watchdog + work queue
state) first, then neighbouring .bss objects — it is not a heap overflow.

Configuration dimension:

  • SPI build, CONFIG_DEBUG_ASSERTIONS = n (default): the guard is compiled out → overflow.
  • SPI build, CONFIG_DEBUG_ASSERTIONS = y: the assert fires → controlled panic (DoS), no overflow.
  • QSPI/SQI build (#else path): there is no capacity check in any configuration, so enabling
    assertions does not prevent the overflow on QSPI/SQI targets.

Why this is a bug: the length is a parameter at the sink (lan9250_recv_buffer)
that originates in the caller (lan9250_receive), and the only guard anywhere on the SPI path is the
default-off DEBUGASSERT at :853 (and nothing at all on the QSPI path). The caller's if (pktlen)
check is non-zero-only, with no upper bound against MAX_NETDEV_PKTSIZE before handing the
device-reported length to the copy.

Steps:

  1. Build the LAN9250 driver (SPI with default CONFIG_DEBUG_ASSERTIONS unset, or any QSPI/SQI build).
  2. A peer on the same L2 network sends a frame larger than ~596 bytes (an ordinary full-size Ethernet
    frame suffices), or a malicious/faulty LAN9250 PHY reports an oversized RX-status length.
  3. The copy writes pktlen bytes into the 596-byte g_lan9250.pktbuf, overflowing into the adjacent
    watchdog/work members and .bss.

An AddressSanitizer build of the copy with the real buffer sizing (as a 596-byte global region)
reports a global-buffer-overflow WRITE.

Suggested fix: add an always-compiled check before lan9250_recv_buffer, and/or replace the
DEBUGASSERT, and add the equivalent check on the QSPI/SQI path:

if (pktlen > MAX_NETDEV_PKTSIZE)
  {
    /* drop oversized frame */
    return;
  }

and in lan9250_recv_buffer replace the SPI DEBUGASSERT with if (buflen > sizeof(priv->pktbuf)) return;
and add the same guard before the QSPI QSPI_MEMORY transfer.

On which OS does this issue occur?

[OS: Linux]

What is the version of your OS?

ubuntu 22

NuttX Version

master

Issue Architecture

[Arch: all]

Issue Area

[Area: Drivers]

Host information

No response

Verification
  • I have verified before submitting the report.
主要言語
C
スター
4.1k
フォーク
1.7k
平均マージ
1日 10時間
マージ済み PR(30日)
649

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/nuttx のほかの issue

apache/nuttx の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。