Patch "ipv6: handle -EFAULT from skb_copy_bits" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ipv6: handle -EFAULT from skb_copy_bits
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-handle-efault-from-skb_copy_bits.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Jan 12 21:36:14 CET 2017
From: Dave Jones <[email protected]>
Date: Thu, 22 Dec 2016 11:16:22 -0500
Subject: ipv6: handle -EFAULT from skb_copy_bits
From: Dave Jones <[email protected]>
[ Upstream commit a98f91758995cb59611e61318dddd8a6956b52c3 ]
By setting certain socket options on ipv6 raw sockets, we can confuse the length calculation in rawv6_push_pending_frames triggering a BUG_ON.
RIP: 0010:[<ffffffff817c6390>] [<ffffffff817c6390>] rawv6_sendmsg+0xc30/0xc40 RSP: 0018:ffff881f6c4a7c18 EFLAGS: 00010282 RAX: 00000000fffffff2 RBX: ffff881f6c681680 RCX: 0000000000000002 RDX: ffff881f6c4a7cf8 RSI: 0000000000000030 RDI: ffff881fed0f6a00 RBP: ffff881f6c4a7da8 R08: 0000000000000000 R09: 0000000000000009 R10: ffff881fed0f6a00 R11: 0000000000000009 R12: 0000000000000030 R13: ffff881fed0f6a00 R14: ffff881fee39ba00 R15: ffff881fefa93a80 Call Trace: [<ffffffff8118ba23>] ? unmap_page_range+0x693/0x830 [<ffffffff81772697>] inet_sendmsg+0x67/0xa0 [<ffffffff816d93f8>] sock_sendmsg+0x38/0x50 [<ffffffff816d982f>] SYSC_sendto+0xef/0x170 [<ffffffff816da27e>] SyS_sendto+0xe/0x10 [<ffffffff81002910>] do_syscall_64+0x50/0xa0 [<ffffffff817f7cbc>] entry_SYSCALL64_slow_path+0x25/0x25
Handle by jumping to the failure path if skb_copy_bits gets an EFAULT.
Reproducer:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define LEN 504
int main(int argc, char* argv[])
{
int fd;
int zero = 0;
char buf[LEN];
memset(buf, 0, LEN);
fd = socket(AF_INET6, SOCK_RAW, 7);
setsockopt(fd, SOL_IPV6, IPV6_CHECKSUM, &zero, 4);
setsockopt(fd, SOL_IPV6, IPV6_DSTOPTS, &buf, LEN);
sendto(fd, buf, 1, 0, (struct sockaddr *) buf, 110);
}--- net/ipv6/raw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/ipv6/raw.c +5 -1
@@ -589,7 +589,11 @@ static int rawv6_push_pending_frames(str } offset +=skb_transport_offset (skb); -BUG_ON (skb_copy_bits (skb, offset, &csum,2 )); + err =skb_copy_bits (skb, offset, &csum,2 ); +if (err <0 ) { +ip6_flush_pending_frames (sk); + goto out; + }/* in case cksum was not initialized */ if (unlikely (csum))
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/ipv6-handle-efault-from-skb_copy_bits.patch