[Unionfs] NULL pointer dereference if copyup_dentry() failed?
Tetsuo Handa
penguin-kernel at i-love.sakura.ne.jp
Sun Sep 21 22:06:19 EDT 2008
Hello.
> Could you add this small patch below and let me know if the BUG_ON triggers?
> Given your stack trace, I'm suspecting that somehow the lower dentry isn't
> instantiated w/ an inode perhaps.
Yes, it triggered.
> OK thanks for the report. Tetsuo, are the instructions you gave me before
> for reproducing this w/ TOMOYO the same, or have the instructions changed?
> If they've changed, can you give me an updated set of instrux?
Below is the updated procedure for how to reproduce this problem.
I tested using CentOS 5.2 (gcc 4.1.2).
(1) Get and extract kernel source.
# wget http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.27-rc7.tar.bz2
# tar -jxf linux-2.6.27-rc7.tar.bz2
# cd linux-2.6.27-rc7
(2) Get and extract and apply unionfs patch.
# wget http://download.filesystems.org/unionfs/unionfs-2.x/unionfs-2.5_for_2.6.27-rc6.diff.gz
# zcat unionfs-2.5_for_2.6.27-rc6.diff.gz | patch -p1
(3) Get and extract and apply TOMOYO Linux patch.
# wget http://osdn.dl.sourceforge.jp/tomoyo/30297/ccs-patch-1.6.4-20080903.tar.gz
# tar -zxf ccs-patch-1.6.4-20080903.tar.gz
# patch -p1 < patches/ccs-patch-2.6.27.diff
(4) Apply BUG_ON() patch.
index 800648e..76f20de 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -964,6 +964,7 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
/* notify the (possibly copied-up) lower inode */
mutex_lock(&lower_inode->i_mutex);
+ BUG_ON(!lower_dentry->d_inode);
err = notify_change(lower_dentry, ia);
mutex_unlock(&lower_inode->i_mutex);
if (err)
Apply some printk() patch for unionfs. This is optional.
---
fs/unionfs/commonfops.c | 5 +++++
fs/unionfs/copyup.c | 5 +++++
fs/unionfs/inode.c | 4 ++++
3 files changed, 14 insertions(+)
--- linux-2.6.27-rc7.orig/fs/unionfs/commonfops.c
+++ linux-2.6.27-rc7/fs/unionfs/commonfops.c
@@ -548,6 +548,8 @@ int unionfs_open(struct inode *inode, st
int size;
int valid = 0;
+ printk(KERN_WARNING "Entering %s()\n", __func__);
+
unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT);
parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
@@ -630,6 +632,9 @@ out_nofree:
unionfs_unlock_dentry(dentry);
unionfs_unlock_parent(dentry, parent);
unionfs_read_unlock(inode->i_sb);
+
+ printk(KERN_WARNING "Leaving %s() with %d\n", __func__, err);
+
return err;
}
--- linux-2.6.27-rc7.orig/fs/unionfs/copyup.c
+++ linux-2.6.27-rc7/fs/unionfs/copyup.c
@@ -387,6 +387,8 @@ int copyup_dentry(struct inode *dir, str
mm_segment_t oldfs;
char *symbuf = NULL;
+ printk(KERN_WARNING "Entering %s()\n", __func__);
+
verify_locked(dentry);
old_bindex = bstart;
@@ -540,6 +542,9 @@ out_free:
unionfs_check_inode(dir);
unionfs_check_dentry(dentry);
out:
+
+ printk(KERN_WARNING "Leaving %s() with %d\n", __func__, err);
+
return err;
}
--- linux-2.6.27-rc7.orig/fs/unionfs/inode.c
+++ linux-2.6.27-rc7/fs/unionfs/inode.c
@@ -882,6 +882,8 @@ static int unionfs_setattr(struct dentry
int bstart, bend, bindex;
loff_t size;
+ printk(KERN_WARNING "Entering %s()\n", __func__);
+
unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
@@ -993,6 +995,8 @@ out:
unionfs_unlock_parent(dentry, parent);
unionfs_read_unlock(dentry->d_sb);
+ printk(KERN_WARNING "Leaving %s() with %d\n", __func__, err);
+
return err;
}
(5) Compile the kernel with CONFIG_UNION_FS=m and CONFIG_UNION_FS_DEBUG=y and
CONFIG_TOMOYO=y . The config I used is available at http://I-love.SAKURA.ne.jp/tmp/config-2.6.27-rc7-unionfs-ccs .
(6) Get and extract and compile and install TOMOYO Linux tools.
# cd /tmp/
# wget http://osdn.dl.sourceforge.jp/tomoyo/30298/ccs-tools-1.6.4-20080903.tar.gz
# tar -zxf ccs-tools-1.6.4-20080903.tar.gz
# make -C ccstools install
(7) Initialize policy configuration.
# /usr/lib/ccs/init_policy.sh
# echo "4-MAC_FOR_CAPABILITY::SYS_CHMOD=enforcing" >> /etc/ccs/profile.conf
(8) Reboot the system with the compiled kernel.
(9) Run the following commands to set up environment.
My environment has only / partition (ext3 filesystem).
# rm -fR /tmp/1 /tmp/2
# mkdir /tmp/1 /tmp/2
# touch /tmp/2/foo
# mount -t unionfs -o dirs=/tmp/1=rw:/tmp/2=ro none /mnt/
(10) Configure /bin/touch executed from current shell to allow everything
except for changing mode (i.e. calling notify_change() with ATTR_MODE).
# ( echo `cat < /proc/ccs/self_domain` /bin/touch ; echo use_profile 4) | /usr/sbin/ccs-loadpolicy -d
(11) Create /mnt/foo using /bin/touch . Unionfs will try to create copy of
/tmp/2/foo as /tmp/1/foo , but notify_change() for changing mode is
rejected by TOMOYO Linux. So, you will see TOMOYO-ERROR: message in dmesg.
# touch /mnt/foo
You will get BUG() message at this point. The dmesg is shown below.
------------------------------------------------------------
Entering unionfs_open()
Leaving unionfs_open() with 0
Entering unionfs_setattr()
Entering copyup_dentry()
TOMOYO-ERROR: sys_chmod() denied for /bin/touch
Leaving copyup_dentry() with -1
Leaving unionfs_setattr() with -1
Entering unionfs_setattr()
------------[ cut here ]------------
kernel BUG at fs/unionfs/inode.c:969!
invalid opcode: 0000 [#1] SMP
Modules linked in: unionfs autofs4 sunrpc binfmt_misc nvram pcnet32 mptspi mptscsih scsi_transport_spi mptbase uhci_hcd ohci_hcd ehci_hcd
Pid: 3509, comm: touch Not tainted (2.6.27-rc7 #2)
EIP: 0060:[<f88b2b31>] EFLAGS: 00010246 CPU: 1
EIP is at unionfs_setattr+0x2bc/0x3e7 [unionfs]
EAX: f450f078 EBX: f450e2bc ECX: 00000000 EDX: f78af474
ESI: f6b57f20 EDI: f44fc07c EBP: f450e22c ESP: f6b57ec0
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process touch (pid: 3509, ti=f6b57000 task=f78aef40 task.ti=f6b57000)
Stack: f6b57f20 f44fa2a0 f450f078 f44d61e8 00000000 c013ac2a f7b96a30 f44fc038
f6b57f20 00000070 00000000 f44fc07c c0177fb8 f44fa2a0 00000000 222281a4
22222222 22222222 22222222 f44fc10c fffffff3 f44fc07c f6b57f68 c0181e14
Call Trace:
[<c013ac2a>] trace_hardirqs_on_caller+0xe7/0x10e
[<c0177fb8>] notify_change+0x2e4/0x31c
[<c0181e14>] utimes_common+0xfc/0x134
[<c0181eee>] do_utimes+0xa2/0xba
[<c0181f77>] sys_futimesat+0x71/0x81
[<c01f5d04>] trace_hardirqs_on_thunk+0xc/0x10
[<c0113a26>] do_page_fault+0x0/0x552
[<c013ac2a>] trace_hardirqs_on_caller+0xe7/0x10e
[<c0181f96>] sys_utimes+0xf/0x13
[<c0103829>] sysenter_do_call+0x12/0x35
=======================
Code: f8 89 d9 e8 09 4f 8a c7 85 c0 89 c6 0f 85 aa 00 00 00 8d 9d 90 00 00 00 31 d2 89 d8 e8 f3 0d a7 c7 8b 44 24 08 83 78 28 00 75 04 <0f> 0b eb fe 8b 14 24 8b 44 24 08 e8 93 51 8c c7 89 c6 89 d8 e8
EIP: [<f88b2b31>] unionfs_setattr+0x2bc/0x3e7 [unionfs] SS:ESP 0068:f6b57ec0
---[ end trace 611002353eec27ad ]---
------------------------------------------------------------
If you use Debian Sarge (gcc 3.3.5), you will get the below message by
running
# touch /mnt/foo
once again.
------------------------------------------------------------
Entering unionfs_open()
Leaving unionfs_open() with 0
Entering unionfs_setattr()
Entering copyup_dentry()
TOMOYO-ERROR: sys_chmod() denied for /bin/touch
Leaving copyup_dentry() with -1
Leaving unionfs_setattr() with -1
Entering unionfs_open()
BUG: unable to handle kernel NULL pointer dereference at 00000084
IP: [<c013eb9d>] __lock_acquire+0x98/0x75f
*pde = 00000000
Oops: 0000 [#1] SMP
Modules linked in: unionfs nfsd lockd sunrpc exportfs pcnet32 uhci_hcd ohci_hcd ehci_hcd
Pid: 2078, comm: touch Not tainted (2.6.27-rc7-unionfs #1)
EIP: 0060:[<c013eb9d>] EFLAGS: 00010046 CPU: 1
EIP is at __lock_acquire+0x98/0x75f
EAX: 00000001 EBX: 00000246 ECX: 00000080 EDX: 00000002
ESI: 00000000 EDI: 00000000 EBP: 00000080 ESP: f7ca4dc0
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process touch (pid: 2078, ti=f7ca4000 task=f7b60f40 task.ti=f7ca4000)
Stack: f7b60f40 00000000 0001bb0d 00001b0d f7b6144c c013f20b 00000000 f7b60f40
00000002 00000000 00000000 00000080 00000246 00000000 00000000 00000080
c013fd64 00000000 00000002 00000000 00000000 c0172979 00000070 00000080
Call Trace:
[<c013f20b>] __lock_acquire+0x706/0x75f
[<c013fd64>] lock_acquire+0x5a/0x74
[<c0172979>] get_write_access+0xe/0x38
[<c0337531>] _spin_lock+0x1c/0x45
[<c0172979>] get_write_access+0xe/0x38
[<c0172979>] get_write_access+0xe/0x38
[<c016bdf3>] __dentry_open+0x36/0x1e8
[<c016c087>] dentry_open+0x5d/0x63
[<f88957c7>] __open_file+0x173/0x1fc [unionfs]
[<f8895a3d>] unionfs_open+0x1ed/0x358 [unionfs]
[<f8895850>] unionfs_open+0x0/0x358 [unionfs]
[<c016bec2>] __dentry_open+0x105/0x1e8
[<c016c01a>] nameidata_to_filp+0x1c/0x2c
[<c0174565>] do_filp_open+0x2ad/0x580
[<c013b854>] lock_release_holdtime+0x77/0x84
[<c017ecba>] alloc_fd+0xa8/0xb1
[<c0337690>] _spin_unlock+0x14/0x1c
[<c016c14b>] do_sys_open+0x40/0xb9
[<c016c1e2>] sys_open+0x1e/0x23
[<c0103862>] syscall_call+0x7/0xb
=======================
Code: ba e9 09 00 00 e9 3c 04 00 00 83 7c 24 28 07 76 0f e8 08 1e 0c 00 68 80 5b 3e c0 e9 9f 06 00 00 83 7c 24 28 00 75 0f 8b 4c 24 2c <8b> 59 04 85 db 0f 85 92 03 00 00 83 3d 88 58 67 c0 00 75 19 e8
EIP: [<c013eb9d>] __lock_acquire+0x98/0x75f SS:ESP 0068:f7ca4dc0
---[ end trace e8ff1f7a46bd1f83 ]---
------------------------------------------------------------
Regards.
More information about the unionfs
mailing list