<div dir="ltr">Thanks Valdis!<div><br></div><div>I'm trying to enforce path-based access policies inside a file system</div><div><br></div><div>Dir to be excluded is specified during mount time:</div><div>mount -t fs -oexclude=/home/user/.ssh /home/user /home/user</div><div> </div><div>When an application invokes an open() sys call, the control is transferred to fs lookup function:</div><div>fd = open(path) -> VFS link_path_walk(path) -> walk_component(dentry) -> fs_lookup(inode, dentry)</div><div><br></div><div>Is it safe to do the following check in lookup?</div><div><br></div><div>int fs_lookup(inode, dentry) { // called on every path component</div><div><br></div><div>   struct path dentry_path;</div><div>   const char *full_path;</div><div><br></div><div>    ... // get dentry path <br></div><div><br></div><div>    full_path = d_path(&dentry_path, buf, PATH_MAX);         </div><div>    if (strcmp(exclude, full_path) == 0) {<br></div><div>        ret = -EACCES;</div><div>        goto out;</div><div>    }</div><div><br></div><div>    ... // clean up</div><div>}<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 24, 2018 at 6:32 PM,  <span dir="ltr"><<a href="mailto:valdis.kletnieks@vt.edu" target="_blank">valdis.kletnieks@vt.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, 24 Jul 2018 16:59:27 -0400, riya khanna said:<br>
<br>
> I'm trying to understand what prevents TOCTTOU race conditions in<br>
> dentry_path_raw<br>
> and link_path_walk? What happens when somebody points a symlink path<br>
> component from a dir that has the attacker is allowed to read to a dir that<br>
> they are not allowed to read while link_path_walk() is doing its job?<br>
<br>
</span>The important part is that each step of the walk is atomic - it will go where<br>
the link points at that point in the walk (or possibly fail if one of the steps<br>
points to a now non-existent or non-accessible location).  If there's 5 parts<br>
in the symlink path, say a/b/c/d/e, it will go to where 'a' points then, then<br>
attempt to lookup 'b' in whatever directory following 'a' left it, then if it<br>
finds 'b', it tries to lookup 'c', lather rinse repeat.<br>
<br>
So in your case, the reader will attempt to land in one directory or the other,<br>
at which point the permissions get applied.  So if the directory is unreadable,<br>
the effect is the same as if you were following <br>
'ln -s /foo/bar/unreadable/baz /tmp/quux'<br>
<br>
Another good way to confuse many programs is to have them cd to<br>
a directory that's a bunch of levels deep (5-6 is usually sufficient), and<br>
once they get there, have something chmod one of the intermediate<br>
directories to mode 000.  Things that chase '..' to find / then have a bad day...<br>
<br>
Most of the fun with TOCTTOU games with symlinks involves landing the<br>
victim in a directory they *can* do damage in, but not the intended one.<br>
For instance, getting root to do something in //lib/modules rather than in<br>
/tmp  (note that this can be done in auto-ambush mode with things like<br>
tar or cpio, where you deliver first a symlink off to someplace else, and<br>
then extract a file relative to the symlink)<br>
</blockquote></div><br></div>