Quoting Niels Thykier ([email protected]): > On 2015-03-13 18:31, Serge Hallyn wrote: > > Hi, > > > > those two patches are fixups after the following patch: > > > > https://github.com/lxc/cgmanager/commit/a08d1c038c8457cda1b5d85c4d628595157812c1 > > > > startup: pivot into a mostly-empty new root > > > > which is the one that really fixed the issue. Backporting these > > should be no big deal. Please let me know if you hit any issues, > > So the fix for #757348 requires a08d1c0 plus the two patches I mentioned?
That should do it. > > I'm up against some deadlines today but if needed I can come up > > with a debdiff over the weekend. > > > > [...] > > If you have time to prepare a t-p-u upload for it, then that would be > great. Otherwise, if you can confirm the above, then I believe I have > enough to out delegate it if needed. Here is a debdiff - it builds and installs fine and solves the bug on my end. thanks, -serge diff -Nru cgmanager-0.33/debian/changelog cgmanager-0.33/debian/changelog --- cgmanager-0.33/debian/changelog 2015-02-16 21:19:02.000000000 -0600 +++ cgmanager-0.33/debian/changelog 2015-03-14 23:40:15.000000000 -0500 @@ -1,3 +1,10 @@ +cgmanager (0.33-2+deb8u2) testing-proposed-updates; urgency=medium + + * Cherrypick patches to run cgmanager in a private namespace to prevent + host mounts from being pinned. (Closes: #757348) + + -- Serge Hallyn <[email protected]> Sat, 14 Mar 2015 23:37:07 -0500 + cgmanager (0.33-2+deb8u1) testing-proposed-updates; urgency=medium * SECURITY UPDATE: Cross-cgroup resource control bypass. diff -Nru cgmanager-0.33/debian/patches/bind-mount-old-root.patch cgmanager-0.33/debian/patches/bind-mount-old-root.patch --- cgmanager-0.33/debian/patches/bind-mount-old-root.patch 1969-12-31 18:00:00.000000000 -0600 +++ cgmanager-0.33/debian/patches/bind-mount-old-root.patch 2015-03-14 23:35:39.000000000 -0500 @@ -0,0 +1,46 @@ +commit 55138814d2fedc8d71e2196f75b04d31970d1dad +Author: Serge Hallyn <[email protected]> +Date: Fri Feb 13 13:44:59 2015 -0600 + + pivot_root: bind-mount the old / rather than starting with empty / + + That way we get /lib and /etc which sometimes are needed. + + Signed-off-by: Serge Hallyn <[email protected]> + +Index: cgmanager-0.33/fs.c +=================================================================== +--- cgmanager-0.33.orig/fs.c ++++ cgmanager-0.33/fs.c +@@ -850,8 +850,7 @@ fail: + + static int pivot_into_new_root(void) { + int i, ret; +- char *createdirs[] = {NEWROOT "/proc", NEWROOT "/run", +- NEWROOT "/run/cgmanager", NEWROOT "/run/cgmanager/fs", NULL}; ++ char *createdirs[] = {NEWROOT "/run/cgmanager", NEWROOT "/run/cgmanager/fs", NULL}; + char path[100]; + + /* Mount tmpfs for new root */ +@@ -859,16 +858,17 @@ static int pivot_into_new_root(void) { + nih_fatal("%s: Failed to create directory for new root\n", __func__); + return -1; + } +- ret = mount("root", NEWROOT, "tmpfs", 0, "size=10000,mode=0755"); ++ ret = mount("/", NEWROOT, NULL, MS_BIND, 0); + if (ret < 0) { +- nih_fatal("%s: Failed to mount tmpfs for root", __func__); ++ nih_fatal("%s: Failed to bind-mount / for new root", __func__); + return -1; + } + + /* create /proc and /run/cgmanager/fs, and move-mount those */ + for (i = 0; createdirs[i]; i++) { +- if (mkdir(createdirs[i], 0755) < 0) { +- nih_fatal("%s: failed to created %s\n", __func__, createdirs[i]); ++ if (mkdir(createdirs[i], 0755) < 0 && errno != EEXIST) { ++ nih_fatal("%s: failed to create %s: %s\n", __func__, ++ createdirs[i], strerror(errno)); + return -1; + } + } diff -Nru cgmanager-0.33/debian/patches/bind-mount-run-from-host.patch cgmanager-0.33/debian/patches/bind-mount-run-from-host.patch --- cgmanager-0.33/debian/patches/bind-mount-run-from-host.patch 1969-12-31 18:00:00.000000000 -0600 +++ cgmanager-0.33/debian/patches/bind-mount-run-from-host.patch 2015-03-14 23:35:39.000000000 -0500 @@ -0,0 +1,58 @@ +commit 6dcd68be0c6d349f5754deb022761806ceb720ab +Author: Serge Hallyn <[email protected]> +Date: Fri Feb 13 14:30:09 2015 -0600 + + bind-mount /run from host into cgmanager's fs as well + + That's so that if host is running sysvinit, /run/cgmanager.pid + shows up on the host's mounted /run, not the underlying rootfs + /run/. + + Signed-off-by: Serge Hallyn <[email protected]> + +Index: cgmanager-0.33/fs.c +=================================================================== +--- cgmanager-0.33.orig/fs.c ++++ cgmanager-0.33/fs.c +@@ -864,15 +864,6 @@ static int pivot_into_new_root(void) { + return -1; + } + +- /* create /proc and /run/cgmanager/fs, and move-mount those */ +- for (i = 0; createdirs[i]; i++) { +- if (mkdir(createdirs[i], 0755) < 0 && errno != EEXIST) { +- nih_fatal("%s: failed to create %s: %s\n", __func__, +- createdirs[i], strerror(errno)); +- return -1; +- } +- } +- + ret = snprintf(path, 100, NEWROOT "/proc"); + if (ret < 0 || ret > 100) + return -1; +@@ -881,6 +872,25 @@ static int pivot_into_new_root(void) { + __func__, strerror(errno)); + return -1; + } ++ ++ ret = snprintf(path, 100, NEWROOT "/run"); ++ if (ret < 0 || ret > 100) ++ return -1; ++ ret = mount("/run", path, NULL, MS_BIND, 0); ++ if (ret < 0) { ++ nih_fatal("%s: failed to move /run into new root: %s", ++ __func__, strerror(errno)); ++ return -1; ++ } ++ ++ for (i = 0; createdirs[i]; i++) { ++ if (mkdir(createdirs[i], 0755) < 0 && errno != EEXIST) { ++ nih_fatal("%s: failed to create %s : %s\n", __func__, ++ createdirs[i], strerror(errno)); ++ return -1; ++ } ++ } ++ + ret = snprintf(path, 100, NEWROOT "/run/cgmanager/fs"); + if (ret < 0 || ret > 100) + return -1; diff -Nru cgmanager-0.33/debian/patches/pivot-into-mostly-empty-nonroot cgmanager-0.33/debian/patches/pivot-into-mostly-empty-nonroot --- cgmanager-0.33/debian/patches/pivot-into-mostly-empty-nonroot 1969-12-31 18:00:00.000000000 -0600 +++ cgmanager-0.33/debian/patches/pivot-into-mostly-empty-nonroot 2015-03-14 23:35:39.000000000 -0500 @@ -0,0 +1,205 @@ +commit a08d1c038c8457cda1b5d85c4d628595157812c1 +Author: Serge Hallyn <[email protected]> +Date: Tue Feb 10 21:18:45 2015 -0600 + + startup: pivot into a mostly-empty new root + + And umount everything but /proc and /run/cgmanager/fs in our new root. + + That prevents us from pinning them if the host wants to unmount them. + + Signed-off-by: Serge Hallyn <[email protected]> + +Index: cgmanager-0.33/configure.ac +=================================================================== +--- cgmanager-0.33.orig/configure.ac ++++ cgmanager-0.33/configure.ac +@@ -23,6 +23,8 @@ AC_PROG_CC + + AC_PROG_CC_C99 + ++AC_CHECK_FUNCS([setns pivot_root]) ++ + AC_PATH_PROG([NIH_DBUS_TOOL], [nih-dbus-tool]) + + PKG_CHECK_MODULES([NIH], [libnih >= 1.0.2]) +Index: cgmanager-0.33/fs.c +=================================================================== +--- cgmanager-0.33.orig/fs.c ++++ cgmanager-0.33/fs.c +@@ -56,6 +56,21 @@ + #define AGENT SBINDIR "/cgm-release-agent" + #define AGENT_LINK_PATH "/run/cgmanager/agents" + ++/* Define pivot_root() if missing from the C library */ ++#ifndef HAVE_PIVOT_ROOT ++static int pivot_root(const char * new_root, const char * put_old) ++{ ++#ifdef __NR_pivot_root ++return syscall(__NR_pivot_root, new_root, put_old); ++#else ++errno = ENOSYS; ++return -1; ++#endif ++} ++#else ++extern int pivot_root(const char * new_root, const char * put_old); ++#endif ++ + char *all_controllers; + + struct controller_mounts { +@@ -124,6 +139,10 @@ bool setup_base_run_path(void) + nih_fatal("%s: failed to create /run/cgmanager/fs", __func__); + return false; + } ++ if (mount("cgmfs", "/run/cgmanager/fs", "tmpfs", 0, "size=100000,mode=0755") < 0) { ++ nih_fatal("%s: failed to mount tmpfs onto /run/cgmanager/fs", __func__); ++ return false; ++ } + if (mkdir(AGENT_LINK_PATH, 0755) < 0 && errno != EEXIST) { + nih_fatal("%s: failed to create %s", __func__, AGENT_LINK_PATH); + return false; +@@ -768,6 +787,116 @@ int collect_subsystems(char *extra_mount + return 0; + } + ++#define NEWROOT "/run/cgmanager/root" ++ ++static int do_pivot(void) { ++ int oldroot = -1, newroot = -1; ++ ++ oldroot = open("/", O_DIRECTORY | O_RDONLY); ++ if (oldroot < 0) { ++ nih_fatal("%s: Error opening old-/ for fchdir", __func__); ++ return -1; ++ } ++ newroot = open(NEWROOT, O_DIRECTORY | O_RDONLY); ++ if (newroot < 0) { ++ nih_fatal("%s: Error opening new-/ for fchdir", __func__); ++ goto fail; ++ } ++ ++ /* change into new root fs */ ++ if (fchdir(newroot)) { ++ nih_fatal("%s: can't chdir to new rootfs '%s'", __func__, NEWROOT); ++ goto fail; ++ } ++ ++ /* pivot_root into our new root fs */ ++ if (pivot_root(".", ".")) { ++ nih_fatal("%s: pivot_root syscall failed: %s", ++ __func__, strerror(errno)); ++ goto fail; ++ } ++ ++ /* ++ * at this point the old-root is mounted on top of our new-root ++ * To unmounted it we must not be chdir'd into it, so escape back ++ * to old-root ++ */ ++ if (fchdir(oldroot) < 0) { ++ nih_fatal("%s: Error entering oldroot", __func__); ++ goto fail; ++ } ++ if (umount2(".", MNT_DETACH) < 0) { ++ nih_fatal("%s: Error detaching old root", __func__); ++ goto fail; ++ } ++ ++ if (fchdir(newroot) < 0) { ++ nih_fatal("%s: Error re-entering newroot", __func__); ++ goto fail; ++ } ++ ++ close(oldroot); ++ close(newroot); ++ ++ return 0; ++ ++fail: ++ if (oldroot != -1) ++ close(oldroot); ++ if (newroot != -1) ++ close(newroot); ++ return -1; ++} ++ ++static int pivot_into_new_root(void) { ++ int i, ret; ++ char *createdirs[] = {NEWROOT "/proc", NEWROOT "/run", ++ NEWROOT "/run/cgmanager", NEWROOT "/run/cgmanager/fs", NULL}; ++ char path[100]; ++ ++ /* Mount tmpfs for new root */ ++ if (mkdir(NEWROOT, 0755) < 0 && errno != EEXIST) { ++ nih_fatal("%s: Failed to create directory for new root\n", __func__); ++ return -1; ++ } ++ ret = mount("root", NEWROOT, "tmpfs", 0, "size=10000,mode=0755"); ++ if (ret < 0) { ++ nih_fatal("%s: Failed to mount tmpfs for root", __func__); ++ return -1; ++ } ++ ++ /* create /proc and /run/cgmanager/fs, and move-mount those */ ++ for (i = 0; createdirs[i]; i++) { ++ if (mkdir(createdirs[i], 0755) < 0) { ++ nih_fatal("%s: failed to created %s\n", __func__, createdirs[i]); ++ return -1; ++ } ++ } ++ ++ ret = snprintf(path, 100, NEWROOT "/proc"); ++ if (ret < 0 || ret > 100) ++ return -1; ++ if (mount("/proc", path, NULL, MS_REC|MS_MOVE, 0) < 0) { ++ nih_fatal("%s: failed to move /proc into new root: %s", ++ __func__, strerror(errno)); ++ return -1; ++ } ++ ret = snprintf(path, 100, NEWROOT "/run/cgmanager/fs"); ++ if (ret < 0 || ret > 100) ++ return -1; ++ if (mount("/run/cgmanager/fs", path, NULL, MS_REC|MS_MOVE, 0) < 0) { ++ nih_fatal("%s: failed to move /run/cgmanager/fs into new root: %s", ++ __func__, strerror(errno)); ++ return -1; ++ } ++ ++ /* Pivot into new root */ ++ if (do_pivot() < 0) ++ return -1; ++ ++ return 0; ++} ++ + /** + * Mount the cgroup filesystems and record the information. + * This should take configuration data from /etc. For now, +@@ -789,8 +918,10 @@ int setup_cgroup_mounts(void) + return 0; + } + +- if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, 0) < 0) +- nih_warn("Failed to re-mount / non-shared"); ++ if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, 0) < 0) { ++ nih_warn("Failed to re-mount / private"); ++ return -1; ++ } + + for (i=0; i<num_controllers; i++) { + if (!do_mount_subsys(i)) { +@@ -799,6 +930,12 @@ int setup_cgroup_mounts(void) + } + } + ++ /* Now pivot into a new root */ ++ if (pivot_into_new_root() < 0) { ++ nih_fatal("Failed pivoting into new root"); ++ return -1; ++ } ++ + return 0; + } + diff -Nru cgmanager-0.33/debian/patches/series cgmanager-0.33/debian/patches/series --- cgmanager-0.33/debian/patches/series 2015-02-11 22:26:16.000000000 -0600 +++ cgmanager-0.33/debian/patches/series 2015-03-14 23:37:03.000000000 -0500 @@ -4,3 +4,6 @@ 0004-chown-stop-cgmanager-crash-on-chown-of-bad-file.patch 0005-prevent-some-cgmanager-asserts.patch 0006-fix-subdirectory-check +pivot-into-mostly-empty-nonroot +bind-mount-old-root.patch +bind-mount-run-from-host.patch -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: https://lists.debian.org/20150315051518.GA24404@ubuntumail

