kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
* link_path_walk/dentry_path_raw TOCTTOU race question
@ 2018-07-24 20:59 riya khanna
  2018-07-24 22:32 ` valdis.kletnieks at vt.edu
  0 siblings, 1 reply; 4+ messages in thread
From: riya khanna @ 2018-07-24 20:59 UTC (permalink / raw)
  To: kernelnewbies

Hi,

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?

Thanks!
-Riya
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180724/2c63a800/attachment.html>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* link_path_walk/dentry_path_raw TOCTTOU race question
  2018-07-24 20:59 link_path_walk/dentry_path_raw TOCTTOU race question riya khanna
@ 2018-07-24 22:32 ` valdis.kletnieks at vt.edu
  2018-07-24 23:42   ` riya khanna
  0 siblings, 1 reply; 4+ messages in thread
From: valdis.kletnieks at vt.edu @ 2018-07-24 22:32 UTC (permalink / raw)
  To: kernelnewbies

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 --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 486 bytes
Desc: not available
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180724/988a358a/attachment.sig>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* link_path_walk/dentry_path_raw TOCTTOU race question
  2018-07-24 22:32 ` valdis.kletnieks at vt.edu
@ 2018-07-24 23:42   ` riya khanna
  2018-07-25  8:08     ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: riya khanna @ 2018-07-24 23:42 UTC (permalink / raw)
  To: kernelnewbies

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@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>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* link_path_walk/dentry_path_raw TOCTTOU race question
  2018-07-24 23:42   ` riya khanna
@ 2018-07-25  8:08     ` Greg KH
  0 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2018-07-25  8:08 UTC (permalink / raw)
  To: kernelnewbies

On Tue, Jul 24, 2018 at 07:42:08PM -0400, riya khanna wrote:
> Thanks Valdis!
> 
> I'm trying to enforce path-based access policies inside a file system

<snip>

Look at how the apparmor code does it, that's the best solution here.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-07-25  8:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-24 20:59 link_path_walk/dentry_path_raw TOCTTOU race question riya khanna
2018-07-24 22:32 ` valdis.kletnieks at vt.edu
2018-07-24 23:42   ` riya khanna
2018-07-25  8:08     ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).