|
|
b97c30 |
From 4388f1ebeee9ba362b6b94ea587e1006a8721a15 Mon Sep 17 00:00:00 2001
|
|
|
b97c30 |
From: David Lebrun <dlebrun@google.com>
|
|
|
b97c30 |
Date: Fri, 2 Sep 2022 10:45:06 +0100
|
|
|
b97c30 |
Subject: [PATCH] ipv6: sr: fix out-of-bounds read when setting HMAC data.
|
|
|
b97c30 |
Git-commit: 84a53580c5d2138c7361c7c3eea5b31827e63b35
|
|
|
b97c30 |
Patch-mainline: v6.0-rc5
|
|
|
b97c30 |
References: bsc#1211592
|
|
|
b97c30 |
|
|
|
b97c30 |
The SRv6 layer allows defining HMAC data that can later be used to sign IPv6
|
|
|
b97c30 |
Segment Routing Headers. This configuration is realised via netlink through
|
|
|
b97c30 |
four attributes: SEG6_ATTR_HMACKEYID, SEG6_ATTR_SECRET, SEG6_ATTR_SECRETLEN and
|
|
|
b97c30 |
SEG6_ATTR_ALGID. Because the SECRETLEN attribute is decoupled from the actual
|
|
|
b97c30 |
length of the SECRET attribute, it is possible to provide invalid combinations
|
|
|
b97c30 |
(e.g., secret = "", secretlen = 64). This case is not checked in the code and
|
|
|
b97c30 |
with an appropriately crafted netlink message, an out-of-bounds read of up
|
|
|
b97c30 |
to 64 bytes (max secret length) can occur past the skb end pointer and into
|
|
|
b97c30 |
skb_shared_info:
|
|
|
b97c30 |
|
|
|
b97c30 |
Breakpoint 1, seg6_genl_sethmac (skb=<optimized out>, info=<optimized out>) at net/ipv6/seg6.c:208
|
|
|
b97c30 |
208 memcpy(hinfo->secret, secret, slen);
|
|
|
b97c30 |
(gdb) bt
|
|
|
b97c30 |
#0 seg6_genl_sethmac (skb=<optimized out>, info=<optimized out>) at net/ipv6/seg6.c:208
|
|
|
b97c30 |
#1 0xffffffff81e012e9 in genl_family_rcv_msg_doit (skb=skb@entry=0xffff88800b1f9f00, nlh=nlh@entry=0xffff88800b1b7600,
|
|
|
b97c30 |
extack=extack@entry=0xffffc90000ba7af0, ops=ops@entry=0xffffc90000ba7a80, hdrlen=4, net=0xffffffff84237580 <init_net>, family=<optimized out>,
|
|
|
b97c30 |
family=<optimized out>) at net/netlink/genetlink.c:731
|
|
|
b97c30 |
#2 0xffffffff81e01435 in genl_family_rcv_msg (extack=0xffffc90000ba7af0, nlh=0xffff88800b1b7600, skb=0xffff88800b1f9f00,
|
|
|
b97c30 |
family=0xffffffff82fef6c0 <seg6_genl_family>) at net/netlink/genetlink.c:775
|
|
|
b97c30 |
#3 genl_rcv_msg (skb=0xffff88800b1f9f00, nlh=0xffff88800b1b7600, extack=0xffffc90000ba7af0) at net/netlink/genetlink.c:792
|
|
|
b97c30 |
#4 0xffffffff81dfffc3 in netlink_rcv_skb (skb=skb@entry=0xffff88800b1f9f00, cb=cb@entry=0xffffffff81e01350 <genl_rcv_msg>)
|
|
|
b97c30 |
at net/netlink/af_netlink.c:2501
|
|
|
b97c30 |
#5 0xffffffff81e00919 in genl_rcv (skb=0xffff88800b1f9f00) at net/netlink/genetlink.c:803
|
|
|
b97c30 |
#6 0xffffffff81dff6ae in netlink_unicast_kernel (ssk=0xffff888010eec800, skb=0xffff88800b1f9f00, sk=0xffff888004aed000)
|
|
|
b97c30 |
at net/netlink/af_netlink.c:1319
|
|
|
b97c30 |
#7 netlink_unicast (ssk=ssk@entry=0xffff888010eec800, skb=skb@entry=0xffff88800b1f9f00, portid=portid@entry=0, nonblock=<optimized out>)
|
|
|
b97c30 |
at net/netlink/af_netlink.c:1345
|
|
|
b97c30 |
#8 0xffffffff81dff9a4 in netlink_sendmsg (sock=<optimized out>, msg=0xffffc90000ba7e48, len=<optimized out>) at net/netlink/af_netlink.c:1921
|
|
|
b97c30 |
...
|
|
|
b97c30 |
(gdb) p/x ((struct sk_buff *)0xffff88800b1f9f00)->head + ((struct sk_buff *)0xffff88800b1f9f00)->end
|
|
|
b97c30 |
$1 = 0xffff88800b1b76c0
|
|
|
b97c30 |
(gdb) p/x secret
|
|
|
b97c30 |
$2 = 0xffff88800b1b76c0
|
|
|
b97c30 |
(gdb) p slen
|
|
|
b97c30 |
$3 = 64 '@'
|
|
|
b97c30 |
|
|
|
b97c30 |
The OOB data can then be read back from userspace by dumping HMAC state. This
|
|
|
b97c30 |
commit fixes this by ensuring SECRETLEN cannot exceed the actual length of
|
|
|
b97c30 |
SECRET.
|
|
|
b97c30 |
|
|
|
b97c30 |
Reported-by: Lucas Leong <wmliang.tw@gmail.com>
|
|
|
b97c30 |
Tested: verified that EINVAL is correctly returned when secretlen > len(secret)
|
|
|
b97c30 |
Fixes: 4f4853dc1c9c1 ("ipv6: sr: implement API to control SR HMAC structure")
|
|
|
b97c30 |
Signed-off-by: David Lebrun <dlebrun@google.com>
|
|
|
b97c30 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
b97c30 |
Signed-off-by: Denis Kirjanov <denis.kirjanov@suse.com>
|
|
|
b97c30 |
---
|
|
|
b97c30 |
net/ipv6/seg6.c | 5 +++++
|
|
|
b97c30 |
1 file changed, 5 insertions(+)
|
|
|
b97c30 |
|
|
|
b97c30 |
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
|
|
|
b97c30 |
index 4458e46977fe..c7f5e76d1544 100644
|
|
|
b97c30 |
--- a/net/ipv6/seg6.c
|
|
|
b97c30 |
+++ b/net/ipv6/seg6.c
|
|
|
b97c30 |
@@ -129,6 +129,11 @@ static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
|
|
|
b97c30 |
goto out_unlock;
|
|
|
b97c30 |
}
|
|
|
b97c30 |
|
|
|
b97c30 |
+ if (slen > nla_len(info->attrs[SEG6_ATTR_SECRET])) {
|
|
|
b97c30 |
+ err = -EINVAL;
|
|
|
b97c30 |
+ goto out_unlock;
|
|
|
b97c30 |
+ }
|
|
|
b97c30 |
+
|
|
|
b97c30 |
if (hinfo) {
|
|
|
b97c30 |
err = seg6_hmac_info_del(net, hmackeyid);
|
|
|
b97c30 |
if (err)
|
|
|
b97c30 |
--
|
|
|
b97c30 |
2.16.4
|
|
|
b97c30 |
|