mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 05:00:55 +07:00
net: sched: Fix memory exposure from short TCA_U32_SEL
Via u32_change(), TCA_U32_SEL has an unspecified type in the netlink policy, so max length isn't enforced, only minimum. This means nkeys (from userspace) was being trusted without checking the actual size of nla_len(), which could lead to a memory over-read, and ultimately an exposure via a call to u32_dump(). Reachability is CAP_NET_ADMIN within a namespace. Reported-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Jamal Hadi Salim <jhs@mojatatu.com> Cc: Cong Wang <xiyou.wangcong@gmail.com> Cc: Jiri Pirko <jiri@resnulli.us> Cc: "David S. Miller" <davem@davemloft.net> Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e75d039a54
commit
98c8f125fd
@ -914,6 +914,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
|
||||
struct nlattr *opt = tca[TCA_OPTIONS];
|
||||
struct nlattr *tb[TCA_U32_MAX + 1];
|
||||
u32 htid, flags = 0;
|
||||
size_t sel_size;
|
||||
int err;
|
||||
#ifdef CONFIG_CLS_U32_PERF
|
||||
size_t size;
|
||||
@ -1076,8 +1077,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
|
||||
}
|
||||
|
||||
s = nla_data(tb[TCA_U32_SEL]);
|
||||
sel_size = struct_size(s, keys, s->nkeys);
|
||||
if (nla_len(tb[TCA_U32_SEL]) < sel_size) {
|
||||
err = -EINVAL;
|
||||
goto erridr;
|
||||
}
|
||||
|
||||
n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
|
||||
n = kzalloc(offsetof(typeof(*n), sel) + sel_size, GFP_KERNEL);
|
||||
if (n == NULL) {
|
||||
err = -ENOBUFS;
|
||||
goto erridr;
|
||||
@ -1092,7 +1098,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
|
||||
memcpy(&n->sel, s, sel_size);
|
||||
RCU_INIT_POINTER(n->ht_up, ht);
|
||||
n->handle = handle;
|
||||
n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
|
||||
|
Loading…
Reference in New Issue
Block a user