From: Jann Horn <jannh(a)google.com>
[ Upstream commit 6ab405114b0b229151ef06f4e31c7834dd09d0c0 ]
Check whether inputs from userspace are too long (explicit length field too
big or string not null-terminated) to avoid out-of-bounds reads.
As far as I can tell, this can at worst lead to very limited kernel heap
memory disclosure or oopses.
This bug can be triggered by an unprivileged user even if the xt_bpf module
is not loaded: iptables is available in network namespaces, and the xt_bpf
module can be autoloaded.
Triggering the bug with a classic BPF filter with fake length 0x1000 causes
the following KASAN report:
==================================================================
BUG: KASAN: slab-out-of-bounds in bpf_prog_create+0x84/0xf0
Read of size 32768 at addr ffff8801eff2c494 by task test/4627
CPU: 0 PID: 4627 Comm: test Not tainted 4.15.0-rc1+ #1
[...]
Call Trace:
dump_stack+0x5c/0x85
print_address_description+0x6a/0x260
kasan_report+0x254/0x370
? bpf_prog_create+0x84/0xf0
memcpy+0x1f/0x50
bpf_prog_create+0x84/0xf0
bpf_mt_check+0x90/0xd6 [xt_bpf]
[...]
Allocated by task 4627:
kasan_kmalloc+0xa0/0xd0
__kmalloc_node+0x47/0x60
xt_alloc_table_info+0x41/0x70 [x_tables]
[...]
The buggy address belongs to the object at ffff8801eff2c3c0
which belongs to the cache kmalloc-2048 of size 2048
The buggy address is located 212 bytes inside of
2048-byte region [ffff8801eff2c3c0, ffff8801eff2cbc0)
[...]
==================================================================
Fixes: e6f30c731718 ("netfilter: x_tables: add xt_bpf match")
Signed-off-by: Jann Horn <jannh(a)google.com>
Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org>
Signed-off-by: Zubin Mithra <zsm(a)chromium.org>
---
* Syzkaller triggered an OOB read with the following stacktrace:
__dump_stack lib/dump_stack.c:15 [inline]
dump_stack+0xcb/0x130 lib/dump_stack.c:56
print_trailer+0x151/0x15a mm/slub.c:658
object_err+0x35/0x3d mm/slub.c:665
print_address_description mm/kasan/report.c:188 [inline]
kasan_report_error mm/kasan/report.c:285 [inline]
kasan_report.part.0.cold+0x21a/0x4c1 mm/kasan/report.c:310
kasan_report+0x25/0x30 mm/kasan/report.c:297
check_memory_region_inline mm/kasan/kasan.c:292 [inline]
check_memory_region+0x116/0x190 mm/kasan/kasan.c:299
memcpy+0x24/0x50 mm/kasan/kasan.c:334
bpf_prog_create+0xdd/0x230 net/core/filter.c:1075
bpf_mt_check+0xb1/0x100 net/netfilter/xt_bpf.c:31
xt_check_match+0x26b/0x560 net/netfilter/x_tables.c:444
check_match net/ipv4/netfilter/ip_tables.c:593 [inline]
find_check_match net/ipv4/netfilter/ip_tables.c:616 [inline]
find_check_entry.isra.0+0x2fe/0x950 net/ipv4/netfilter/ip_tables.c:673
translate_table+0xb3f/0x15b0 net/ipv4/netfilter/ip_tables.c:878
do_replace net/ipv4/netfilter/ip_tables.c:1300 [inline]
do_ipt_set_ctl+0x2cf/0x460 net/ipv4/netfilter/ip_tables.c:1864
nf_sockopt net/netfilter/nf_sockopt.c:105 [inline]
nf_setsockopt+0x72/0xd0 net/netfilter/nf_sockopt.c:114
ip_setsockopt net/ipv4/ip_sockglue.c:1227 [inline]
ip_setsockopt+0xa0/0xb0 net/ipv4/ip_sockglue.c:1212
udp_setsockopt+0x53/0x90 net/ipv4/udp.c:2162
sock_common_setsockopt+0x9f/0xe0 net/core/sock.c:2697
SYSC_setsockopt net/socket.c:1769 [inline]
SyS_setsockopt+0x146/0x210 net/socket.c:1748
entry_SYSCALL_64_fastpath+0x1e/0xa0
* This commit is present in linux-4.14.y.
* This patch resolves conflicts that arise due to the following commit
not being present in linux-4.9.y, linux-4.4.y:
- 2c16d6033264 ("netfilter: xt_bpf: support ebpf")
* Tests run: syzkaller reproducer
net/netfilter/xt_bpf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c
index dffee9d47ec4b..7b993f25aab92 100644
--- a/net/netfilter/xt_bpf.c
+++ b/net/netfilter/xt_bpf.c
@@ -25,6 +25,9 @@ static int bpf_mt_check(const struct xt_mtchk_param *par)
struct xt_bpf_info *info = par->matchinfo;
struct sock_fprog_kern program;
+ if (info->bpf_program_num_elem > XT_BPF_MAX_NUM_INSTR)
+ return -EINVAL;
+
program.len = info->bpf_program_num_elem;
program.filter = info->bpf_program;
--
2.25.0.265.gbab2e86ba0-goog
From: Martynas Pumputis <martynas(a)weave.works>
[ Upstream commit ed07d9a021df6da53456663a76999189badc432a ]
This patch enables the clash resolution for NAT (disabled in
"590b52e10d41") if clashing conntracks match (i.e. both tuples are equal)
and a protocol allows it.
The clash might happen for a connections-less protocol (e.g. UDP) when
two threads in parallel writes to the same socket and consequent calls
to "get_unique_tuple" return the same tuples (incl. reply tuples).
In this case it is safe to perform the resolution, as the losing CT
describes the same mangling as the winning CT, so no modifications to
the packet are needed, and the result of rules traversal for the loser's
packet stays valid.
Signed-off-by: Martynas Pumputis <martynas(a)weave.works>
Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org>
Signed-off-by: Andy Strohman <astroh(a)amazon.com>
---
net/netfilter/nf_conntrack_core.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5123e91b1982..4ced7c7102b6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -632,6 +632,18 @@ nf_ct_key_equal(struct nf_conntrack_tuple_hash *h,
net_eq(net, nf_ct_net(ct));
}
+static inline bool
+nf_ct_match(const struct nf_conn *ct1, const struct nf_conn *ct2)
+{
+ return nf_ct_tuple_equal(&ct1->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ &ct2->tuplehash[IP_CT_DIR_ORIGINAL].tuple) &&
+ nf_ct_tuple_equal(&ct1->tuplehash[IP_CT_DIR_REPLY].tuple,
+ &ct2->tuplehash[IP_CT_DIR_REPLY].tuple) &&
+ nf_ct_zone_equal(ct1, nf_ct_zone(ct2), IP_CT_DIR_ORIGINAL) &&
+ nf_ct_zone_equal(ct1, nf_ct_zone(ct2), IP_CT_DIR_REPLY) &&
+ net_eq(nf_ct_net(ct1), nf_ct_net(ct2));
+}
+
/* caller must hold rcu readlock and none of the nf_conntrack_locks */
static void nf_ct_gc_expired(struct nf_conn *ct)
{
@@ -825,19 +837,21 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb,
/* This is the conntrack entry already in hashes that won race. */
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
const struct nf_conntrack_l4proto *l4proto;
+ enum ip_conntrack_info oldinfo;
+ struct nf_conn *loser_ct = nf_ct_get(skb, &oldinfo);
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
if (l4proto->allow_clash &&
- ((ct->status & IPS_NAT_DONE_MASK) == 0) &&
!nf_ct_is_dying(ct) &&
atomic_inc_not_zero(&ct->ct_general.use)) {
- enum ip_conntrack_info oldinfo;
- struct nf_conn *loser_ct = nf_ct_get(skb, &oldinfo);
-
- nf_ct_acct_merge(ct, ctinfo, loser_ct);
- nf_conntrack_put(&loser_ct->ct_general);
- nf_ct_set(skb, ct, oldinfo);
- return NF_ACCEPT;
+ if (((ct->status & IPS_NAT_DONE_MASK) == 0) ||
+ nf_ct_match(ct, loser_ct)) {
+ nf_ct_acct_merge(ct, ctinfo, loser_ct);
+ nf_conntrack_put(&loser_ct->ct_general);
+ nf_ct_set(skb, ct, oldinfo);
+ return NF_ACCEPT;
+ }
+ nf_ct_put(ct);
}
NF_CT_STAT_INC(net, drop);
return NF_DROP;
--
2.16.6
Hello Greg,
Can you please consider including the following patch in the stable
linux-5.4.y and linux-5.5.y?
This is to downgrade "EDAC skx: Can't get tolm/tohm" to debug level
on missing PCI device.
854bb48018d5("EDAC: skx_common: downgrade message importance
on missing PCI device")
Thanks,
Qian Lu