diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-05-03 17:00:15 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-05-20 08:17:05 +0200 |
| commit | 875df4e784530430b13e77f4c37e37466db4ef3c (patch) | |
| tree | 99bc2b5c8dd7eae690d9d1f39750f0b468d9c5c0 /src/ipcpd/eth | |
| parent | ee329b9047532c7e9199bba2246992ea1a619df8 (diff) | |
| download | ouroboros-875df4e784530430b13e77f4c37e37466db4ef3c.tar.gz ouroboros-875df4e784530430b13e77f4c37e37466db4ef3c.zip | |
ipcpd: Reject outbound packets on eth
AF_PACKET under `tc netem duplicate`, produces an extra
PACKET_OUTGOING frame at the source that receive path didn't reject.
Read with recvfrom(2) and discard frames whose sll_pkttype is
PACKET_OUTGOING. Restores the dst-MAC check body (defense in depth,
also bumps n_bad_id) so any frame addressed neither to us nor the
broadcast MAC is dropped before flow lookup.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/ipcpd/eth')
| -rw-r--r-- | src/ipcpd/eth/eth.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index 7981ade5..10a8b338 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -1118,6 +1118,10 @@ static void * eth_ipcp_packet_reader(void * o) fd_set fds; int frame_len; #endif +#if defined(HAVE_RAW_SOCKETS) + struct sockaddr_ll src; + socklen_t slen; +#endif size_t eth_len; uint8_t hcs; struct eth_frame * e_frame; @@ -1168,8 +1172,10 @@ static void * eth_ipcp_packet_reader(void * o) FETCH_ADD_RELAXED(ð_data.stat.n_buf_f, 1); continue; } - frame_len = recv(eth_data.s_fd, buf, - ETH_MTU + ETH_HEADER_TOT_SIZE, 0); + slen = sizeof(src); + frame_len = recvfrom(eth_data.s_fd, buf, + ETH_MTU + ETH_HEADER_TOT_SIZE, 0, + (struct sockaddr *) &src, &slen); #endif if (frame_len <= 0) { log_dbg("Failed to receive frame."); @@ -1179,6 +1185,12 @@ static void * eth_ipcp_packet_reader(void * o) } #endif +#if defined(HAVE_RAW_SOCKETS) + /* Drop our own egress. */ + if (src.sll_pkttype == PACKET_OUTGOING) + goto fail_frame; +#endif + #if defined(HAVE_BPF) && !defined(HAVE_NETMAP) e_frame = (struct eth_frame *) (buf + ((struct bpf_hdr *) buf)->bh_hdrlen); @@ -1196,6 +1208,8 @@ static void * eth_ipcp_packet_reader(void * o) e_frame->dst_hwaddr, MAC_SIZE) && memcmp(br_addr, e_frame->dst_hwaddr, MAC_SIZE)) { + FETCH_ADD_RELAXED(ð_data.stat.n_bad_id, 1); + goto fail_frame; } #endif length = ntohs(e_frame->length); |
