Dave Jones
a98f917589
ipv6: handle -EFAULT from skb_copy_bits
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);
}
Signed-off-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2016-12-23 12:20:39 -05:00
..
2016-11-02 15:26:02 -04:00
2016-12-06 21:42:20 +01:00
2015-07-31 15:21:30 -07:00
2016-12-03 23:21:37 -05:00
2015-12-22 15:57:54 -05:00
2016-12-02 13:46:08 -05:00
2016-11-04 14:45:23 -04:00
2015-03-31 13:51:54 -04:00
2016-08-13 14:56:17 -07:00
2016-12-23 12:19:18 -05:00
2016-12-03 12:29:53 -05:00
2016-06-27 15:06:15 -04:00
2015-09-02 15:31:00 -07:00
2016-11-09 20:40:06 -05:00
2016-09-10 23:12:51 -07:00
2016-05-29 22:24:21 -07:00
2016-12-03 12:29:53 -05:00
2016-12-17 11:13:19 -05:00
2016-10-29 12:01:49 -04:00
2016-06-14 15:26:42 -04:00
2016-09-09 16:50:23 -07:00
2016-05-03 16:08:14 -04:00
2016-11-18 10:59:15 -05:00
2016-06-18 22:11:38 -07:00
2016-06-08 00:25:38 -07:00
2016-12-02 13:34:58 -05:00
2016-04-07 16:53:29 -04:00
2016-11-25 16:26:04 -05:00
2016-12-03 12:29:53 -05:00
2016-11-02 15:18:36 -04:00
2016-12-03 12:29:53 -05:00
2016-10-31 16:18:30 -04:00
2016-11-04 14:45:23 -04:00
2016-11-09 20:40:06 -05:00
2016-11-16 11:29:46 -05:00
2016-11-16 11:29:46 -05:00
2015-08-13 17:08:39 -07:00
2016-10-21 11:29:02 -04:00
2015-10-05 03:16:47 -07:00
2016-12-03 23:21:37 -05:00
2016-11-04 14:45:23 -04:00
2016-12-02 12:34:22 -05:00
2016-11-04 14:45:23 -04:00
2016-09-30 01:50:44 -04:00
2014-09-19 17:15:31 -04:00
2016-12-23 12:20:39 -05:00
2016-11-03 15:41:11 -04:00
2016-12-17 21:37:06 -05:00
2016-11-09 20:40:06 -05:00
2016-11-09 20:40:06 -05:00
2016-11-16 11:29:46 -05:00
2016-11-18 10:59:15 -05:00
2016-12-02 12:49:59 -05:00
2016-06-27 15:06:17 -04:00
2016-12-05 13:32:24 -05:00
2015-02-28 16:56:51 -05:00
2015-11-03 10:52:13 -05:00
2016-11-24 15:32:14 -05:00
2016-05-20 18:03:15 -04:00
2016-11-26 23:42:21 -05:00
2016-11-24 15:32:14 -05:00
2016-09-21 10:09:14 +02:00
2015-03-31 13:58:35 -04:00
2013-12-06 12:37:56 -05:00
2016-01-15 15:07:23 -05:00
2015-10-24 06:54:12 -07:00
2016-09-12 15:52:44 -07:00
2014-05-06 07:08:38 +02:00
2014-08-24 22:37:52 -07:00
2016-11-18 10:59:15 -05:00