/* * Test subdir as private FS in new mount namespace . * Version 2 of ct_namespace_mnt1.c . It mounts the procfs file system so that we can query the /proc/self/mounts from the program in the container */ #include #include #include #include #include #include #include #include #include #include #include "test.h" #ifndef CLONE_NEWNS #define CLONE_NEWNS 0x00020000 #endif #define FS_ROOT "libct_test_root_ns" #define FS_PRIVATE "libct_test_private_ns" #define FS_FILE "libct_test_file_ns" #define FS_NEW_FILE "new" #define FS_PTS "libct_test_devpts" #define FS_SECRET_DIR "secret-dir" #define FS_SECRET_FILE "secret-file" // External directories that will be bind mounted in the container #define FS_EXT_BIN "/bin" #define FS_EXT_LIB "/lib" #define FS_EXT_LIB64 "/lib64" #define FS_CT_BIN "bin" #define FS_CT_LIB "lib" #define FS_CT_LIB64 "lib64" static int check_fs_data(void *a) { int fd; int *fs_data = a; printf("\n In check_fs_data \n"); fd = open("/"FS_FILE, O_CREAT, O_RDONLY); if (fd < 0) return 0; close(fd); printf("\n In entered callback pid value is %d \n", getpid()); fd = open("/" FS_NEW_FILE,O_CREAT, O_RDWR); if (fd < 0) return 0; close(fd); if (access("/"FS_FILE, F_OK) == 0) { printf (" File %s is available inside \n",FS_FILE); } else { printf (" File %s is NOT available inside !! \n",FS_FILE); } if (access("/"FS_CT_BIN"/ls", F_OK) == 0) printf (" ls program is accessible in the CT \n"); else printf (" ls program is NOT available !! \n"); mkdir("/"FS_SECRET_DIR, 0600); mkdir("/proc", 0600); printf("\n In check private mounts \n "); printf("\n ls in %s \n",FS_PRIVATE ); system("/bin/ls -la "FS_PRIVATE""); printf("\n ls in root of the container \n"); system("/bin/ls -la /"); printf("\n ls in %s \n",FS_ROOT ); system("/bin/ls -la "FS_ROOT""); system("/bin/mount"); printf("\n In before mount \n "); system("/bin/mount -n -o size=1m -t tmpfs tmpfs /"FS_SECRET_DIR""); if (creat("/"FS_SECRET_DIR "/" FS_SECRET_FILE, 0600) < 0) { printf("Can't create file %s",FS_SECRET_FILE ); } printf("\n ls in root of the container \n"); system("/bin/ls -la /"); if (access("/"FS_SECRET_DIR "/" FS_SECRET_FILE, F_OK) == 0) { printf (" File %s is available inside \n",FS_SECRET_FILE); } else { printf (" File %s is NOT available inside !! \n",FS_SECRET_FILE); } system("/bin/mount -t proc proc /proc"); printf("\n Looking at /proc/self/mounts \n"); system("/bin/cat /proc/self/mounts"); printf("\n Keeping the program in the container with pid %d running \n ", getpid()); *fs_data = 1; //Keeping the namespace program running while(1) { } #if 0 char buf[32]; readlink("/proc/self", buf, sizeof(buf)); printf("\n The pid of the callback is %d\n ", atoi(buf)); #endif return 0; } static int is_private_filesystem_hidden() { printf ("\n In is_private_filesystem_hidden \n "); printf("\n ls in %s \n",FS_PRIVATE ); system("ls -la "FS_PRIVATE""); printf("\n ls in %s \n",FS_ROOT ); system("ls -la "FS_ROOT""); if (access(FS_ROOT"/"FS_NEW_FILE, F_OK) == 0) { printf (" Secret file %s/%s is available outside \n",FS_ROOT,FS_NEW_FILE); } else { printf (" Secret file is %s/%s NOT available outside !! \n",FS_ROOT,FS_NEW_FILE); } if (access(FS_PRIVATE"/"FS_FILE, F_OK) == 0) { printf (" Secret file %s/%s is available outside \n",FS_PRIVATE,FS_FILE); } else { printf (" Secret file %s/%s is NOT available outside !! \n",FS_PRIVATE,FS_FILE); } printf("\n ls from outside the namespace in secret-directory \n "); system("ls -la "FS_ROOT"/"FS_SECRET_DIR""); return 1; } int main(int argc, char **argv) { char *fs_data; libct_session_t s; ct_handler_t ct; ct_process_desc_t p; ct_process_t pr; int fs_err = 0; int status ; mkdir(FS_ROOT, 0600); mkdir(FS_PRIVATE, 0600); mkdir(FS_ROOT "/" FS_CT_BIN, 0600); mkdir(FS_ROOT "/" FS_CT_LIB, 0600); mkdir(FS_ROOT "/" FS_CT_LIB64, 0600); if (creat(FS_PRIVATE "/" FS_FILE, 0600) < 0) { tst_perr("Can't create file"); return 2; } unlink(FS_ROOT "/" FS_FILE); unlink(FS_PRIVATE "/" FS_FILE); fs_data = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0); fs_data[0] = '\0'; s = libct_session_open_local(); ct = libct_container_create(s, "test"); p = libct_process_desc_create(s); libct_container_set_nsmask(ct, CLONE_NEWNS); libct_fs_set_root(ct, FS_ROOT); libct_fs_add_bind_mount(ct, FS_EXT_BIN, FS_CT_BIN, 0); libct_fs_add_bind_mount(ct, FS_EXT_LIB, FS_CT_LIB, 0); libct_fs_add_bind_mount(ct, FS_EXT_LIB64, FS_CT_LIB64, 0); libct_fs_add_mount(ct, "test_devpts", FS_PTS, 0, "devpts", "newinstance"); libct_fs_set_private(ct, CT_FS_SUBDIR, FS_PRIVATE); pr =libct_container_spawn_cb(ct, p, check_fs_data, fs_data); printf("\n Before \n"); libct_process_wait(pr, &status); printf("\nAfter wait \n"); is_private_filesystem_hidden(); libct_container_wait(ct); libct_container_destroy(ct); libct_session_close(s); if (unlink(FS_PRIVATE "/" FS_FILE) < 0) fs_err |= 1; if (rmdir(FS_ROOT "/" FS_CT_BIN) < 0) fs_err |= 2; if (rmdir(FS_ROOT "/" FS_CT_LIB) < 0) fs_err |= 4; if (rmdir(FS_ROOT "/" FS_CT_LIB64) < 0) fs_err |= 8; if (rmdir(FS_ROOT) < 0) fs_err |= 3; if (rmdir(FS_PRIVATE "/" FS_CT_BIN) < 0) fs_err |= 5; if (rmdir(FS_PRIVATE "/" FS_CT_LIB) < 0) fs_err |= 6; if (rmdir(FS_PRIVATE "/" FS_CT_LIB64) < 0) fs_err |= 7; if (unlink(FS_PRIVATE "/" FS_NEW_FILE) < 0) fs_err |= 9; if (rmdir(FS_PRIVATE "/" FS_SECRET_DIR) < 0) fs_err |= 11; if (rmdir(FS_PRIVATE "/proc") < 0) fs_err |= 12; if (rmdir(FS_PRIVATE "/" FS_PTS) < 0) fs_err |= 13; if (rmdir(FS_PRIVATE) < 0) { fs_err |= 16; printf(" error = %d\n", errno); } if (fs_err) { printf("FS remove failed %d \n",fs_err); return fail("FS broken"); } if (!fs_data[0]) return fail("FS private is not accessible"); return pass("Creation of private filesystem using mount namespace is OK"); }