lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAG48ez0srRLS07oiL6x61eRzoD+LpLgT_=74hCJGRFqfYd00Pg@mail.gmail.com>
Date:   Thu, 12 Jul 2018 15:54:52 -0700
From:   Jann Horn <jannh@...gle.com>
To:     Alexander Viro <viro@...iv.linux.org.uk>,
        linux-fsdevel@...r.kernel.org
Cc:     kernel list <linux-kernel@...r.kernel.org>
Subject: readdir() and directory names containing slashes

Hi!

The kernel doesn't seem to filter slashes out of directory names
coming from the disk (with the exception of a few specific
filesystems, like FUSE):

# touch fatimg
# truncate --size=40M fatimg
# mkfs.fat fatimg
mkfs.fat 4.1 (2017-01-24)
# mkdir mount
# mount fatimg mount
# touch mount/FOOBAR
# umount mount
# sed -i 's|FOOBAR|FO/BAR|' fatimg
# mount fatimg mount
# strace -v -e trace=getdents,lstat ls -l mount
lstat("mount", {st_dev=makedev(7, 0), st_ino=1, st_mode=S_IFDIR|0755,
st_nlink=2, st_uid=0, st_gid=0, st_blksize=2048, st_blocks=32,
st_size=16384, st_atime=0, st_atime_nsec=0, st_mtime=0,
st_mtime_nsec=0, st_ctime=0, st_ctime_nsec=0}) = 0
getdents(3, [{d_ino=1, d_off=1, d_reclen=24, d_name=".",
d_type=DT_DIR}, {d_ino=1, d_off=2, d_reclen=24, d_name="..",
d_type=DT_DIR}, {d_ino=267, d_off=16384, d_reclen=32, d_name="FO/BAR",
d_type=DT_REG}], 32768) = 80
lstat("mount/FO/BAR", 0x5603c71ee1a8)   = -1 ENOENT (No such file or directory)
ls: cannot access 'mount/FO/BAR': No such file or directory
getdents(3, [], 32768)                  = 0
total 0
-????????? ? ? ? ?            ? FO/BAR
+++ exited with 1 +++

I think it would be reasonable for the VFS layer to block this - if
someone puts something like "../../etc" in a filename, userspace could
get pretty confused.

AFAICS the simple way to deal with this would be to patch dir_emit()
to do something like this:

if (WARN_ON_ONCE(memchr(name, '/', namelen))) return true;

... but then readdir() won't indicate to userspace that the kernel
omitted a (bad) directory entry. A cleaner way might be to patch all
the ->actor handlers to do the check and propagate the error
appropriately, but then the checks would have to be placed in more
places... which also doesn't seem very clean.

Al, you probably have opinions on this?

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