unionmount: Null pointer dereference when creating file in new directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,

I've been using your unionmount patches from

http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?id=refs/heads/unionmount

and ran into an apparent bug when creating a new file in an empty
directory. The quickest way to reproduce it:

# mkdir /tmp/mnt
# mount -t tmpfs -o ro tmpfs /tmp/mnt
# mount -t tmpfs -o union tmpfs /tmp/mnt
# mkdir -p /tmp/mnt/bobo/foo/bar
# touch /tmp/mnt/bobo/foo/bar/ugh

The last command causes a null pointer dereference in __lookup_union()
in fs/namei.c, because union_find_dir(parent.dentry, i) is returning
null.

Changing the next line to

  if (!lower_parent || !lower_parent->mnt)
    continue;

seems to improve things, but I don't know whether this is merely
papering over a symptom of the actual problem.

In case it helps, here is a backtrace from gdb when the bug hits. Note
that the line numbers are slightly off because I had to add in a
couple of lines to set a breakpoint.

(gdb) bt full
#0  __lookup_union (nd=0xffff88001c3ffe58, name=0xffff88001f0b9aa0,
topmost=0xffff88001c3ffd58) at linux/fs/namei.c:1311
        lower_parent = 0x0
        lower = {mnt = 0xffff88001c3ffc98, dentry = 0xffffffff800f0df9}
        parent = {mnt = 0xffff88001c3e0320, dentry = 0xffff88001f0b99c0}
        i = <optimized out>
        layers = <optimized out>
        err = <optimized out>
#1  0xffffffff800dacdf in lookup_open (opened=0xffff88001c3ffe14,
got_write=true, op=0xffff88001c3fff28, file=0xffff88001f542800,
    path=0xffff88001c3ffde8, nd=0xffff88001c3ffe58) at linux/fs/namei.c:3349
        topmost = {mnt = 0xffff88001c3e0320, dentry = 0xffff88001f0b9a80}
        mode = 33188
        dir = <optimized out>
        dir_inode = 0xffff88001c3f8968
        dentry = <optimized out>
        need_lookup = true
        error = <optimized out>
#2  do_last (nd=0xffff88001c3ffe58, path=0xffff88001c3ffde8,
file=0xffff88001f542800, op=0xffff88001c3fff28,
opened=0xffff88001c3ffe14,
    name=<optimized out>) at linux/fs/namei.c:3489
        dir = 0xffff88001f0b99c0
        open_flag = 32834
        will_truncate = false
        got_write = true
        acc_mode = 38
        inode = 0xffff88001c264400
        symlink_ok = false
        save_parent = {mnt = 0x0, dentry = 0x0}
        retried = false
        error = <optimized out>
#3  0xffffffff800db2b7 in path_openat (dfd=<optimized out>,
nd=0xffff88001c3ffe58, op=0xffff88001c3fff28, flags=32833,
pathname=<optimized out>)
    at linux/fs/namei.c:3733
        base = 0x0
        file = 0xffff88001f542800
        terminal_symlink = {mnt = 0xffff88001fa10dc0, dentry =
0xffff88001f443378}
        opened = 0
        error = <optimized out>
#4  0xffffffff800dba2d in do_filp_open (dfd=-100,
pathname=0xffff88001c3bd000, op=0xffff88001c3fff28, flags=1)
    at linux/fs/namei.c:3781
        nd = {path = {mnt = 0xffff88001c3e0320, dentry =
0xffff88001f0b99c0}, last = {{{hash = 6842229, len = 3}, hash_len =
12891744117},
            name = 0xffff88001c3bd036 "ugh"}, root = {mnt = 0x0,
dentry = 0xffff88001f0030c0}, inode = 0xffff88001c3f8968, flags =
33537, seq = 4,
          last_type = 0, depth = 0, saved_names = {0x8042 <Address
0x8042 out of bounds>, 0xffff88001c3ffef8 "\234\377\377\377",
            0xffffffff800e7c05 "\203", <incomplete sequence \370>,
0xffff880000000003 "\360S\377", 0x3800d6e1d <Address 0x3800d6e1d out
of bounds>,
            0xffff88001c3fff38 "H\377?\034", 0x8042 <Address 0x8042
out of bounds>, 0xffff88001c3bd000 " \320;\034",
            0xffffff9c <Address 0xffffff9c out of bounds>}}
        filp = <optimized out>
#5  0xffffffff800cb409 in do_sys_open (dfd=-100, filename=<optimized
out>, flags=<optimized out>, mode=<optimized out>)
    at linux/fs/open.c:1017
        f = <optimized out>
        op = {open_flag = 32834, mode = 33206, acc_mode = 38, intent = 768}
        lookup = 1
        tmp = 0xffff88001c3bd000
        fd = 3
#6  0xffffffff80115786 in compat_sys_open (filename=<optimized out>,
flags=<optimized out>, mode=<optimized out>)
    at linux/fs/compat.c:1293
No locals.
#7  <signal handler called>
No locals.
#8  0x00000000f76c7efe in ?? ()
No symbol table info available.
(gdb) p *pathname
$3 = {name = 0xffff88001c3bd020 "/tmp/mnt/bobo/foo/bar/ugh", uptr =
0xffe5df70 "/tmp/mnt/bobo/foo/bar/ugh", aname = 0x640a302030207772,
  separate = false}

Any help would be appreciated!

--Ed
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux