2026-09-29 17:47CVE-2026-102721eclipse
PUBLISHED5.2CWE-125

A TFTP server that answers with a short ERROR packet makes the client read up to 64 bytes past the

received datagram.

Each receive path checks only that the datagram is at least four bytes long (nxd_tftp_client.c:1229,

1521, 1984). When the opcode is NX_TFTP_CODE_ERROR the message string is copied with a loop whose

only limits are the destination buffer and a NUL byte:

```c

/* addons/tftp/nxd_tftp_client.c:1769 */

for (i = 0; (i < (sizeof(tftp_client_ptr -> nx_tftp_client_error_string) - 1)) && (*buffer_ptr); i++)

```

Nothing compares `buffer_ptr` against `nx_packet_append_ptr`. An ERROR packet that carries no

terminating NUL, which a server controls completely, walks the loop off the end of the packet until

it happens to meet a zero byte or fills the 64 byte destination.

```

ERROR: AddressSanitizer: heap-buffer-overflow

READ of size 1 at 0x60d0000000c8 thread T4

#0 _nxd_tftp_client_file_read addons/tftp/nxd_tftp_client.c:1769

0x60d0000000c8 is 0 bytes to the right of 136-byte region

```

The open path has the same loop at :1327 and reports the same way. What is read lands in

`nx_tftp_client_error_string`, which the application is expected to display or log, so adjacent

packet pool memory ends up in whatever the device does with the error text.

Add `(buffer_ptr < packet_ptr -> nx_packet_append_ptr)` to the loop condition in all three paths.

Problem type

Affected products

Eclipse Foundation

NetX Duo

<= 6.5.1 - AFFECTED

References

GitHub Security Advisories

GHSA-5cxq-44w6-64mx

A TFTP server that answers with a short ERROR packet makes the client read up to 64 bytes past...

https://github.com/advisories/GHSA-5cxq-44w6-64mx

A TFTP server that answers with a short ERROR packet makes the client read up to 64 bytes past the

received datagram.

Each receive path checks only that the datagram is at least four bytes long (nxd_tftp_client.c:1229,

1521, 1984). When the opcode is NX_TFTP_CODE_ERROR the message string is copied with a loop whose

only limits are the destination buffer and a NUL byte:




/* addons/tftp/nxd_tftp_client.c:1769 */



for (i = 0; (i < (sizeof(tftp_client_ptr -> nx_tftp_client_error_string) - 1)) && (*buffer_ptr); i++)


Nothing compares buffer_ptr against nx_packet_append_ptr. An ERROR packet that carries no

terminating NUL, which a server controls completely, walks the loop off the end of the packet until

it happens to meet a zero byte or fills the 64 byte destination.




ERROR: AddressSanitizer: heap-buffer-overflow



READ of size 1 at 0x60d0000000c8 thread T4

    #0 _nxd_tftp_client_file_read  addons/tftp/nxd_tftp_client.c:1769


0x60d0000000c8 is 0 bytes to the right of 136-byte region


The open path has the same loop at :1327 and reports the same way. What is read lands in

nx_tftp_client_error_string, which the application is expected to display or log, so adjacent

packet pool memory ends up in whatever the device does with the error text.

Add (buffer_ptr < packet_ptr -> nx_packet_append_ptr) to the loop condition in all three paths.

JSON source

