* UNIX sockets kernel panic @ 2008-11-06 0:14 Andrea Bittau 2008-11-06 1:13 ` Alexey Dobriyan 0 siblings, 1 reply; 5+ messages in thread From: Andrea Bittau @ 2008-11-06 0:14 UTC (permalink / raw) To: netdev; +Cc: a.bittau The following code causes a kernel panic on Linux 2.6.26: http://darkircop.org/unix.c I haven't investigated the bug so I'm not sure what is causing it, and don't know if it's exploitable. The code passes unix sockets from one process to another using unix sockets. The bug probably has to do with closing file descriptors. [I'm not subscribed to the list so please CC me if you answer.] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: UNIX sockets kernel panic 2008-11-06 0:14 UNIX sockets kernel panic Andrea Bittau @ 2008-11-06 1:13 ` Alexey Dobriyan 2008-11-06 1:18 ` David Miller 0 siblings, 1 reply; 5+ messages in thread From: Alexey Dobriyan @ 2008-11-06 1:13 UTC (permalink / raw) To: netdev; +Cc: a.bittau On Thu, Nov 06, 2008 at 12:14:46AM +0000, Andrea Bittau wrote: > The following code causes a kernel panic on Linux 2.6.26: > http://darkircop.org/unix.c > > I haven't investigated the bug so I'm not sure what is causing it, and > don't know if it's exploitable. The code passes unix sockets from one > process to another using unix sockets. The bug probably has to do with > closing file descriptors. Aie, nice localhost DoS (random oopses) BUG: unable to handle kernel paging request at ffff880827feb448 IP: [<ffffffff8022191a>] cfs_rq_of+0x19/0x27 PGD 202063 PUD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/kernel/uevent_seqnum CPU 0 Pid: 20940, comm: unix Not tainted 2.6.28-rc3 #2 RIP: 0010:[<ffffffff8022191a>] [<ffffffff8022191a>] cfs_rq_of+0x19/0x27 RSP: 0018:ffff88017dbd3d08 EFLAGS: 00010046 RAX: ffffffff80505940 RBX: ffff88017f94ad90 RCX: 00000000ffff8801 RDX: ffff880028027440 RSI: ffff88002802f9d8 RDI: ffff88017f94adc8 RBP: ffff88017dbd3d08 R08: ffff88002802f9d8 R09: ffff88002802f9b0 R10: 0000000000000000 R11: 0000000000000001 R12: ffff88002802f940 R13: 0000000000000001 R14: ffff88017dbd3d88 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffffffff804b2540(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: ffff880827feb448 CR3: 0000000000201000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process unix (pid: 20940, threadinfo ffff88017dbd2000, task ffff88017f94ad90) Stack: ffff88017dbd3d28 ffffffff80224b4b ffff88017f87d5d0 ffff88002802f940 ffff88017dbd3d48 ffffffff80221ada 0000000000000000 ffff88002802f940 ffff88017dbd3d68 ffffffff80221b69 ffff88017dbd3d88 ffff88017f87d5d0 Call Trace: [<ffffffff80224b4b>] hrtick_update+0x24/0x3f [<ffffffff80221ada>] enqueue_task+0x13/0x1e [<ffffffff80221b69>] activate_task+0x22/0x2a [<ffffffff80224f4b>] try_to_wake_up+0xf9/0x162 [<ffffffff80233816>] signal_wake_up+0x2b/0x3e [<ffffffff80233ada>] ? send_signal+0x166/0x182 [<ffffffff80235392>] ? do_notify_parent+0x16c/0x19b [<ffffffff8027baa2>] ? mntput_no_expire+0x20/0x103 [<ffffffff80222719>] ? need_resched+0x1e/0x28 [<ffffffff8027baa2>] ? mntput_no_expire+0x20/0x103 [<ffffffff8022d5af>] ? do_exit+0x491/0x6cb [<ffffffff8022d878>] ? sys_exit_group+0x0/0xe [<ffffffff8020b305>] ? tracesys+0xd0/0xd5 Code: 0d 0e 29 00 48 8b 14 ca 48 03 42 08 c9 48 83 c0 70 c3 48 8b 57 d0 55 48 c7 c0 40 59 50 80 48 89 e5 8b 4a 1c 48 8b 15 e6 0d 29 00 <48> 8b 14 ca 48 03 42 08 c9 48 83 c0 70 c3 48 8b 47 50 48 8b 4f RIP [<ffffffff8022191a>] cfs_rq_of+0x19/0x27 RSP <ffff88017dbd3d08> CR2: ffff880827feb448 Kernel panic - not syncing: Fatal exception in interrupt ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: UNIX sockets kernel panic 2008-11-06 1:13 ` Alexey Dobriyan @ 2008-11-06 1:18 ` David Miller 2008-11-06 12:26 ` David Miller 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2008-11-06 1:18 UTC (permalink / raw) To: adobriyan; +Cc: netdev, a.bittau From: Alexey Dobriyan <adobriyan@gmail.com> Date: Thu, 6 Nov 2008 04:13:19 +0300 > On Thu, Nov 06, 2008 at 12:14:46AM +0000, Andrea Bittau wrote: > > The following code causes a kernel panic on Linux 2.6.26: > > http://darkircop.org/unix.c > > > > I haven't investigated the bug so I'm not sure what is causing it, and > > don't know if it's exploitable. The code passes unix sockets from one > > process to another using unix sockets. The bug probably has to do with > > closing file descriptors. > > Aie, nice localhost DoS (random oopses) Indeed. I'm looking at it too and in my case I get random memory corruption, usually it's skb->destruct being set to garbage and then we hit the WARN_ON(in_irq()) in net/core/skbuff.c I think the key is passing a unix socket fd (as opposed to some other kind of fd) using SCM_RIGHTS and the ordering of the fd closes. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: UNIX sockets kernel panic 2008-11-06 1:18 ` David Miller @ 2008-11-06 12:26 ` David Miller 2008-11-06 15:14 ` Andrea Bittau 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2008-11-06 12:26 UTC (permalink / raw) To: adobriyan; +Cc: netdev, a.bittau From: David Miller <davem@davemloft.net> Date: Wed, 05 Nov 2008 17:18:22 -0800 (PST) > From: Alexey Dobriyan <adobriyan@gmail.com> > Date: Thu, 6 Nov 2008 04:13:19 +0300 > > > On Thu, Nov 06, 2008 at 12:14:46AM +0000, Andrea Bittau wrote: > > > The following code causes a kernel panic on Linux 2.6.26: > > > http://darkircop.org/unix.c > > > > > > I haven't investigated the bug so I'm not sure what is causing it, and > > > don't know if it's exploitable. The code passes unix sockets from one > > > process to another using unix sockets. The bug probably has to do with > > > closing file descriptors. > > > > Aie, nice localhost DoS (random oopses) > > Indeed. I'm looking at it too and in my case I get random memory > corruption, usually it's skb->destruct being set to garbage and then > we hit the WARN_ON(in_irq()) in net/core/skbuff.c > > I think the key is passing a unix socket fd (as opposed to some other > kind of fd) using SCM_RIGHTS and the ordering of the fd closes. Andrea, can you try this patch? net: Fix recursive descent in __scm_destroy(). __scm_destroy() walks the list of file descriptors in the scm_fp_list pointed to by the scm_cookie argument. Those, in turn, can close sockets and invoke __scm_destroy() again. There is nothing which limits how deeply this can occur. The idea for how to fix this is from Linus. Basically, we do all of the fput()s at the top level by collecting all of the scm_fp_list objects hit by an fput(). Inside of the initial __scm_destroy() we keep running the list until it is empty. Signed-off-by: David S. Miller <davem@davemloft.net> diff --git a/include/linux/sched.h b/include/linux/sched.h index b483f39..295b7c7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1349,6 +1349,8 @@ struct task_struct { */ unsigned long timer_slack_ns; unsigned long default_timer_slack_ns; + + struct list_head *scm_work_list; }; /* diff --git a/include/net/scm.h b/include/net/scm.h index 06df126..33e9986 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -14,8 +14,9 @@ struct scm_fp_list { - int count; - struct file *fp[SCM_MAX_FD]; + struct list_head list; + int count; + struct file *fp[SCM_MAX_FD]; }; struct scm_cookie diff --git a/net/core/scm.c b/net/core/scm.c index 10f5c65..ab242cc 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) if (!fpl) return -ENOMEM; *fplp = fpl; + INIT_LIST_HEAD(&fpl->list); fpl->count = 0; } fpp = &fpl->fp[fpl->count]; @@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm) if (fpl) { scm->fp = NULL; - for (i=fpl->count-1; i>=0; i--) - fput(fpl->fp[i]); - kfree(fpl); + if (current->scm_work_list) { + list_add_tail(&fpl->list, current->scm_work_list); + } else { + LIST_HEAD(work_list); + + current->scm_work_list = &work_list; + + list_add(&fpl->list, &work_list); + while (!list_empty(&work_list)) { + fpl = list_first_entry(&work_list, struct scm_fp_list, list); + + list_del(&fpl->list); + for (i=fpl->count-1; i>=0; i--) + fput(fpl->fp[i]); + kfree(fpl); + } + + current->scm_work_list = NULL; + } } } @@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); if (new_fpl) { + INIT_LIST_HEAD(&new_fpl->list); for (i=fpl->count-1; i>=0; i--) get_file(fpl->fp[i]); memcpy(new_fpl, fpl, sizeof(*fpl)); ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: UNIX sockets kernel panic 2008-11-06 12:26 ` David Miller @ 2008-11-06 15:14 ` Andrea Bittau 0 siblings, 0 replies; 5+ messages in thread From: Andrea Bittau @ 2008-11-06 15:14 UTC (permalink / raw) To: David Miller; +Cc: adobriyan, netdev I'm still seeing problems with your patch. I'm getting mixed results. With SMP off, everything seems to work. With SMP, on my laptop, it still barfs (.26 and .27). Here's a screenshot (literally) of .26: http://darkircop.org/unix.jpg I can't seem to reproduce it on qemu using -smp. However, on qemu, with kernel 2.6.19, your patch, and -smp 2, I can get this one to hang: http://darkircop.org/unix2.c On my laptop, with 2.6.19 and SMP on, I think that everything works. It's likely that it's a scheduling / configuration problem, so I don't think there's anything magic in .19. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-11-06 15:13 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-11-06 0:14 UNIX sockets kernel panic Andrea Bittau 2008-11-06 1:13 ` Alexey Dobriyan 2008-11-06 1:18 ` David Miller 2008-11-06 12:26 ` David Miller 2008-11-06 15:14 ` Andrea Bittau
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).