Talos Vulnerability Report

TALOS-2023-1828

Weston Embedded uC-TCP-IP ICMP/ICMPv6 parsing denial of service vulnerabilities

February 20, 2024
CVE Number

CVE-2023-39540,CVE-2023-39541

SUMMARY

A denial of service vulnerability exists in the ICMP and ICMPv6 parsing functionality of Weston Embedded uC-TCP-IP v3.06.01. A specially crafted network packet can lead to an out-of-bounds read. An attacker can send a malicious packet to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Silicon Labs Gecko Platform 4.3.1.0
Weston Embedded uC-TCP-IP v3.06.01

PRODUCT URLS

uC-TCP-IP - https://weston-embedded.com/micrium/overview Gecko Platform - https://www.silabs.com/developers/gecko-software-development-kit

CVSSv3 SCORE

5.9 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

CWE

CWE-126 - Buffer Over-read

DETAILS

The uC-TCP-IP protocol stack is open source and optimized for embedded systems. It is designed for embedded systems running the µC/OS II or µC/OS III RTOS kernels and provides API’s for integration with other operating system kernels. The protocol stack features dual IPv4 and IPv6 support and an SSL/TLS socket option, as well as support for Ethernet, Wi-Fi and PHY controllers.

This out of bounds read vulnerability exists in the ICMP/ICMPv6 parsing functionality of the IPv4 and IPv6 protocol stacks within uC-TCP-IP. This out-of-bounds read could lead to denial of service when the invalid pointer that is read accesses unmapped memory.

CVE-2023-39540 - ipv4

If there are any errors in the IPv4 header of an ICMP packet processed by the uC-TCP-IP stack, the function NetICMPv4_TxMsgErrValidate will use an uninitialized value to index into a buffer. The value 0xffff is used as the initial value for the variable p_buf_hdr->ICMP_MsgIx, which is used to access the buffer p_buf->DataPtr at [2]. When 0xffff is added to p_buf->DataPtr, the resulting pointer could point to an unmapped memory address, resulting in a crash.

Under normal circumstances, the function NetIPv4_RxPktValidate will initialize the value for p_buf_hdr->ICMP_MsgIx. However, this correct initialization only happens after the IPv4 header has been fully validated. Alternatively, when an error is detected in the IPv4 header, NetICMPv4_TxMsgErr is called to transmit an error message before the variable p_buf_hdr->ICMP_MsgIx has been initialized. The function NetICMPv4_TxMsgErr eventually calls NetICMPv4_TxMsgErrValidate, which assumes that the value for p_buf_hdr->ICMP_MsgIx is valid for a packet whose IPv4 header protocol field contains the value for ICMP (1) [1]. The function then uses that uninitialized value to calculate the address of an invalid pointer.

