CVE-2023-39540,CVE-2023-39541
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.
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
uC-TCP-IP - https://weston-embedded.com/micrium/overview Gecko Platform - https://www.silabs.com/developers/gecko-software-development-kit
5.9 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-126 - Buffer Over-read
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.
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]
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)
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
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]
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)
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
2023-08-30 - Vendor Disclosure
2023-11-21 - Vendor Patch Release
2024-02-20 - Public Release
Discovered by Francesco Benvenuto and Kelly Patterson of Cisco Talos.