link_path_walk/dentry_path_raw TOCTTOU race question

riya khanna riyakhanna1983 at gmail.com
Tue Jul 24 19:42:08 EDT 2018


Thanks Valdis!

I'm trying to enforce path-based access policies inside a file system

Dir to be excluded is specified during mount time:
mount -t fs -oexclude=/home/user/.ssh /home/user /home/user

When an application invokes an open() sys call, the control is transferred
to fs lookup function:
fd = open(path) -> VFS link_path_walk(path) -> walk_component(dentry) ->
fs_lookup(inode, dentry)

Is it safe to do the following check in lookup?

int fs_lookup(inode, dentry) { // called on every path component

   struct path dentry_path;
   const char *full_path;

    ... // get dentry path

    full_path = d_path(&dentry_path, buf, PATH_MAX);
    if (strcmp(exclude, full_path) == 0) {
        ret = -EACCES;
        goto out;
    }

    ... // clean up
}

On Tue, Jul 24, 2018 at 6:32 PM, <valdis.kletnieks at vt.edu> wrote:

> On Tue, 24 Jul 2018 16:59:27 -0400, riya khanna said:
>
> > I'm trying to understand what prevents TOCTTOU race conditions in
> > dentry_path_raw
> > and link_path_walk? What happens when somebody points a symlink path
> > component from a dir that has the attacker is allowed to read to a dir
> that
> > they are not allowed to read while link_path_walk() is doing its job?
>
> The important part is that each step of the walk is atomic - it will go
> where
> the link points at that point in the walk (or possibly fail if one of the
> steps
> points to a now non-existent or non-accessible location).  If there's 5
> parts
> in the symlink path, say a/b/c/d/e, it will go to where 'a' points then,
> then
> attempt to lookup 'b' in whatever directory following 'a' left it, then if
> it
> finds 'b', it tries to lookup 'c', lather rinse repeat.
>
> So in your case, the reader will attempt to land in one directory or the
> other,
> at which point the permissions get applied.  So if the directory is
> unreadable,
> the effect is the same as if you were following
> 'ln -s /foo/bar/unreadable/baz /tmp/quux'
>
> Another good way to confuse many programs is to have them cd to
> a directory that's a bunch of levels deep (5-6 is usually sufficient), and
> once they get there, have something chmod one of the intermediate
> directories to mode 000.  Things that chase '..' to find / then have a bad
> day...
>
> Most of the fun with TOCTTOU games with symlinks involves landing the
> victim in a directory they *can* do damage in, but not the intended one.
> For instance, getting root to do something in //lib/modules rather than in
> /tmp  (note that this can be done in auto-ambush mode with things like
> tar or cpio, where you deliver first a symlink off to someplace else, and
> then extract a file relative to the symlink)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180724/7f02957b/attachment.html>


More information about the Kernelnewbies mailing list