[cs631apue] question about chroot(2)

yluo4 yluo4 at stevens.edu
Wed Nov 20 12:54:57 EST 2013


Hi,
   I think option(1) may also need to check if directory exist. For 
example,
   ./sws /home/yluo4/testdir
   GET /../dir_test/../test

   I think if dir_test doesn't exist in  /home/yluo4/testdir, we should 
response "Not Found", not resolve it to /home/yluo4/testdir/test.
   Maybe we can combine option(1) and option(2) together.  As following,
     canonpath = prefix;
     while not end of shortpath:
		find the next '/',
  		chars = chars up until that '/'
  		canonpath = canonpath + chars;
                 realpath(canonpath);
                 if error:
                    return error;
                 if success:
                     if canonpath is not under prefix:
                         if chars == "..":
                            canonpath = prefix;
                         else: /*this is the case that symbolic link 
points to out of prefix.  Is it right to return
                                * error in this case?
                                */
                            return error;

Thanks,
  Yulong



On 11/19/2013 11:27 PM, Jan Schaumann wrote:
> yluo4 <yluo4 at stevens.edu> wrote:
> 
>>   chroot(2) can change the root directory of a process to specified
>> directory and then we can use realpath(3) or use  dirname() and
>> basename() to solve the path problem easily.  But we don't have
>> privilege to use chroot(2) in linux lab.  Does anyone have an easy way
>> to solve the path problem?
> 
> You're right, without using chroot(2), which you can't do, this will 
> get
> tricky.
> 
> Off the top of my head, I think I'd probably try to do this something
> along these lines:
> 
> read request
> if request begins with "/~foo"
> 	strip /~foo
> 	get homedir for user "foo"
> 	append "sws" to homedir for user "foo"
> 	store that path as prefix
> 	store remainder of request as shortpath
> 
> if request begins with "/cgi-bin"
> 	strip "/cgi-bin"
> 	take cgi-dir as specified at startup time
> 	store that path as prefix
> 	store remainder of request as shortpath
> 
> if request doesn't match either of those two cases:
> 	take root dir specified at startup time
> 	store that path as prefix
> 	store request as shortpath
> 
> Then, option (1):
> 
> canonicolize shortpath:
> 	dirs = an array of directories, initially empty
> 	while not end of shortpath:
> 		find the next '/',
> 		chars = chars up until that '/'
> 		if chars == ".."
> 			pop last entry off dirs
> 		else if chars == "."
> 			continue
> 		else
> 			push chars onto dirs
> 	join dirs with '/' slashes into new canonpath
> 
> use prefix+canonpath as the final path
> 
> 
> 
> Option(2):
> 
> canonicolize prefix+shortpath using realpath(3) as canonpath
> 
> if realpath(3) errors, return an error
> if realpath(3) succeeds:
> 	if canonpath is not under prefix, return an error
> 
> 
> 
> Both options have their disadvantages:
> In (1) you're not handling symlinks, which might exist under the
> server's docroot, and which would have to be resolved within that
> docroot.
> 
> In (2), you're not accounting for the possibility of a URI request that
> may exist under the docroot but that canonicolizes to outside of the
> prefix.
> 
> 
> I'm fine with you choosing either option.  I'm also fine with you 
> coming
> up with another option that makes more sense (if so, please share it
> here).  Maybe take a look at what other web servers like bozohttpd or
> mini_httpd do, too.  Some web servers may take the lazy way out and
> simply say that requests containing "../" are not allowed.  This,
> however, is not very elegant, nor correct according to the RFC, I
> believe.
> 
> Also, welcome to software development, where something as seemingly
> simple as resolving a path becomes... this.
> 
> -Jan
> _______________________________________________
> cs631apue mailing list
> cs631apue at lists.stevens.edu
> https://lists.stevens.edu/mailman/listinfo/cs631apue


More information about the cs631apue mailing list