File: net_icmpv4.c
2431: static  void  NetICMPv4_TxMsgErrValidate (NET_BUF       *p_buf,
2432:                                           NET_BUF_HDR   *p_buf_hdr,
2433:                                           NET_IPv4_HDR  *p_ip_hdr,
2434:                                           CPU_INT08U     type,
2435:                                           CPU_INT08U     code,
2436:                                           CPU_INT08U     ptr,
2437:                                           NET_ERR       *p_err)
2438: {
...
2529:                                                                 /* ---------------- CHK ICMPv4 ERR MSG ---------------- */
2530:     if (p_ip_hdr->Protocol == NET_IP_HDR_PROTOCOL_ICMP) {       /* If rx'd IP datagram is ICMP, ...                     */    //[1]
2531: #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
2532:         if (p_buf_hdr->ICMP_MsgIx == NET_BUF_IX_NONE) {
2533:             NET_CTR_ERR_INC(Net_ErrCtrs.ICMPv4.RxInvalidBufIxCtr);
2534:            *p_err = NET_BUF_ERR_INVALID_IX;
2535:             return;
2536:         }
2537: #endif
2538:         p_icmp_hdr = (NET_ICMPv4_HDR *)&p_buf->DataPtr[p_buf_hdr->ICMP_MsgIx];                                                //[2]

Crash Information

Thread 3 "app" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf7f47b40 (LWP 68319)]
0x5659f638 in NetICMPv4_TxMsgErrValidate (p_buf=0x565c4f38 <Mem_Heap+29112>, p_buf_hdr=0x565c4f38 <Mem_Heap+29112>, p_ip_hdr=0x565c180e <Mem_Heap+14990>, type=12 '\f',
    code=0 '\000', ptr=0 '\000', p_err=0xf7f47070) at uc-tcp-ip/IP/IPv4/net_icmpv4.c:2540
2540            switch (p_icmp_hdr->Type) {                             /* ... chk ICMPv4 msg type & ...                        */
(gdb) bt
#0  0x5659f638 in NetICMPv4_TxMsgErrValidate (p_buf=0x565c4f38 <Mem_Heap+29112>, p_buf_hdr=0x565c4f38 <Mem_Heap+29112>, p_ip_hdr=0x565c180e <Mem_Heap+14990>, type=12 '\f',
    code=0 '\000', ptr=0 '\000', p_err=0xf7f47070) at uc-tcp-ip/IP/IPv4/net_icmpv4.c:2540
#1  0x5659dddb in NetICMPv4_TxMsgErr (p_buf=0x565c4f38 <Mem_Heap+29112>, type=12 '\f', code=0 '\000', ptr=0 '\000', p_err=0xf7f470f8) at uc-tcp-ip/IP/IPv4/net_icmpv4.c:924
#2  0x565a59fb in NetIPv4_RxPktValidate (p_buf=0x565c4f38 <Mem_Heap+29112>, p_buf_hdr=0x565c4f38 <Mem_Heap+29112>, p_ip_hdr=0x565c180e <Mem_Heap+14990>, p_err=0xf7f472d4)
    at uc-tcp-ip/IP/IPv4/net_ipv4.c:5182
#3  0x565a50a0 in NetIPv4_Rx (p_buf=0x565c4f38 <Mem_Heap+29112>, p_err=0xf7f472d4) at uc-tcp-ip/IP/IPv4/net_ipv4.c:3956
#4  0x5659d0cd in NetIF_802x_RxPktFrameDemux (p_if=0x565bbf00 <NetIF_Tbl+128>, p_buf=0x565c4f38 <Mem_Heap+29112>, p_buf_hdr=0x565c4f38 <Mem_Heap+29112>,
    p_if_hdr=0x565c1800 <Mem_Heap+14976>, p_ctrs_stat=0x565bc81c <Net_StatCtrs+156>, p_ctrs_err=0x565bc524 <Net_ErrCtrs+132>, p_err=0xf7f472d4)
    at uc-tcp-ip/IF/net_if_802x.c:2067
#5  0x5659c4a4 in NetIF_802x_Rx (p_if=0x565bbf00 <NetIF_Tbl+128>, p_buf=0x565c4f38 <Mem_Heap+29112>, p_ctrs_stat=0x565bc81c <Net_StatCtrs+156>,
    p_ctrs_err=0x565bc524 <Net_ErrCtrs+132>, p_err=0xf7f472d4) at uc-tcp-ip/IF/net_if_802x.c:579
#6  0x565970a4 in NetIF_Ether_Rx (p_if=0x565bbf00 <NetIF_Tbl+128>, p_buf=0x565c4f38 <Mem_Heap+29112>, p_err=0xf7f472d4) at uc-tcp-ip/IF/net_if_ether.c:306
#7  0x5659ae96 in NetIF_RxPkt (p_if=0x565bbf00 <NetIF_Tbl+128>, p_err=0xf7f472d4) at uc-tcp-ip/IF/net_if.c:6644
#8  0x5659abc4 in NetIF_RxHandler (if_nbr=1 '\001') at uc-tcp-ip/IF/net_if.c:6390
#9  0x5659aa41 in NetIF_RxTaskHandler () at uc-tcp-ip/IF/net_if.c:6251
#10 0x5659a9a4 in NetIF_RxTask (p_data=0x0) at uc-tcp-ip/IF/net_if.c:6188
#11 0x565ab3c2 in KAL_TaskFnctWrapper (p_arg=0xffc7bd94) at uc-common/KAL/POSIX/kal.c:1343
#12 0xf7f1060a in start_thread (arg=<optimized out>) at pthread_create.c:477
#13 0xf7e1fd2a in clone () from /lib32/libc.so.6
(gdb) i r
eax            0x565d17ff          1448941567
ecx            0xc                 12
edx            0x565c1800          1448876032
ebx            0x565baf10          1448849168
esp            0xf7f46ff0          0xf7f46ff0
ebp            0xf7f47018          0xf7f47018
esi            0xf7f47070          -134975376
edi            0x0                 0
eip            0x5659f638          0x5659f638 <NetICMPv4_TxMsgErrValidate+426>
eflags         0x10206             [ PF IF RF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb)

