Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/filter: Permit reading NET in load_bytes_relative when MAC not set

Added a check in the switch case on start_header that checks for
the existence of the header, and in the case that MAC is not set
and the caller requests for MAC, -EFAULT. If the caller requests
for NET then MAC's existence is completely ignored.

There is no function to check NET header's existence and as far
as cgroup_skb/egress is concerned it should always be set.

Removed for ptr >= the start of header, considering offset is
bounded unsigned and should always be true. len <= end - mac is
redundant to ptr + len <= end.

Fixes: 3eee1f75f2b9 ("bpf: fix bpf_skb_load_bytes_relative pkt length check")
Signed-off-by: YiFei Zhu <zhuyifei@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/76bb820ddb6a95f59a772ecbd8c8a336f646b362.1591812755.git.zhuyifei@google.com

authored by

YiFei Zhu and committed by
Daniel Borkmann
0f5d82f1 47f6bc4c

+9 -7
+9 -7
net/core/filter.c
··· 1755 1755 u32, offset, void *, to, u32, len, u32, start_header) 1756 1756 { 1757 1757 u8 *end = skb_tail_pointer(skb); 1758 - u8 *net = skb_network_header(skb); 1759 - u8 *mac = skb_mac_header(skb); 1760 - u8 *ptr; 1758 + u8 *start, *ptr; 1761 1759 1762 - if (unlikely(offset > 0xffff || len > (end - mac))) 1760 + if (unlikely(offset > 0xffff)) 1763 1761 goto err_clear; 1764 1762 1765 1763 switch (start_header) { 1766 1764 case BPF_HDR_START_MAC: 1767 - ptr = mac + offset; 1765 + if (unlikely(!skb_mac_header_was_set(skb))) 1766 + goto err_clear; 1767 + start = skb_mac_header(skb); 1768 1768 break; 1769 1769 case BPF_HDR_START_NET: 1770 - ptr = net + offset; 1770 + start = skb_network_header(skb); 1771 1771 break; 1772 1772 default: 1773 1773 goto err_clear; 1774 1774 } 1775 1775 1776 - if (likely(ptr >= mac && ptr + len <= end)) { 1776 + ptr = start + offset; 1777 + 1778 + if (likely(ptr + len <= end)) { 1777 1779 memcpy(to, ptr, len); 1778 1780 return 0; 1779 1781 }