| From foo@baz Tue Nov 21 15:28:16 CET 2017 |
| From: "Eric W. Biederman" <ebiederm@xmission.com> |
| Date: Wed, 15 Nov 2017 22:17:48 -0600 |
| Subject: net/sctp: Always set scope_id in sctp_inet6_skb_msgname |
| |
| From: "Eric W. Biederman" <ebiederm@xmission.com> |
| |
| |
| [ Upstream commit 7c8a61d9ee1df0fb4747879fa67a99614eb62fec ] |
| |
| Alexandar Potapenko while testing the kernel with KMSAN and syzkaller |
| discovered that in some configurations sctp would leak 4 bytes of |
| kernel stack. |
| |
| Working with his reproducer I discovered that those 4 bytes that |
| are leaked is the scope id of an ipv6 address returned by recvmsg. |
| |
| With a little code inspection and a shrewd guess I discovered that |
| sctp_inet6_skb_msgname only initializes the scope_id field for link |
| local ipv6 addresses to the interface index the link local address |
| pertains to instead of initializing the scope_id field for all ipv6 |
| addresses. |
| |
| That is almost reasonable as scope_id's are meaniningful only for link |
| local addresses. Set the scope_id in all other cases to 0 which is |
| not a valid interface index to make it clear there is nothing useful |
| in the scope_id field. |
| |
| There should be no danger of breaking userspace as the stack leak |
| guaranteed that previously meaningless random data was being returned. |
| |
| Fixes: 372f525b495c ("SCTP: Resync with LKSCTP tree.") |
| History-tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git |
| Reported-by: Alexander Potapenko <glider@google.com> |
| Tested-by: Alexander Potapenko <glider@google.com> |
| Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/sctp/ipv6.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/net/sctp/ipv6.c |
| +++ b/net/sctp/ipv6.c |
| @@ -805,6 +805,8 @@ static void sctp_inet6_skb_msgname(struc |
| if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { |
| struct sctp_ulpevent *ev = sctp_skb2event(skb); |
| addr->v6.sin6_scope_id = ev->iif; |
| + } else { |
| + addr->v6.sin6_scope_id = 0; |
| } |
| } |
| |