Skip to content

Missing Security Control in Zephyr OS IP Packet Handling

High
ceolin published GHSA-fjc8-223c-qgqr Mar 15, 2024

Package

zephyr (zephyr)

Affected versions

<= 3.5

Patched versions

None

Description

Summary

Zephyr OS IP packet handling does not properly drop IP packets arriving on an external interface with a source address equal to 127.0.01 or the destination address.

Details

Most routers will drop such IP packets before they reach the destination address, but if not, then Zephyr OS should drop any IP packet arriving on an external interface with the source address 127.0.0.1 or address equal to destination address.
This work for both IPv4 and IPv6 interfaces with TCP and UDP connections. This is now tested only in native simulator (native_sim) with ethernet interface, but the code executed is not dependent on the interfaces and behavior should be same e.g., over WLAN.
IP packet with localhost source address can be used to bypass the host side IP address-based access control like Project Zero has shown: https://googleprojectzero.blogspot.com/2015/01/finding-and-exploiting-ntpd.html.
In addition, those makes test target more vulnerable for DoS attacks since answers are handled by loopback interfaces.
In Zephyr OS there is also a bug causing kernel to crash in this kind of situations. The crash is reproduced with IPv4 and IPv6 packets over TCP connection against echo_server and dump_http_server_mt test targets.

Below are debug logs from such a crash:

[00:01:13.200,000] net_ipv4: net_ipv4_input: (0x80bd9c0): IPv4 packet received from 127.0.0.1 to 192.0.2.1
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4c1c data 0x80c7c14 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4c1c skip 20
[00:01:13.200,000] net_conn: net_conn_input: (0x80bd9c0): Check TCP listener for pkt 0x80c4c1c src port 4242 dst port 1559 family 1
[00:01:13.200,000] net_conn: net_conn_input: (0x80bd9c0): No match found.
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4c1c skip 20
[00:01:13.200,000] net_pkt: pkt_alloc_with_buffer: (0x80bd9c0): On iface 0x80baf00 size 20
[00:01:13.200,000] net_pkt: pkt_estimate_headers_length: (0x80bd9c0): HDRs length estimation 48
[00:01:13.200,000] net_pkt: net_pkt_alloc_buffer_debug: (0x80bd9c0): Data allocation maximum size 68 (requested 20)
[00:01:13.200,000] net_pkt: pkt_alloc_buffer: (0x80bd9c0): TDATA (?) [0] frag 0x80c74b8 ref 1 (net_tcp_reply_rst():1178)
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4bd8 data 0x80c7c80 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4bd8 data 0x80c7c94 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4bd8 data 0x80c7c80 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 12
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 8
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4bd8 data 0x80c7c94 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_tcp: tcp_send: (0x80bd9c0): RST Seq=3235108224 Len=0
[00:01:13.200,000] net_pkt: net_pkt_ref_debug: (0x80bd9c0): TX [10] pkt 0x80c4bd8 ref 2 (tcp_send():327)
[00:01:13.200,000] net_core: net_send_data: (0x80bd9c0): Loopback pkt 0x80c4bd8 back to us
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_ipv4: net_ipv4_input: (0x80bd9c0): IPv4 packet received from 127.0.0.1 to 192.0.2.1
[00:01:13.200,000] net_pkt: net_pkt_write: (0x80bd9c0): pkt 0x80c4bd8 data 0x80c7c94 length 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_conn: net_conn_input: (0x80bd9c0): Check TCP listener for pkt 0x80c4bd8 src port 1559 dst port 4242 family 1
[00:01:13.200,000] net_conn: net_conn_input: (0x80bd9c0): [0x80bd578] match found cb 0x808afba ud 0x80bc340 rank 0x78
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_pkt: net_pkt_skip: (0x80bd9c0): pkt 0x80c4bd8 skip 20
[00:01:13.200,000] net_tcp: tcp_in: (0x80bd9c0): RST Seq=3235108224 Len=0 [SYN_RECEIVED Seq=3006520478 Ack=3235108224]
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [10] pkt 0x80c4bd8 ref 1 frags 0x80c74b8 (tcp_in():3084)
[00:01:13.200,000] net_tcp: tcp_conn_close_debug: (0x80bd9c0): conn: 0x80cafcc closed by TCP stack (tcp_in():3142)
[00:01:13.200,000] net_tcp: tcp_conn_close_debug: (0x80bd9c0): SYN_RECEIVED->CLOSED
[00:01:13.200,000] net_tcp: tcp_conn_unref: (0x80bd9c0): conn: 0x80cafcc, ref_count=1
[00:01:13.200,000] net_conn: net_conn_unregister: (0x80bd9c0): Connection handler 0x80bd578 removed
[00:01:13.200,000] net_ctx: net_context_unref: (0x80bd9c0): Context 0x80bc340 released
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [10] pkt 0x80c4c60 ref 0 frags 0x80c7480 (tcp_send_queue_flush():518)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c7480 ref 0 frags (nil) (tcp_send_queue_flush():518)
[00:01:13.200,000] net_pkt: net_pkt_frag_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c7480 ref 0 (net_pkt_unref_debug():597)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [11] pkt 0x80c4ca4 ref 0 frags (nil) (tcp_conn_unref():586)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): RX [13] pkt 0x80c4820 ref 0 frags (nil) (tcp_conn_unref():589)
[00:01:13.200,000] net_core: processing_data: (0x80bd9c0): Consumed pkt 0x80c4bd8
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [12] pkt 0x80c4bd8 ref 0 frags 0x80c74b8 (tcp_send():374)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c74b8 ref 0 frags (nil) (tcp_send():374)
[00:01:13.200,000] net_pkt: net_pkt_frag_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c74b8 ref 0 (net_pkt_unref_debug():597)
[00:01:13.200,000] net_core: processing_data: (0x80bd9c0): Dropping pkt 0x80c4c1c
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [13] pkt 0x80c4c1c ref 1 frags 0x80c749c (processing_data():174)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TX [13] pkt 0x80c4c1c ref 0 frags 0x80c749c (tcp_send():374)
[00:01:13.200,000] net_pkt: net_pkt_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c749c ref 0 frags (nil) (tcp_send():374)
[00:01:13.200,000] net_pkt: net_pkt_frag_unref_debug: (0x80bd9c0): TDATA (?) [0] frag 0x80c749c ref 0 (net_pkt_unref_debug():597)
work: 0x80cb060 work->handler: (nil)
ASSERTION FAIL [handler != ((void *)0)] @ WEST_TOPDIR/zephyr/kernel/work.c:650
@ WEST_TOPDIR/zephyr/lib/os/assert.c:43
[00:01:13.200,000] os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
[00:01:13.200,000] os: Current thread: 0x80bd9c0 (unknown)
[00:01:13.200,000] os: Halting system
Exiting due to fatal error

PoC

This was found using Defensics, if further details for reproduction are required - please let us know

Impact

Result of exploitation could lead to instability (i.e., crash) or denial of service attacks.

Patches

embargo: 2024-03-14

For more information

If you have any questions or comments about this advisory:

Credit

Synopsys Cybersecurity Research Center (CyRC) Researcher: Kari Hulkko

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H

CVE ID

CVE-2023-7060

Weaknesses

Credits