Commit 955db450 authored by Jukka Rissanen's avatar Jukka Rissanen Committed by Josh Lilly
Browse files

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: default avatarJukka Rissanen <jukka.rissanen@nordicsemi.no>
(cherry picked from commit 6d41e683)
parent 5e05c015
Loading
Loading
Loading
Loading
+9 −1
Changes for subsys/net/ip/ipv4.c: 9 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -219,7 +219,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);
@@ -280,6 +280,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;
+1 −1
Changes for subsys/net/ip/net_core.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -135,7 +135,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);
+4 −2
Changes for subsys/net/ip/net_private.h: 4 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -72,12 +72,14 @@ static inline const char *net_context_state(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;
}
+4 −4
Changes for tests/net/icmpv4/src/main.c: 4 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -450,7 +450,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");
	}
@@ -467,7 +467,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");
	}
@@ -485,7 +485,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");
	}
@@ -501,7 +501,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);
	}
}
+1 −1
Changes for tests/net/virtual/src/main.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -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);
	}