From 069fbaabc592681b60910a964f09de63548f19d2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 19 Dec 2023 11:16:59 +0200 Subject: [PATCH 1/2] net: ipv4: Check localhost for incoming packet If we receive a packet from non localhost interface, then drop it if either source or destination address is a localhost address. Signed-off-by: Jukka Rissanen (cherry picked from commit 6d41e6835259d4c6ede50b00b0ba4b84f80eeca6) --- subsys/net/ip/ipv4.c | 10 +++++++++- subsys/net/ip/net_core.c | 2 +- subsys/net/ip/net_private.h | 6 ++++-- tests/net/icmpv4/src/main.c | 8 ++++---- tests/net/virtual/src/main.c | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 922068274f72..b294563896c8 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -220,7 +220,7 @@ int net_ipv4_parse_hdr_options(struct net_pkt *pkt, } #endif -enum net_verdict net_ipv4_input(struct net_pkt *pkt) +enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback) { NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv4_access, struct net_ipv4_hdr); NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr); @@ -281,6 +281,14 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt) net_pkt_update_length(pkt, pkt_len); } + if (!is_loopback) { + if (net_ipv4_is_addr_loopback((struct in_addr *)hdr->dst) || + net_ipv4_is_addr_loopback((struct in_addr *)hdr->src)) { + NET_DBG("DROP: localhost packet"); + goto drop; + } + } + if (net_ipv4_is_addr_mcast((struct in_addr *)hdr->src)) { NET_DBG("DROP: src addr is %s", "mcast"); goto drop; diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index c94607b44859..afa964c819a1 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -136,7 +136,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt, if (IS_ENABLED(CONFIG_NET_IPV6) && vtc_vhl == 0x60) { return net_ipv6_input(pkt, is_loopback); } else if (IS_ENABLED(CONFIG_NET_IPV4) && vtc_vhl == 0x40) { - return net_ipv4_input(pkt); + return net_ipv4_input(pkt, is_loopback); } NET_DBG("Unknown IP family packet (0x%x)", NET_IPV6_HDR(pkt)->vtc & 0xf0); diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index d8d57a6bdc7e..9712c041ea9f 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -97,12 +97,14 @@ static inline bool net_context_is_reuseport_set(struct net_context *context) #endif #if defined(CONFIG_NET_NATIVE) -enum net_verdict net_ipv4_input(struct net_pkt *pkt); +enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback); enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback); #else -static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt) +static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt, + bool is_loopback) { ARG_UNUSED(pkt); + ARG_UNUSED(is_loopback); return NET_CONTINUE; } diff --git a/tests/net/icmpv4/src/main.c b/tests/net/icmpv4/src/main.c index c48e480a769c..afa5c0072802 100644 --- a/tests/net/icmpv4/src/main.c +++ b/tests/net/icmpv4/src/main.c @@ -452,7 +452,7 @@ static void icmpv4_send_echo_req(void) zassert_true(false, "EchoRequest packet prep failed"); } - if (net_ipv4_input(pkt)) { + if (net_ipv4_input(pkt, false)) { net_pkt_unref(pkt); zassert_true(false, "Failed to send"); } @@ -474,7 +474,7 @@ static void icmpv4_send_echo_rep(void) zassert_true(false, "EchoReply packet prep failed"); } - if (net_ipv4_input(pkt)) { + if (net_ipv4_input(pkt, false)) { net_pkt_unref(pkt); zassert_true(false, "Failed to send"); } @@ -494,7 +494,7 @@ ZTEST(net_icmpv4, test_icmpv4_send_echo_req_opt) zassert_true(false, "EchoRequest with opts packet prep failed"); } - if (net_ipv4_input(pkt)) { + if (net_ipv4_input(pkt, false)) { net_pkt_unref(pkt); zassert_true(false, "Failed to send"); } @@ -510,7 +510,7 @@ ZTEST(net_icmpv4, test_send_echo_req_bad_opt) "EchoRequest with bad opts packet prep failed"); } - if (net_ipv4_input(pkt)) { + if (net_ipv4_input(pkt, false)) { net_pkt_unref(pkt); } } diff --git a/tests/net/virtual/src/main.c b/tests/net/virtual/src/main.c index be0ba1715b6a..b124f14a5ba9 100644 --- a/tests/net/virtual/src/main.c +++ b/tests/net/virtual/src/main.c @@ -1040,7 +1040,7 @@ static void test_virtual_recv_data_from_tunnel(int remote_ip, net_pkt_cursor_init(outer); if (peer_addr.sa_family == AF_INET) { - verdict = net_ipv4_input(outer); + verdict = net_ipv4_input(outer, false); } else { verdict = net_ipv6_input(outer, false); } From d4a7cfbdbff27cbbd0e5f260824a8b230d66c653 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 19 Dec 2023 12:31:37 +0200 Subject: [PATCH 2/2] net: ipv4: Drop packet if source address is my address If we receive a packet where the source address is our own address, then we should drop it. Signed-off-by: Jukka Rissanen (cherry picked from commit 19392a6d2b5eee26ba62fcc6f61e769b4cebaa32) --- subsys/net/ip/ipv4.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index b294563896c8..6da4fac87846 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -287,6 +287,11 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback) NET_DBG("DROP: localhost packet"); goto drop; } + + if (net_ipv4_is_my_addr((struct in_addr *)hdr->src)) { + NET_DBG("DROP: src addr is %s", "mine"); + goto drop; + } } if (net_ipv4_is_addr_mcast((struct in_addr *)hdr->src)) {