* [syzbot] [fs?] general protection fault in splice_to_socket @ 2023-06-12 9:43 syzbot 2023-06-14 8:57 ` David Howells 2023-06-14 9:00 ` David Howells 0 siblings, 2 replies; 4+ messages in thread From: syzbot @ 2023-06-12 9:43 UTC (permalink / raw) To: brauner, dhowells, kuba, linux-fsdevel, linux-kernel, netdev, syzkaller-bugs, viro Hello, syzbot found the following issue on: HEAD commit: e7c5433c5aaa tools: ynl: Remove duplicated include in hand.. git tree: net-next console+strace: https://syzkaller.appspot.com/x/log.txt?x=10d8188b280000 kernel config: https://syzkaller.appspot.com/x/.config?x=526f919910d4a671 dashboard link: https://syzkaller.appspot.com/bug?extid=f9e28a23426ac3b24f20 compiler: gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12715143280000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=17a936f1280000 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/13c08af1fd21/disk-e7c5433c.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/35820511752b/vmlinux-e7c5433c.xz kernel image: https://storage.googleapis.com/syzbot-assets/6a8cbec0d40f/bzImage-e7c5433c.xz The issue was bisected to: commit 2dc334f1a63a8839b88483a3e73c0f27c9c1791c Author: David Howells <dhowells@redhat.com> Date: Wed Jun 7 18:19:09 2023 +0000 splice, net: Use sendmsg(MSG_SPLICE_PAGES) rather than ->sendpage() bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=12c225b3280000 final oops: https://syzkaller.appspot.com/x/report.txt?x=11c225b3280000 console output: https://syzkaller.appspot.com/x/log.txt?x=16c225b3280000 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+f9e28a23426ac3b24f20@syzkaller.appspotmail.com Fixes: 2dc334f1a63a ("splice, net: Use sendmsg(MSG_SPLICE_PAGES) rather than ->sendpage()") general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 1 PID: 5007 Comm: syz-executor330 Not tainted 6.4.0-rc5-syzkaller-00915-ge7c5433c5aaa #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023 RIP: 0010:pipe_buf_release include/linux/pipe_fs_i.h:203 [inline] RIP: 0010:splice_to_socket+0xa91/0xe30 fs/splice.c:933 Code: 10 48 89 f8 48 c1 e8 03 42 80 3c 28 00 0f 85 19 03 00 00 49 8b 46 10 49 c7 46 10 00 00 00 00 48 8d 78 08 48 89 fa 48 c1 ea 03 <42> 80 3c 2a 00 0f 85 e3 02 00 00 4c 89 f6 4c 89 e7 ff 50 08 83 44 RSP: 0018:ffffc90003adfa28 EFLAGS: 00010202 RAX: 0000000000000000 RBX: 0000000000008001 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffffffff81f4e014 RDI: 0000000000000008 RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 1ffffffff2186c9b R12: ffff88802819f000 R13: dffffc0000000000 R14: ffff888077c05028 R15: 0000000000008001 FS: 00007f82b229b700(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f82b227a718 CR3: 0000000075e14000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> do_splice_from fs/splice.c:969 [inline] do_splice+0xb8c/0x1e50 fs/splice.c:1309 __do_splice+0x14e/0x270 fs/splice.c:1387 __do_sys_splice fs/splice.c:1598 [inline] __se_sys_splice fs/splice.c:1580 [inline] __x64_sys_splice+0x19c/0x250 fs/splice.c:1580 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f82b22e8fc9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 81 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f82b229b2f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000113 RAX: ffffffffffffffda RBX: 00007f82b2371428 RCX: 00007f82b22e8fc9 RDX: 0000000000000008 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007f82b2371420 R08: 0000000002000007 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82b237142c R13: 00007f82b233f004 R14: 0100000000000000 R15: 0000000000022000 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:pipe_buf_release include/linux/pipe_fs_i.h:203 [inline] RIP: 0010:splice_to_socket+0xa91/0xe30 fs/splice.c:933 Code: 10 48 89 f8 48 c1 e8 03 42 80 3c 28 00 0f 85 19 03 00 00 49 8b 46 10 49 c7 46 10 00 00 00 00 48 8d 78 08 48 89 fa 48 c1 ea 03 <42> 80 3c 2a 00 0f 85 e3 02 00 00 4c 89 f6 4c 89 e7 ff 50 08 83 44 RSP: 0018:ffffc90003adfa28 EFLAGS: 00010202 RAX: 0000000000000000 RBX: 0000000000008001 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffffffff81f4e014 RDI: 0000000000000008 RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 1ffffffff2186c9b R12: ffff88802819f000 R13: dffffc0000000000 R14: ffff888077c05028 R15: 0000000000008001 FS: 00007f82b229b700(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa5f3ff2304 CR3: 0000000075e14000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 ---------------- Code disassembly (best guess): 0: 10 48 89 adc %cl,-0x77(%rax) 3: f8 clc 4: 48 c1 e8 03 shr $0x3,%rax 8: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) d: 0f 85 19 03 00 00 jne 0x32c 13: 49 8b 46 10 mov 0x10(%r14),%rax 17: 49 c7 46 10 00 00 00 movq $0x0,0x10(%r14) 1e: 00 1f: 48 8d 78 08 lea 0x8(%rax),%rdi 23: 48 89 fa mov %rdi,%rdx 26: 48 c1 ea 03 shr $0x3,%rdx * 2a: 42 80 3c 2a 00 cmpb $0x0,(%rdx,%r13,1) <-- trapping instruction 2f: 0f 85 e3 02 00 00 jne 0x318 35: 4c 89 f6 mov %r14,%rsi 38: 4c 89 e7 mov %r12,%rdi 3b: ff 50 08 callq *0x8(%rax) 3e: 83 .byte 0x83 3f: 44 rex.R --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkaller@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. For information about bisection process see: https://goo.gl/tpsmEJ#bisection If the bug is already fixed, let syzbot know by replying with: #syz fix: exact-commit-title If you want syzbot to run the reproducer, reply with: #syz test: git://repo/address.git branch-or-commit-hash If you attach or paste a git patch, syzbot will apply it before testing. If you want to change bug's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the bug is a duplicate of another bug, reply with: #syz dup: exact-subject-of-another-report If you want to undo deduplication, reply with: #syz undup ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [syzbot] [fs?] general protection fault in splice_to_socket 2023-06-12 9:43 [syzbot] [fs?] general protection fault in splice_to_socket syzbot @ 2023-06-14 8:57 ` David Howells 2023-06-14 9:00 ` David Howells 1 sibling, 0 replies; 4+ messages in thread From: David Howells @ 2023-06-14 8:57 UTC (permalink / raw) To: syzbot Cc: dhowells, brauner, kuba, linux-fsdevel, linux-kernel, netdev, syzkaller-bugs, viro Here's a much reduced test program. The key is to splice more than a page from the pipe into the second socket (AF_ALG in this case) and more than that into the pipe. David --- // https://syzkaller.appspot.com/bug?id=613f5060400df25674e1b213295ef45a8422b077 // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include <endian.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/syscall.h> #include <sys/socket.h> #include <sys/mman.h> #include <sys/wait.h> #include <netinet/in.h> #include <linux/if_alg.h> #define OSERROR(R, S) do { if ((long)(R) == -1L) { perror((S)); exit(1); } } while(0) static const unsigned char data[1024 * 1024] = { "\x44\xf9\xb1\x08\xb1\xcd\xc8\x85\xc9\xc5\x33\xd2\x1f\x47\x4b\xec\x8b" "\xfe\xf1\xdf\x1e\x2d\xa7\x1e\x57\x8d\xc6\xb9\x1d\x09\xf7\xab\x15\x37" "\x85\x71\xd8\xe2\x75\x46\x09\x00\x00\x00\x6e\x75\x43\x69\x14\xab\x71" "\x75\x28\xee\x4b\x7a\x9b\xea\xf9\x08\xd1\x11\x37\xc1\x19\x03\x06\x4e" "\x83\xb4\x95\x1f\x4d\x43\x3a\x54\x04\x97\x0c\x85\xd9\x2d\x70\x83\xfd" "\x38\x84\x4c\xbb\x0c\x6c\x5e\xb5\x08\xdd\xc2\xdc\x7a\x59\x0a\xa7\x94" "\x1b\x1e\x9e\xeb\x5a\x68\x81\x38\xde\xa0\x9b\x77\x6c\xbf\xa7\x84\xcb" "\xf5\x50\xbf\x30\x74\xfb\x0d\x77\x5d\xa4\xdf\x5a\x3f\x48\xbb\xdf\x45" "\x2e\xeb\x6b\x92\x3d\xa9\xd0\xe2\x5b\x80\xf7\x6a\x87\x36\x64\xb5\x75" "\x34\x44\xfe\x05\xf3\x3e\x5f\x91\x04\x55\x40\x83\x6c\x3c\xd6\xaf\x10" "\xf0\xcd\x01\x8f\x0c\x6f\x57\xf9\x26\xac\x95\x9a\x56\x28\xc4\x50\x88" "\xfb\xe0\xc8\x7f\xbe\x6c\xbc\xda\x46\x62\xd2\xa1\x2f\x6d\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", }; int main(int argc, char *argv[]) { struct sockaddr_in6 sin6; struct sockaddr_alg salg; int pipefd[2], ipv6fd, algfd, hashfd, res, wt; res = pipe(pipefd); OSERROR(res, "pipe"); ipv6fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); OSERROR(ipv6fd, "socket/inet6"); memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(2); res = bind(ipv6fd, (struct sockaddr *)&sin6, sizeof(sin6)); OSERROR(res, "bind/inet6"); memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(2); sin6.sin6_addr.s6_addr[15] = 1; res = sendto(ipv6fd, NULL, 0, MSG_OOB|MSG_NOSIGNAL|MSG_FASTOPEN|0x2000000, (struct sockaddr *)&sin6, sizeof(sin6)); OSERROR(res, "sendto_1"); res = send(ipv6fd, data, 0xd0d0c2ac /* massive overrun */, MSG_OOB); OSERROR(res, "sendto_2"); algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); OSERROR(algfd, "socket/alg"); memset(&salg, 0, sizeof(salg)); salg.salg_family = AF_ALG; strcpy(salg.salg_type, "hash"); strcpy(salg.salg_name, "sha3-512"); res = bind(algfd, (struct sockaddr *)&salg, sizeof(salg)); OSERROR(res, "bind/alg"); hashfd = accept4(algfd, NULL, 0, 0); OSERROR(hashfd, "accept/alg"); switch (fork()) { case -1: OSERROR(-1, "fork"); case 0: res = splice(pipefd[0], 0, hashfd, 0, 65536, 0); OSERROR(res, "splice/p->h"); return 0; default: sleep(1); break; } res = splice(ipv6fd, 0, pipefd[1], 0, 32767, 0); OSERROR(res, "splice/i->p"); wait(&wt); return 0; } ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [syzbot] [fs?] general protection fault in splice_to_socket 2023-06-12 9:43 [syzbot] [fs?] general protection fault in splice_to_socket syzbot 2023-06-14 8:57 ` David Howells @ 2023-06-14 9:00 ` David Howells 2023-06-14 10:02 ` syzbot 1 sibling, 1 reply; 4+ messages in thread From: David Howells @ 2023-06-14 9:00 UTC (permalink / raw) To: syzbot Cc: dhowells, brauner, kuba, linux-fsdevel, linux-kernel, netdev, syzkaller-bugs, viro #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git main commit d302bc9baf84c549891bedee57ee917d9e0485d7 Author: David Howells <dhowells@redhat.com> Date: Wed Jun 14 09:14:50 2023 +0100 splice: Fix splice_to_socket() to handle pipe bufs larger than a page splice_to_socket() assumes that a pipe_buffer won't hold more than a single page of data - but it seems that this assumption can be violated when splicing from a socket into a pipe. The problem is that splice_to_socket() doesn't advance the pipe_buffer length and offset when transcribing from the pipe buf into a bio_vec, so if the buf is >PAGE_SIZE, it keeps repeating the same initial chunk and doesn't advance the tail index. It then subtracts this from "remain" and overcounts the amount of data to be sent. The cleanup phase then tries to overclean the pipe, hits an unused pipe buf and a NULL-pointer dereference occurs. Fix this by not restricting the bio_vec size to PAGE_SIZE and instead transcribing the entirety of each pipe_buffer into a single bio_vec and advancing the tail index if remain hasn't hit zero yet. Large bio_vecs will then be split up iterator functions such as iov_iter_extract_pages(). This resulted in a KASAN report looking like: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] ... RIP: 0010:pipe_buf_release include/linux/pipe_fs_i.h:203 [inline] RIP: 0010:splice_to_socket+0xa91/0xe30 fs/splice.c:933 Reported-by: syzbot+f9e28a23426ac3b24f20@syzkaller.appspotmail.com Fixes: 2dc334f1a63a ("splice, net: Use sendmsg(MSG_SPLICE_PAGES) rather than ->sendpage()") Signed-off-by: David Howells <dhowells@redhat.com> cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com> cc: David Ahern <dsahern@kernel.org> cc: "David S. Miller" <davem@davemloft.net> cc: Eric Dumazet <edumazet@google.com> cc: Jakub Kicinski <kuba@kernel.org> cc: Paolo Abeni <pabeni@redhat.com> cc: Jens Axboe <axboe@kernel.dk> cc: Matthew Wilcox <willy@infradead.org> cc: Christian Brauner <brauner@kernel.org> cc: Alexander Viro <viro@zeniv.linux.org.uk> cc: netdev@vger.kernel.org cc: linux-fsdevel@vger.kernel.org diff --git a/fs/splice.c b/fs/splice.c index e337630aed64..567a1f03ea1e 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -886,7 +886,6 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, } seg = min_t(size_t, remain, buf->len); - seg = min_t(size_t, seg, PAGE_SIZE); ret = pipe_buf_confirm(pipe, buf); if (unlikely(ret)) { @@ -897,10 +896,9 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, bvec_set_page(&bvec[bc++], buf->page, seg, buf->offset); remain -= seg; - if (seg >= buf->len) - tail++; - if (bc >= ARRAY_SIZE(bvec)) + if (remain == 0 || bc >= ARRAY_SIZE(bvec)) break; + tail++; } if (!bc) ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [syzbot] [fs?] general protection fault in splice_to_socket 2023-06-14 9:00 ` David Howells @ 2023-06-14 10:02 ` syzbot 0 siblings, 0 replies; 4+ messages in thread From: syzbot @ 2023-06-14 10:02 UTC (permalink / raw) To: brauner, dhowells, kuba, linux-fsdevel, linux-kernel, netdev, syzkaller-bugs, viro Hello, syzbot has tested the proposed patch and the reproducer did not trigger any issue: Reported-and-tested-by: syzbot+f9e28a23426ac3b24f20@syzkaller.appspotmail.com Tested on: commit: 2bddad9e ethtool: ioctl: account for sopass diff in se.. git tree: git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git main console output: https://syzkaller.appspot.com/x/log.txt?x=12d9c93b280000 kernel config: https://syzkaller.appspot.com/x/.config?x=526f919910d4a671 dashboard link: https://syzkaller.appspot.com/bug?extid=f9e28a23426ac3b24f20 compiler: gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2 patch: https://syzkaller.appspot.com/x/patch.diff?x=12c4f0d9280000 Note: testing is done by a robot and is best-effort only. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-06-14 10:02 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-06-12 9:43 [syzbot] [fs?] general protection fault in splice_to_socket syzbot 2023-06-14 8:57 ` David Howells 2023-06-14 9:00 ` David Howells 2023-06-14 10:02 ` syzbot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).