Subject: Re: CRITICAL ** Holes in default cron jobs ** CRITICAL
To: None <mouse@Holo.Rodents.Montreal.QC.CA>
From: Mike Long <mike.long@analog.com>
List: tech-kern
Date: 01/02/1997 13:43:51
[this probably belongs in tech-userlevel instead of tech-kern, but
I'll leave it here to preserve the thread.]

>Date: Thu, 2 Jan 1997 11:27:02 -0500 (EST)
>From: der Mouse <mouse@Holo.Rodents.Montreal.QC.CA>

>But chdir()ing through .. is just what you can't do, or you can wind up
>in an arbitrary unexpected place about which all you know is that it's
>on the same filesystem you started from (assuming a few reasonable
>things about who can do mounts and umounts and who owns mount points),
>and if you do a second chdir("..") before recovering you don't know
>even that much.  Er, not quite - you do know that if you wind up
>someplace unexpected, it's someplace the attacker had write access to
>at some point between your descent and your ascent.  (I don't see how
>knowing this could be useful; I'm being a bit pedantic.)

>Of course, you can _detect_ having been tricked when you chdir("..");
>it's just not clear to me what you can _do_ about it - especially if
>you're stuck in a library routine like fts_*() where you don't know
>whether the appropriate action is plowing bravely on, a silent exit, a
>noisy exit, or something else (perhaps a syslog message plus carrying
>on)....

What you can do is to keep a stack of structures, one for each
directory you have traversed to get from the original starting
directory to the current directory.  The structure contains the
directory's pathname, device#, and inode#.  When you recurse into a
directory, you push that directory's stats onto the stack.

When backtracking, you could just pop the stack, and chdir() to the
path in the new top element instead of chdir("..").  Then you can
open() "." and fstat() it to verify that the device# and inode# match.
If not, then you can (optionally) make noise, pop the stack again, and
repeat the process.  Continue until you either find a directory that
matches, or empty the stack.

Support for such a scheme seems to already exist in fts(3); I'm
insufficiently familiar with it to be sure.  I won't claim that this
proposal is ideal, but hopefully it can help someone generate a better
idea.
-- 
Mike Long <mike.long@analog.com>     <URL:http://www.shore.net/~mikel>
VLSI Design Engineer         finger mikel@shore.net for PGP public key
Analog Devices, CPD Division          CCBF225E7D3F7ECB2C8F7ABB15D9BE7B
Norwood, MA 02062 USA       (eq (opinion 'ADI) (opinion 'mike)) -> nil