Skip to content

Commit 03ea11d

Browse files
ummakynesgregkh
authored andcommitted
netfilter: arp_tables: fix IEEE1394 ARP payload parsing
[ Upstream commit 1e8e3f4 ] Weiming Shi says: "arp_packet_match() unconditionally parses the ARP payload assuming two hardware addresses are present (source and target). However, IPv4-over-IEEE1394 ARP (RFC 2734) omits the target hardware address field, and arp_hdr_len() already accounts for this by returning a shorter length for ARPHRD_IEEE1394 devices. As a result, on IEEE1394 interfaces arp_packet_match() advances past a nonexistent target hardware address and reads the wrong bytes for both the target device address comparison and the target IP address. This causes arptables rules to match against garbage data, leading to incorrect filtering decisions: packets that should be accepted may be dropped and vice versa. The ARP stack in net/ipv4/arp.c (arp_create and arp_process) already handles this correctly by skipping the target hardware address for ARPHRD_IEEE1394. Apply the same pattern to arp_packet_match()." Mangle the original patch to always return 0 (no match) in case user matches on the target hardware address which is never present in IEEE1394. Note that this returns 0 (no match) for either normal and inverse match because matching in the target hardware address in ARPHRD_IEEE1394 has never been supported by arptables. This is intentional, matching on the target hardware address should never evaluate true for ARPHRD_IEEE1394. Moreover, adjust arpt_mangle to drop the packet too as AI suggests: In arpt_mangle, the logic assumes a standard ARP layout. Because IEEE1394 (FireWire) omits the target hardware address, the linear pointer arithmetic miscalculates the offset for the target IP address. This causes mangling operations to write to the wrong location, leading to packet corruption. To ensure safety, this patch drops packets (NF_DROP) when mangling is requested for these fields on IEEE1394 devices, as the current implementation cannot correctly map the FireWire ARP payload. This omits both mangling target hardware and IP address. Even if IP address mangling should be possible in IEEE1394, this would require to adjust arpt_mangle offset calculation, which has never been supported. Based on patch from Weiming Shi <bestswngs@gmail.com>. Fixes: 6752c8d ("firewire net, ipv4 arp: Extend hardware address and remove driver-level packet inspection.") Reported-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f9204a2 commit 03ea11d

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

net/ipv4/netfilter/arp_tables.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,25 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
110110
arpptr += dev->addr_len;
111111
memcpy(&src_ipaddr, arpptr, sizeof(u32));
112112
arpptr += sizeof(u32);
113-
tgt_devaddr = arpptr;
114-
arpptr += dev->addr_len;
113+
114+
if (IS_ENABLED(CONFIG_FIREWIRE_NET) && dev->type == ARPHRD_IEEE1394) {
115+
if (unlikely(memchr_inv(arpinfo->tgt_devaddr.mask, 0,
116+
sizeof(arpinfo->tgt_devaddr.mask))))
117+
return 0;
118+
119+
tgt_devaddr = NULL;
120+
} else {
121+
tgt_devaddr = arpptr;
122+
arpptr += dev->addr_len;
123+
}
115124
memcpy(&tgt_ipaddr, arpptr, sizeof(u32));
116125

117126
if (NF_INVF(arpinfo, ARPT_INV_SRCDEVADDR,
118127
arp_devaddr_compare(&arpinfo->src_devaddr, src_devaddr,
119-
dev->addr_len)) ||
128+
dev->addr_len)))
129+
return 0;
130+
131+
if (tgt_devaddr &&
120132
NF_INVF(arpinfo, ARPT_INV_TGTDEVADDR,
121133
arp_devaddr_compare(&arpinfo->tgt_devaddr, tgt_devaddr,
122134
dev->addr_len)))

net/ipv4/netfilter/arpt_mangle.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,21 @@ target(struct sk_buff *skb, const struct xt_action_param *par)
4040
}
4141
arpptr += pln;
4242
if (mangle->flags & ARPT_MANGLE_TDEV) {
43+
if (unlikely(IS_ENABLED(CONFIG_FIREWIRE_NET) &&
44+
skb->dev->type == ARPHRD_IEEE1394))
45+
return NF_DROP;
46+
4347
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
4448
(arpptr + hln > skb_tail_pointer(skb)))
4549
return NF_DROP;
4650
memcpy(arpptr, mangle->tgt_devaddr, hln);
4751
}
4852
arpptr += hln;
4953
if (mangle->flags & ARPT_MANGLE_TIP) {
54+
if (unlikely(IS_ENABLED(CONFIG_FIREWIRE_NET) &&
55+
skb->dev->type == ARPHRD_IEEE1394))
56+
return NF_DROP;
57+
5058
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
5159
(arpptr + pln > skb_tail_pointer(skb)))
5260
return NF_DROP;

0 commit comments

Comments
 (0)