Mitigation

There is no mitigation for Gecko Platform.

For uC-TCP-IP: Enable the configuration option NET_ERR_CFG_ARG_CHK_DBG_EN in net_cfg.h Ex.

net_cfg.h
#define  NET_ERR_CFG_ARG_CHK_DBG_EN             DEF_ENABLED

CVE-2023-39541 - ipv6

If there are any errors in the IPv6 header of an ICMPv6 packet processed by the uC-TCP-IP stack, the function NetICMPv6_TxMsgErrValidate will use an uninitialized value to index into a buffer. The value 0xffff is used as the initial value for the variable p_buf_hdr->ICMP_MsgIx, which is used to access the buffer p_buf->DataPtr at [2]. When 0xffff is added to p_buf->DataPtr, the resulting pointer could point to an unmapped memory address, resulting in a crash.

Under normal circumstances, the function NetIPv6_RxPktValidate will initialize the value for p_buf_hdr->ICMP_MsgIx by calling the function NetIPv6_RxPktValidateNextHdr. However, this correct initialization only happens after the IPv6 header has been fully validated. Alternatively, when an error is detected in the IPv6 header, NetICMPv6_TxMsgErr is called to transmit an error message before the function NetIPv6_RxPktValidateNextHdr is called to initialize the p_buf_hdr->ICMP_MsgIx variable. The function NetICMPv6_TxMsgErr eventually calls NetICMPv6_TxMsgErrValidate, which assumes that the value for p_buf_hdr->ICMP_MsgIx is valid for a packet whose IPv6 header protocol field contains the value for ICMPv6 (58) [1]. The function uses that uninitialized value to calculate the address of an invalid pointer.

File: net_icmpv6.c
3250: static  void  NetICMPv6_TxMsgErrValidate (NET_BUF       *p_buf,
3251:                                           NET_BUF_HDR   *p_buf_hdr,
3252:                                           NET_IPv6_HDR  *p_ip_hdr,
3253:                                           CPU_INT08U     type,
3254:                                           CPU_INT08U     code,
3255:                                           CPU_INT32U     ptr,
3256:                                           NET_ERR       *p_err)
3257: {
...
3304:                                                                 /* ---------------- CHK ICMPv6 ERR MSG ---------------- */
3305:     if (p_ip_hdr->NextHdr == NET_IP_HDR_PROTOCOL_ICMPv6) {      /* If rx'd IP datagram is ICMPv6, ...                   */    // [1]
3306: #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
3307:         if (p_buf_hdr->ICMP_MsgIx == NET_BUF_IX_NONE) {
3308:             NET_CTR_ERR_INC(Net_ErrCtrs.ICMPv6.RxInvalidBufIxCtr);
3309:            *p_err = NET_BUF_ERR_INVALID_IX;
3310:             return;
3311:         }
3312: #endif
3313:         p_icmp_hdr = (NET_ICMPv6_HDR *)&p_buf->DataPtr[p_buf_hdr->ICMP_MsgIx];                                                // [2]

Crash Information

Thread 3 "app" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf7f47b40 (LWP 96684)]
0x565c5466 in NetICMPv6_TxMsgErrValidate (p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_buf_hdr=0x565e35c4 <Mem_Heap+28836>, p_ip_hdr=0x565dffd6 <Mem_Heap+15030>, type=4 '\004', code=0 '\000',
    ptr=4, p_err=0xf7f47078) at uc-tcp-ip/IP/IPv6/net_icmpv6.c:3315
3315            switch (p_icmp_hdr->Type) {                              /* ... chk ICMPv6 msg type & ...
            */
(gdb) bt
#0  0x565c5466 in NetICMPv6_TxMsgErrValidate (p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_buf_hdr=0x565e35c4 <Mem_Heap+28836>, p_ip_hdr=0x565dffd6 <Mem_Heap+15030>, type=4 '\004', code=0 '\000',
    ptr=4, p_err=0xf7f47078) at uc-tcp-ip/IP/IPv6/net_icmpv6.c:3315
#1  0x565c1e90 in NetICMPv6_TxMsgErr (p_buf=0x565e35c4 <Mem_Heap+28836>, type=4 '\004', code=0 '\000', ptr=4,
    p_err=0xf7f47114) at uc-tcp-ip/IP/IPv6/net_icmpv6.c:832
