[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#661627: Avoid /tmp ?



On Fri, Mar  2, 2012 at 12:44:23 +0100, vladz wrote:

> 
> Julien, thank you for putting me back in CC. ;)
> 
> On Thu, Mar 01, 2012 at 09:48:47PM +0100, Julien Cristau wrote:
> > On Thu, Mar  1, 2012 at 12:39:41 -0800, Tim wrote:
> > > > > Note that the "chown root:root $SOCKET_DIR" also seems redundant to me
> > > > > (if we didn't already own it, we would have bigger problems, right?).
> > > > > 
> > > > I guess it protects against some user doing mkdir /tmp/.X11-unix before
> > > > this runs (which probably means before the package is installed, so it's
> > > > not like this is a very likely race) and then owning the directory.
> > > 
> > > Oh, right, duh.  Well, the dir is created every time the box boots,
> > > since /tmp is cleared, so it is needed for sure.
> 
> I think the obsolete chown command should be removed (as said Tim), and
> also the chmod should by replaced by a single atomic operation (using 
> "mkdir -m").  Those two things will avoid usages of dangerous commands
> and then, reduce TOCTTOU risks.
> 
I'm not convinced the chown can be removed.  And 'mkdir -m 1777 foo' is
not any more atomic than 'mkdir foo && chmod 1777 foo'.  The problem is
that I'd still like to be able to chown and chmod /tmp/.X11-unix if it
already exists as a directory when the script runs.  I can do that in C
with something like this:

  ret = mkdir("/tmp/.X11-unix", 0700);
  if (ret == 0 || errno == EEXIST) {
    fd = open("/tmp/.X11-unix", O_RDONLY | O_NOFOLLOW);
    if (fd < 0)
      fail();
    fstat(fd, &st);
    if (!S_ISDIR(st.st_mode))
      fail();
    if (fchown(fd, 0, 0)) fail();
    if (fchmod(fd, 01777)) fail();
  } else {
    fail();
  }

but so far I haven't seen a way to do that in shell, because chmod(1)
doesn't have a --no-dereference option, and even if it did it doesn't
look like I could safely detect whether to exit with failure or success.

hmm, how about this:

mkdir -p /tmp/.X11-unix
chown -h root:root /tmp/.X11-unix
stat=$(LC_ALL=C stat -c '%u %g %F' /tmp/.X11-unix)
if [ "$stat" != '0 0 directory' ]; then
  exit 1
fi
chmod 1777 /tmp/.X11-unix

?

> To finish, I find the ways to create those two directories ($SOCKET_DIR
> and $ICE_DIR) quite redundant.  A function called create_dir() could 
> contain the code above and be launched from both set_up_socket_dir() and
> set_up_ice_dir()?
> 
Agreed.  Or drop those two functions and call set_up_dir "$SOCKET_DIR &&
set_up_dir $ICE_DIR" directly.

Thanks a lot to you both for the help so far...

Cheers,
Julien



Reply to: