From 24b9970e8c8509b246f39da83af410e66860e7b5 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 6 Sep 2016 14:51:01 +0200 Subject: [PATCH] tests: add test for detect_ramfs_rootfs() Signed-off-by: Christian Brauner --- .gitignore | 2 +- src/tests/Makefile.am | 3 + src/tests/lxc-test-utils.c | 163 +++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a89968f1f..9ad094b04 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,7 @@ src/tests/lxc-test-shutdowntest src/tests/lxc-test-snapshot src/tests/lxc-test-startone src/tests/lxc-test-usernic -src/tests/lxc-test-utils +src/tests/lxc-test-utils* src/tests/lxc-usernic-test config/compile diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 2e7dd5602..322b8bbc4 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -105,3 +105,6 @@ EXTRA_DIST = \ shutdowntest.c \ snapshot.c \ startone.c + +clean-local: + rm -f lxc-test-utils-* diff --git a/src/tests/lxc-test-utils.c b/src/tests/lxc-test-utils.c index 5b213c84f..081ed4b9e 100644 --- a/src/tests/lxc-test-utils.c +++ b/src/tests/lxc-test-utils.c @@ -22,9 +22,16 @@ */ #define _GNU_SOURCE +#include +#include +#include #include #include #include +#include +#include +#include +#include #include "lxctest.h" #include "utils.h" @@ -60,6 +67,161 @@ void test_lxc_deslashify(void) free(s); } +void test_detect_ramfs_rootfs(void) +{ + size_t i; + int ret; + int fret = EXIT_FAILURE; + size_t len = 5 /* /proc */ + 21 /* /int_as_str */ + 7 /* /ns/mnt */ + 1 /* \0 */; + char path[len]; + int init_ns = -1; + char tmpf1[] = "lxc-test-utils-XXXXXX"; + char tmpf2[] = "lxc-test-utils-XXXXXX"; + int fd1 = -1, fd2 = -1; + FILE *fp1 = NULL, *fp2 = NULL; + char *mountinfo[] = { + "18 24 0:17 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw", + "19 24 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw", + "20 24 0:6 / /dev rw,nosuid,relatime shared:2 - devtmpfs udev rw,size=4019884k,nr_inodes=1004971,mode=755", + "21 20 0:14 / /dev/pts rw,nosuid,noexec,relatime shared:3 - devpts devpts rw,gid=5,mode=620,ptmxmode=000", + "22 24 0:18 / /run rw,nosuid,noexec,relatime shared:5 - tmpfs tmpfs rw,size=807912k,mode=755", + + /* This is what we care about. */ + "24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099", + + "25 18 0:12 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:8 - securityfs securityfs rw", + "26 20 0:20 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw", + "27 22 0:21 / /run/lock rw,nosuid,nodev,noexec,relatime shared:6 - tmpfs tmpfs rw,size=5120k", + "28 18 0:22 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:9 - tmpfs tmpfs ro,mode=755", + "29 28 0:23 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd", + "30 18 0:24 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:11 - pstore pstore rw", + "31 18 0:25 / /sys/firmware/efi/efivars rw,nosuid,nodev,noexec,relatime shared:12 - efivarfs efivarfs rw", + "32 28 0:26 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,cpu,cpuacct", + "33 28 0:27 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,net_cls,net_prio", + "34 28 0:28 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,blkio", + "35 28 0:29 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,freezer", + "36 28 0:30 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory", + "37 28 0:31 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,hugetlb", + "38 28 0:32 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,cpuset", + "39 28 0:33 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,devices", + "40 28 0:34 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,pids", + "41 28 0:35 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:23 - cgroup cgroup rw,perf_event", + "42 19 0:36 / /proc/sys/fs/binfmt_misc rw,relatime shared:24 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct", + "43 18 0:7 / /sys/kernel/debug rw,relatime shared:25 - debugfs debugfs rw", + "44 20 0:37 / /dev/hugepages rw,relatime shared:26 - hugetlbfs hugetlbfs rw", + "45 20 0:16 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw", + "46 43 0:9 / /sys/kernel/debug/tracing rw,relatime shared:28 - tracefs tracefs rw", + "76 18 0:38 / /sys/fs/fuse/connections rw,relatime shared:29 - fusectl fusectl rw", + "78 24 8:1 / /boot/efi rw,relatime shared:30 - vfat /dev/sda1 rw,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro", + }; + + ret = snprintf(path, len, "/proc/self/ns/mnt"); + if (ret < 0 || (size_t)ret >= len) { + lxc_error("%s\n", "Failed to create path with snprintf()."); + goto non_test_error; + } + + init_ns = open(path, O_RDONLY | O_CLOEXEC); + if (init_ns < 0) { + lxc_error("%s\n", "Failed to open initial mount namespace."); + goto non_test_error; + } + + if (unshare(CLONE_NEWNS) < 0) { + lxc_error("%s\n", "Could not unshare mount namespace."); + close(init_ns); + init_ns = -1; + goto non_test_error; + } + + if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) < 0) { + lxc_error("Failed to remount / private: %s.\n", strerror(errno)); + goto non_test_error; + } + + fd1 = mkstemp(tmpf1); + if (fd1 < 0) { + lxc_error("%s\n", "Could not create temporary file."); + goto non_test_error; + } + + fd2 = mkstemp(tmpf2); + if (fd2 < 0) { + lxc_error("%s\n", "Could not create temporary file."); + goto non_test_error; + } + + fp1 = fdopen(fd1, "r+"); + if (!fp1) { + lxc_error("%s\n", "Could not fdopen() temporary file."); + goto non_test_error; + } + + fp2 = fdopen(fd2, "r+"); + if (!fp2) { + lxc_error("%s\n", "Could not fdopen() temporary file."); + goto non_test_error; + } + + /* Test if it correctly detects - rootfs rootfs */ + for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) { + if (fprintf(fp1, "%s\n", mountinfo[i]) < 0) { + lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]); + goto non_test_error; + } + } + fclose(fp1); + fp1 = NULL; + + /* Test if it correctly fails to detect when no - rootfs rootfs */ + for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) { + if (strcmp(mountinfo[i], "24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099") == 0) + continue; + if (fprintf(fp2, "%s\n", mountinfo[i]) < 0) { + lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]); + goto non_test_error; + } + } + fclose(fp2); + fp2 = NULL; + + if (mount(tmpf1, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) { + lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\"."); + goto non_test_error; + } + + lxc_test_assert_abort(detect_ramfs_rootfs()); + + if (mount(tmpf2, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) { + lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\"."); + goto non_test_error; + } + + lxc_test_assert_abort(!detect_ramfs_rootfs()); + fret = EXIT_SUCCESS; + +non_test_error: + if (fp1) + fclose(fp1); + else if (fd1 > 0) + close(fd1); + if (fp2) + fclose(fp2); + else if (fd2 > 0) + close(fd2); + + if (init_ns > 0) { + if (setns(init_ns, 0) < 0) { + lxc_error("Failed to switch back to initial mount namespace: %s.\n", strerror(errno)); + fret = EXIT_FAILURE; + } + close(init_ns); + } + if (fret == EXIT_SUCCESS) + return; + exit(fret); +} + void test_lxc_string_replace(void) { char *s; @@ -117,6 +279,7 @@ int main(int argc, char *argv[]) test_lxc_string_replace(); test_lxc_string_in_array(); test_lxc_deslashify(); + test_detect_ramfs_rootfs(); exit(EXIT_SUCCESS); } -- 2.39.2