#2  0x565ba1ab in NetIPv6_RxPktValidate (p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_buf_hdr=0x565e35c4 <Mem_Heap+28836>, p_ip_hdr=0x565dffd6 <Mem_Heap+15030>, p_err=0xf7f472d4)
    at uc-tcp-ip/IP/IPv6/net_ipv6.c:8059
#3  0x565b8b11 in NetIPv6_Rx (p_buf=0x565e35c4 <Mem_Heap+28836>, p_err=0xf7f472d4)
    at uc-tcp-ip/IP/IPv6/net_ipv6.c:5620
#4  0x565b513d in NetIF_802x_RxPktFrameDemux (p_if=0x565d9f40 <NetIF_Tbl+128>, p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_buf_hdr=0x565e35c4 <Mem_Heap+28836>, p_if_hdr=0x565dffc8 <Mem_Heap+15016>,
    p_ctrs_stat=0x565daefc <Net_StatCtrs+156>, p_ctrs_err=0x565dac44 <Net_ErrCtrs+132>, p_err=0xf7f472d4)
    at uc-tcp-ip/IF/net_if_802x.c:2074
#5  0x565b4588 in NetIF_802x_Rx (p_if=0x565d9f40 <NetIF_Tbl+128>, p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_ctrs_stat=0x565daefc <Net_StatCtrs+156>, p_ctrs_err=0x565dac44 <Net_ErrCtrs+132>, p_err=0xf7f472d4)
    at uc-tcp-ip/IF/net_if_802x.c:579
#6  0x565af10e in NetIF_Ether_Rx (p_if=0x565d9f40 <NetIF_Tbl+128>, p_buf=0x565e35c4 <Mem_Heap+28836>,
    p_err=0xf7f472d4) at uc-tcp-ip/IF/net_if_ether.c:306
#7  0x565b2f7a in NetIF_RxPkt (p_if=0x565d9f40 <NetIF_Tbl+128>, p_err=0xf7f472d4) at uc-tcp-ip/IF/net_if.c:6644
#8  0x565b2ca8 in NetIF_RxHandler (if_nbr=1 '\001') at uc-tcp-ip/IF/net_if.c:6390
#9  0x565b2b25 in NetIF_RxTaskHandler () at uc-tcp-ip/IF/net_if.c:6251
#10 0x565b2a88 in NetIF_RxTask (p_data=0x0) at uc-tcp-ip/IF/net_if.c:6188
#11 0x565c83c1 in KAL_TaskFnctWrapper (p_arg=0xffcf6744) at uc-common/KAL/POSIX/kal.c:1343
#12 0xf7f1060a in start_thread (arg=<optimized out>) at pthread_create.c:477
#13 0xf7e1fd2a in clone () from /lib32/libc.so.6
(gdb) i r
eax            0x565effc7          1449066439
ecx            0x4                 4
edx            0x565dffc8          1449000904
ebx            0x565d8f10          1448972048
esp            0xf7f47000          0xf7f47000
ebp            0xf7f47028          0xf7f47028
esi            0xf7f47280          -134974848
edi            0x0                 0
eip            0x565c5466          0x565c5466 <NetICMPv6_TxMsgErrValidate+275>
eflags         0x10212             [ AF IF RF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb)

Mitigation

There is no mitigation for Gecko Platform.

For uC-TCP-IP: Enable the configuration option NET_ERR_CFG_ARG_CHK_DBG_EN in net_cfg.h Ex.

net_cfg.h
#define  NET_ERR_CFG_ARG_CHK_DBG_EN             DEF_ENABLED
TIMELINE

2023-08-30 - Vendor Disclosure
2023-11-21 - Vendor Patch Release
2024-02-20 - Public Release

Credit

Discovered by Francesco Benvenuto and Kelly Patterson of Cisco Talos.