kern/151758: [panic] tmux kernel panic,
with out root privilegies
John Baldwin
jhb at FreeBSD.org
Thu Dec 8 16:10:11 UTC 2011
The following reply was made to PR kern/151758; it has been noted by GNATS.
From: John Baldwin <jhb at FreeBSD.org>
To: Kostik Belousov <kostikbel at gmail.com>
Cc: bug-followup at freebsd.org, andrey at shidakov.ru
Subject: Re: kern/151758: [panic] tmux kernel panic, with out root privilegies
Date: Thu, 08 Dec 2011 11:02:15 -0500
On 12/8/11 10:32 AM, Kostik Belousov wrote:
> On Thu, Dec 08, 2011 at 10:24:56AM -0500, John Baldwin wrote:
>> The bug is that during unp_gc(), we pass NULL as the thread to closef()
>> (to disable certain locking stuff, and because the thread performing the
>> gc doesn't "own" orphaned file descriptors in a closed UNIX domain
>> socket). That resulted in the 'td' argument passed to devfs_close_f()
>> being NULL, so td->td_fpop would fault. The patch I have (untested) is
>> to force devfs_close_f() to always use curthread instead of trusting the
>> td argument it is given.
>>
>> Index: /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c
>> ===================================================================
>> --- /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c (revision
>> 228311)
>> +++ /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c (working
>> copy)
>> @@ -602,6 +602,11 @@
>> int error;
>> struct file *fpop;
>>
>> + /*
>> + * NB: td may be NULL if this descriptor is closed due to
>> + * garbage collection from a closed UNIX domain socket.
>> + */
>> + td = curthread;
>> fpop = td->td_fpop;
>> td->td_fpop = fp;
>> error = vnops.fo_close(fp, td);
>>
> I think you need to use either curthread for td_fpop, or create another
> local variable td1 and use it for td_fpop stuff. So that the original
> td is passed to fo_close().
Ah, doh. I thought I had looked to see if td was used elsewhere. I
will update.
> I am curious whether it would cause further NULL pointer dereference
> down the stack.
Well, I checked all the other fo_close() methods. All the other ones
for PASSABLE fd's are safe. For vnodes the td is passed to vn_close()
which only uses it to pass it to VOP_CLOSE(). So, we'd have to audit
all the filesystems to see if that is safe.
Updated patch:
Index: /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c
===================================================================
--- /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c (revision
228311)
+++ /home/jhb/work/freebsd/svn/head/sys/fs/devfs/devfs_vnops.c (working
copy)
@@ -602,10 +602,14 @@
int error;
struct file *fpop;
- fpop = td->td_fpop;
- td->td_fpop = fp;
+ /*
+ * NB: td may be NULL if this descriptor is closed due to
+ * garbage collection from a closed UNIX domain socket.
+ */
+ fpop = curthread->td_fpop;
+ curthread->td_fpop = fp;
error = vnops.fo_close(fp, td);
- td->td_fpop = fpop;
+ curthread->td_fpop = fpop;
/*
* The f_cdevpriv cannot be assigned non-NULL value while we
--
John Baldwin
More information about the freebsd-bugs
mailing list