lwIP sockets: a UDP send crashes the VM when pbuf_alloc fails instead of returning an error

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

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

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

評価

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

調査の方向性

OTP_SOCKET_LWIP分岐のSocketStateUDPケースにあるdo_socket_sendで、src/libAtomVM/otp_socket.cを読んでください。近くのソケットエラーがどのように返されるか、またpbuf_allocの失敗がどのように処理されるかを確認してください。NULLのpbufに対するエラーパスを追加し、適切なソケットエラーを返すようにしてください。その後、サイズ超過またはメモリ不足時のUDP送信が、VMをクラッシュさせずにエラーを返すことを確認してください。

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

説明

Affected: release-0.7 at ca1583068, lwIP socket backend (RP2 port).
Not changed by #2345.

What happens

do_socket_send builds the datagram with:

struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
uint8_t *bytes = (uint8_t *) p->payload;
memcpy(bytes, buf, len);

There is no NULL check. When lwIP cannot allocate the pbuf (payload larger than
the lwIP heap, or memory exhausted by a burst of datagrams), p is NULL and
the VM dereferences it: hard fault on the Pico W, instead of {error, Reason}.

How to reproduce (Pico W)

{ok, S} = socket:open(inet, dgram, udp),
Dest = #{family => inet, addr => {192, 168, 0, 1}, port => 5000},
socket:sendto(S, binary:copy(<<0>>, 60000), Dest).   % larger than MEM_SIZE

The board faults. A tight loop of 1400-byte datagrams hits the same path once
the pbuf memory is exhausted.

Where

src/libAtomVM/otp_socket.c, do_socket_send, #elif OTP_SOCKET_LWIP branch,
SocketStateUDP case.

Suggested fix

Return SocketOtherError with ERR_MEM (or SocketWouldBlock, so that
socket:sendto/3 waits and retries) when pbuf_alloc returns NULL.

主要言語
Erlang
スター
2.3k
フォーク
171
平均マージ
4日 11時間
マージ済み PR(30日)
20

環境構築

はじめの一歩

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

atomvm/AtomVM のほかの issue

atomvm/AtomVM の issue をすべて見る

似ている issue

Embedded & IoT の issue をもっと見る

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

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