https://cveawg.mitre.org/api/cve/CVE-2026-102721
Click to expand
{
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "cveMetadata": {
    "cveId": "CVE-2026-102721",
    "assignerOrgId": "e51fbebd-6053-4e49-959f-1b94eeb69a2c",
    "assignerShortName": "eclipse",
    "dateUpdated": "2026-09-29T17:47:12.769Z",
    "dateReserved": "2026-09-29T16:15:17.020Z",
    "datePublished": "2026-09-29T17:47:12.769Z",
    "state": "PUBLISHED"
  },
  "containers": {
    "cna": {
      "providerMetadata": {
        "orgId": "e51fbebd-6053-4e49-959f-1b94eeb69a2c",
        "shortName": "eclipse",
        "dateUpdated": "2026-09-29T17:47:12.769Z"
      },
      "descriptions": [
        {
          "lang": "en",
          "value": "A TFTP server that answers with a short ERROR packet makes the client read up to 64 bytes past the\n\n\n\nreceived datagram.\n\n\n\nEach receive path checks only that the datagram is at least four bytes long (nxd_tftp_client.c:1229,\n\n\n\n1521, 1984). When the opcode is NX_TFTP_CODE_ERROR the message string is copied with a loop whose\n\n\n\nonly limits are the destination buffer and a NUL byte:\n\n\n\n```c\n\n\n\n/* addons/tftp/nxd_tftp_client.c:1769 */\n\n\n\nfor (i = 0; (i < (sizeof(tftp_client_ptr -> nx_tftp_client_error_string) - 1)) && (*buffer_ptr); i++)\n\n\n\n```\n\n\n\nNothing compares `buffer_ptr` against `nx_packet_append_ptr`. An ERROR packet that carries no\n\n\n\nterminating NUL, which a server controls completely, walks the loop off the end of the packet until\n\n\n\nit happens to meet a zero byte or fills the 64 byte destination.\n\n\n\n```\n\n\n\nERROR: AddressSanitizer: heap-buffer-overflow\n\n\n\nREAD of size 1 at 0x60d0000000c8 thread T4\n\n    #0 _nxd_tftp_client_file_read  addons/tftp/nxd_tftp_client.c:1769\n\n\n0x60d0000000c8 is 0 bytes to the right of 136-byte region\n\n\n\n```\n\n\n\nThe open path has the same loop at :1327 and reports the same way. What is read lands in\n\n\n\n`nx_tftp_client_error_string`, which the application is expected to display or log, so adjacent\n\n\n\npacket pool memory ends up in whatever the device does with the error text.\n\n\n\nAdd `(buffer_ptr < packet_ptr -> nx_packet_append_ptr)` to the loop condition in all three paths.",
          "supportingMedia": [
            {
              "type": "text/html",
              "base64": false,
              "value": "<p>A TFTP server that answers with a short ERROR packet makes the client read up to 64 bytes past the</p><p>received datagram.</p><p>Each receive path checks only that the datagram is at least four bytes long (nxd_tftp_client.c:1229,</p><p>1521, 1984). When the opcode is NX_TFTP_CODE_ERROR the message string is copied with a loop whose</p><p>only limits are the destination buffer and a NUL byte:</p><p>```c</p><p>/* addons/tftp/nxd_tftp_client.c:1769 */</p><p>for (i = 0; (i &lt; (sizeof(tftp_client_ptr -&gt; nx_tftp_client_error_string) - 1)) &amp;&amp; (*buffer_ptr); i++)</p><p>```</p><p>Nothing compares `buffer_ptr` against `nx_packet_append_ptr`. An ERROR packet that carries no</p><p>terminating NUL, which a server controls completely, walks the loop off the end of the packet until</p><p>it happens to meet a zero byte or fills the 64 byte destination.</p><p>```</p><p>ERROR: AddressSanitizer: heap-buffer-overflow</p><p>READ of size 1 at 0x60d0000000c8 thread T4</p><code>    #0 _nxd_tftp_client_file_read  addons/tftp/nxd_tftp_client.c:1769</code><br><p>0x60d0000000c8 is 0 bytes to the right of 136-byte region</p><p>```</p><p>The open path has the same loop at :1327 and reports the same way. What is read lands in</p><p>`nx_tftp_client_error_string`, which the application is expected to display or log, so adjacent</p><p>packet pool memory ends up in whatever the device does with the error text.</p><p>Add `(buffer_ptr &lt; packet_ptr -&gt; nx_packet_append_ptr)` to the loop condition in all three paths.</p>"
            }
          ]
        }
      ],
      "affected": [
        {
          "vendor": "Eclipse Foundation",
          "product": "NetX Duo",
          "packageName": "NetX Duo",
          "defaultStatus": "unaffected",
          "versions": [
            {
              "version": "0",
              "status": "affected",
              "versionType": "semver",
              "lessThanOrEqual": "6.5.1"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "lang": "en",
              "description": "CWE-125 Out-of-bounds Read",
              "cweId": "CWE-125",
              "type": "CWE"
            }
          ]
        }
      ],
      "references": [
        {
          "url": "https://github.com/eclipse-threadx/netxduo/security/advisories/GHSA-wvc9-5m9h-rvxc"
        }
      ],
      "metrics": [
        {
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "value": "L0stHeart",
          "type": "reporter"
        }
      ]
    }
  }
}