10 Nov, 2015

4 commits

  • commit ab79efab0a0ba01a74df782eb7fa44b044dae8b5 upstream.

    In ovl_copy_up_locked(), newdentry is leaked if the function exits through
    out_cleanup as this just to out after calling ovl_cleanup() - which doesn't
    actually release the ref on newdentry.

    The out_cleanup segment should instead exit through out2 as certainly
    newdentry leaks - and possibly upper does also, though this isn't caught
    given the catch of newdentry.

    Without this fix, something like the following is seen:

    BUG: Dentry ffff880023e9eb20{i=f861,n=#ffff880023e82d90} still in use (1) [unmount of tmpfs tmpfs]
    BUG: Dentry ffff880023ece640{i=0,n=bigfile} still in use (1) [unmount of tmpfs tmpfs]

    when unmounting the upper layer after an error occurred in copyup.

    An error can be induced by creating a big file in a lower layer with
    something like:

    dd if=/dev/zero of=/lower/a/bigfile bs=65536 count=1 seek=$((0xf000))

    to create a large file (4.1G). Overlay an upper layer that is too small
    (on tmpfs might do) and then induce a copy up by opening it writably.

    Reported-by: Ulrich Obergfell
    Signed-off-by: David Howells
    Signed-off-by: Miklos Szeredi
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     
  • commit 0480334fa60488d12ae101a02d7d9e1a3d03d7dd upstream.

    Open the lower file with O_LARGEFILE in ovl_copy_up().

    Pass O_LARGEFILE unconditionally in ovl_copy_up_data() as it's purely for
    catching 32-bit userspace dealing with a file large enough that it'll be
    mishandled if the application isn't aware that there might be an integer
    overflow. Inside the kernel, there shouldn't be any problems.

    Reported-by: Ulrich Obergfell
    Signed-off-by: David Howells
    Signed-off-by: Miklos Szeredi
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     
  • commit 5ffdbe8bf1e485026e1c7e4714d2841553cf0b40 upstream.

    This fixes memory leak after umount.

    Kmemleak report:

    unreferenced object 0xffff8800ba791010 (size 8):
    comm "mount", pid 2394, jiffies 4294996294 (age 53.920s)
    hex dump (first 8 bytes):
    20 1c 13 02 00 88 ff ff .......
    backtrace:
    [] create_object+0x124/0x2c0
    [] kmemleak_alloc+0x7b/0xc0
    [] __kmalloc+0x106/0x340
    [] ovl_fill_super+0x55c/0x9b0 [overlay]
    [] mount_nodev+0x54/0xa0
    [] ovl_mount+0x18/0x20 [overlay]
    [] mount_fs+0x43/0x170
    [] vfs_kern_mount+0x74/0x170
    [] do_mount+0x22d/0xdf0
    [] SyS_mount+0x7b/0xc0
    [] entry_SYSCALL_64_fastpath+0x12/0x76
    [] 0xffffffffffffffff

    Signed-off-by: Konstantin Khlebnikov
    Signed-off-by: Miklos Szeredi
    Fixes: dd662667e6d3 ("ovl: add mutli-layer infrastructure")
    Signed-off-by: Greg Kroah-Hartman

    Konstantin Khlebnikov
     
  • commit 0f95502ad84874b3c05fc7cdd9d4d9d5cddf7859 upstream.

    This fixes small memory leak after mount.

    Kmemleak report:

    unreferenced object 0xffff88003683fe00 (size 16):
    comm "mount", pid 2029, jiffies 4294909563 (age 33.380s)
    hex dump (first 16 bytes):
    20 27 1f bb 00 88 ff ff 40 4b 0f 36 02 88 ff ff '......@K.6....
    backtrace:
    [] create_object+0x124/0x2c0
    [] kmemleak_alloc+0x7b/0xc0
    [] __kmalloc+0x106/0x340
    [] ovl_fill_super+0x389/0x9a0 [overlay]
    [] mount_nodev+0x54/0xa0
    [] ovl_mount+0x18/0x20 [overlay]
    [] mount_fs+0x43/0x170
    [] vfs_kern_mount+0x74/0x170
    [] do_mount+0x22d/0xdf0
    [] SyS_mount+0x7b/0xc0
    [] entry_SYSCALL_64_fastpath+0x12/0x76
    [] 0xffffffffffffffff

    Signed-off-by: Konstantin Khlebnikov
    Signed-off-by: Miklos Szeredi
    Fixes: a78d9f0d5d5c ("ovl: support multiple lower layers")
    Signed-off-by: Greg Kroah-Hartman

    Konstantin Khlebnikov
     

23 Oct, 2015

3 commits

  • commit 9391dd00d13c853ab4f2a85435288ae2202e0e43 upstream.

    when opening a directory we want the overlayfs inode, not one from
    the topmost layer.

    Reported-By: Andrey Jr. Melnikov
    Tested-By: Andrey Jr. Melnikov
    Signed-off-by: Al Viro
    Cc: "Kamata, Munehisa"
    Signed-off-by: Greg Kroah-Hartman

    Al Viro
     
  • commit 4bacc9c9234c7c8eec44f5ed4e960d9f96fa0f01 upstream.

    Make file->f_path always point to the overlay dentry so that the path in
    /proc/pid/fd is correct and to ensure that label-based LSMs have access to the
    overlay as well as the underlay (path-based LSMs probably don't need it).

    Using my union testsuite to set things up, before the patch I see:

    [root@andromeda union-testsuite]# bash 5 /a/foo107
    [root@andromeda union-testsuite]# stat /mnt/a/foo107
    ...
    Device: 23h/35d Inode: 13381 Links: 1
    ...
    [root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
    ...
    Device: 23h/35d Inode: 13381 Links: 1
    ...

    After the patch:

    [root@andromeda union-testsuite]# bash 5 /mnt/a/foo107
    [root@andromeda union-testsuite]# stat /mnt/a/foo107
    ...
    Device: 23h/35d Inode: 40346 Links: 1
    ...
    [root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
    ...
    Device: 23h/35d Inode: 40346 Links: 1
    ...

    Note the change in where /proc/$$/fd/5 points to in the ls command. It was
    pointing to /a/foo107 (which doesn't exist) and now points to /mnt/a/foo107
    (which is correct).

    The inode accessed, however, is the lower layer. The union layer is on device
    25h/37d and the upper layer on 24h/36d.

    Signed-off-by: David Howells
    Signed-off-by: Al Viro
    Cc: "Kamata, Munehisa"
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     
  • commit f25801ee4680ef1db21e15c112e6e5fe3ffe8da5 upstream.

    Call ovl_drop_write() earlier in ovl_dentry_open() before we call vfs_open()
    as we've done the copy up for which we needed the freeze-write lock by that
    point.

    Signed-off-by: David Howells
    Signed-off-by: Al Viro
    Cc: "Kamata, Munehisa"
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     

22 Sep, 2015

1 commit

  • commit a068acf2ee77693e0bf39d6e07139ba704f461c3 upstream.

    Many file systems that implement the show_options hook fail to correctly
    escape their output which could lead to unescaped characters (e.g. new
    lines) leaking into /proc/mounts and /proc/[pid]/mountinfo files. This
    could lead to confusion, spoofed entries (resulting in things like
    systemd issuing false d-bus "mount" notifications), and who knows what
    else. This looks like it would only be the root user stepping on
    themselves, but it's possible weird things could happen in containers or
    in other situations with delegated mount privileges.

    Here's an example using overlay with setuid fusermount trusting the
    contents of /proc/mounts (via the /etc/mtab symlink). Imagine the use
    of "sudo" is something more sneaky:

    $ BASE="ovl"
    $ MNT="$BASE/mnt"
    $ LOW="$BASE/lower"
    $ UP="$BASE/upper"
    $ WORK="$BASE/work/ 0 0
    none /proc fuse.pwn user_id=1000"
    $ mkdir -p "$LOW" "$UP" "$WORK"
    $ sudo mount -t overlay -o "lowerdir=$LOW,upperdir=$UP,workdir=$WORK" none /mnt
    $ cat /proc/mounts
    none /root/ovl/mnt overlay rw,relatime,lowerdir=ovl/lower,upperdir=ovl/upper,workdir=ovl/work/ 0 0
    none /proc fuse.pwn user_id=1000 0 0
    $ fusermount -u /proc
    $ cat /proc/mounts
    cat: /proc/mounts: No such file or directory

    This fixes the problem by adding new seq_show_option and
    seq_show_option_n helpers, and updating the vulnerable show_option
    handlers to use them as needed. Some, like SELinux, need to be open
    coded due to unusual existing escape mechanisms.

    [akpm@linux-foundation.org: add lost chunk, per Kees]
    [keescook@chromium.org: seq_show_option should be using const parameters]
    Signed-off-by: Kees Cook
    Acked-by: Serge Hallyn
    Acked-by: Jan Kara
    Acked-by: Paul Moore
    Cc: J. R. Okajima
    Signed-off-by: Kees Cook
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Kees Cook
     

04 Aug, 2015

1 commit

  • commit cdb672795876d7bc1870aed9a2d7cb59f43d1d96 upstream.

    If jffs2 can deadlock on overlayfs readdir because it takes the same lock
    on ->iterate() as in ->lookup().

    Fix by moving whiteout checking outside iterate_dir(). Optimized by
    collecting potential whiteouts (DT_CHR) in a temporary list and if
    non-empty iterating throug these and checking for a 0/0 chardev.

    Signed-off-by: Miklos Szeredi
    Fixes: 49c21e1cacd7 ("ovl: check whiteout while reading directory")
    Reported-by: Roman Yeryomin
    Signed-off-by: Greg Kroah-Hartman

    Miklos Szeredi
     

19 May, 2015

1 commit

  • OpenWRT folks reported that overlayfs fails to mount if upper fs is full,
    because workdir can't be created. Wordir creation can fail for various
    other reasons too.

    There's no reason that the mount itself should fail, overlayfs can work
    fine without a workdir, as long as the overlay isn't modified.

    So mount it read-only and don't allow remounting read-write.

    Add a couple of WARN_ON()s for the impossible case of workdir being used
    despite being read-only.

    Reported-by: Bastian Bittorf
    Signed-off-by: Miklos Szeredi
    Cc: # v3.18+

    Miklos Szeredi
     

14 May, 2015

1 commit

  • When removing an opaque directory we can't just call rmdir() to check for
    emptiness, because the directory will need to be replaced with a whiteout.
    The replacement is done with RENAME_EXCHANGE, which doesn't check
    emptiness.

    Solution is just to check emptiness by reading the directory. In the
    future we could add a new rename flag to check for emptiness even for
    RENAME_EXCHANGE to optimize this case.

    Reported-by: Vincent Batts
    Signed-off-by: Miklos Szeredi
    Tested-by: Jordi Pujol Palomer
    Fixes: 263b4a0fee43 ("ovl: dont replace opaque dir")
    Cc: # v4.0+

    Miklos Szeredi
     

18 Mar, 2015

3 commits

  • After importing multi-lower layer support, users could mount a r/o
    partition as the left most lowerdir instead of using it as upperdir.
    And a r/o upperdir may cause an error like

    overlayfs: failed to create directory ./workdir/work

    during mount.

    This patch check the *s_flags* of upper fs and return an error if
    it is a r/o partition. The checking of *upper_mnt->mnt_sb->s_flags*
    can be removed now.

    This patch also remove

    /* FIXME: workdir is not needed for a R/O mount */

    from ovl_fill_super() because:

    1) for upper fs r/o case
    Setting a r/o partition as upper is prevented, no need to care about
    workdir in this case.

    2) for "mount overlay -o ro" with a r/w upper fs case
    Users could remount overlayfs to r/w in this case, so workdir should
    not be omitted.

    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     
  • Recently multi-lower layer mount support allow upperdir and workdir
    to be omitted, then cause overlayfs can be mount with only one
    lowerdir directory. This action make no sense and have potential risk.

    This patch check the total number of lower directories to prevent
    mounting overlayfs with only one directory.

    Also, an error message is added to indicate lower directories exceed
    OVL_MAX_STACK limit.

    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     
  • Overlayfs should print an error message if an incorrect mount option
    is caught like other filesystems.

    After this patch, improper option input could be clearly known.

    Reported-by: Fabian Sturm
    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     

23 Feb, 2015

1 commit

  • Convert the following where appropriate:

    (1) S_ISLNK(dentry->d_inode) to d_is_symlink(dentry).

    (2) S_ISREG(dentry->d_inode) to d_is_reg(dentry).

    (3) S_ISDIR(dentry->d_inode) to d_is_dir(dentry). This is actually more
    complicated than it appears as some calls should be converted to
    d_can_lookup() instead. The difference is whether the directory in
    question is a real dir with a ->lookup op or whether it's a fake dir with
    a ->d_automount op.

    In some circumstances, we can subsume checks for dentry->d_inode not being
    NULL into this, provided we the code isn't in a filesystem that expects
    d_inode to be NULL if the dirent really *is* negative (ie. if we're going to
    use d_inode() rather than d_backing_inode() to get the inode pointer).

    Note that the dentry type field may be set to something other than
    DCACHE_MISS_TYPE when d_inode is NULL in the case of unionmount, where the VFS
    manages the fall-through from a negative dentry to a lower layer. In such a
    case, the dentry type of the negative union dentry is set to the same as the
    type of the lower dentry.

    However, if you know d_inode is not NULL at the call site, then you can use
    the d_is_xxx() functions even in a filesystem.

    There is one further complication: a 0,0 chardev dentry may be labelled
    DCACHE_WHITEOUT_TYPE rather than DCACHE_SPECIAL_TYPE. Strictly, this was
    intended for special directory entry types that don't have attached inodes.

    The following perl+coccinelle script was used:

    use strict;

    my @callers;
    open($fd, 'git grep -l \'S_IS[A-Z].*->d_inode\' |') ||
    die "Can't grep for S_ISDIR and co. callers";
    @callers = ;
    close($fd);
    unless (@callers) {
    print "No matches\n";
    exit(0);
    }

    my @cocci = (
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISLNK(E->d_inode->i_mode)',
    '+ d_is_symlink(E)',
    '',
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISDIR(E->d_inode->i_mode)',
    '+ d_is_dir(E)',
    '',
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISREG(E->d_inode->i_mode)',
    '+ d_is_reg(E)' );

    my $coccifile = "tmp.sp.cocci";
    open($fd, ">$coccifile") || die $coccifile;
    print($fd "$_\n") || die $coccifile foreach (@cocci);
    close($fd);

    foreach my $file (@callers) {
    chomp $file;
    print "Processing ", $file, "\n";
    system("spatch", "--sp-file", $coccifile, $file, "--in-place", "--no-show-diff") == 0 ||
    die "spatch failed";
    }

    [AV: overlayfs parts skipped]

    Signed-off-by: David Howells
    Signed-off-by: Al Viro

    David Howells
     

20 Feb, 2015

1 commit


09 Jan, 2015

1 commit

  • Since the ovl_dir_cache is stable during a directory reading, the cursor
    of struct ovl_dir_file don't need to be an independent entry in the list
    of a merged directory.

    This patch changes *cursor* to a pointer which points to the entry in the
    ovl_dir_cache. After this, we don't need to check *is_cursor* either.

    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     

08 Jan, 2015

3 commits

  • Overlayfs should be mounted read-only when upper-fs is read-only or nonexistent.
    But now it can be remounted read-write and this can cause kernel panic.
    So we should prevent read-write remount when the above situation happens.

    Signed-off-by: Seunghun Lee
    Signed-off-by: Miklos Szeredi

    Seunghun Lee
     
  • Current multi-layer support overlayfs has a regression in
    .lookup(). If there is a directory in upperdir and a regular
    file has same name in lowerdir in a merged directory, lower
    file is hidden and upper directory is set to opaque in former
    case. But it is changed in present code.

    In lowerdir lookup path, if a found inode is not directory,
    the type checking of previous inode is missing. This inode
    will be copied to the lowerstack of ovl_entry directly.

    That will lead to several wrong conditions, for example,
    the reading of the directory in upperdir may return an error
    like:

    ls: reading directory .: Not a directory

    This patch makes the lowerdir lookup path check the opaque
    for non-directory file too.

    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     
  • The function ovl_fill_super() in recently multi-layer support
    version will incorrectly return 0 at error handling path and
    then cause kernel panic.

    This failure can be reproduced by mounting a overlayfs with
    upperdir and workdir in different mounts.

    And also, If the memory allocation of *lower_mnt* fail, this
    function may return an zero either.

    This patch fix this problem by setting *err* to proper error
    number before jumping to error handling path.

    Signed-off-by: hujianyang
    Signed-off-by: Miklos Szeredi

    hujianyang
     

13 Dec, 2014

16 commits


09 Dec, 2014

1 commit


20 Nov, 2014

3 commits