From 9bd1b7f0951ec2bcf56674fa729af3872b276057 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 18 Jul 2021 02:10:29 +0100 Subject: [PATCH] jail: refactor directory handling for rootfs and overlaydir Resolve symlinks and check if directories exist before clone() call, it's more clean and allows for more code reuse. This partially reverts commits 0114c6fc8b ("jail: open() extroot folder before mounting") as well as 05459054fb ("jail: make use of realpath() for rootfs and overlaydir") and replaces them with a more generic solution. Signed-off-by: Daniel Golle --- jail/jail.c | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/jail/jail.c b/jail/jail.c index e6c9081..5a31e93 100644 --- a/jail/jail.c +++ b/jail/jail.c @@ -270,6 +270,8 @@ static void free_opts(bool parent) { free(opts.uidmap); free(opts.gidmap); free(opts.annotations); + free(opts.extroot); + free(opts.overlaydir); free_hooklist(opts.hooks.createRuntime); free_hooklist(opts.hooks.createContainer); free_hooklist(opts.hooks.startContainer); @@ -642,14 +644,6 @@ static int build_jail_fs(void) } if (opts.extroot) { - /* use open() to trigger autofs mount */ - DEBUG("mounting extroot from %s\n", opts.extroot); - int rootdirfd = open(opts.extroot, O_RDONLY | O_DIRECTORY); - if (rootdirfd == -1) { - ERROR("extroot %s open failed %m\n", opts.extroot); - return -1; - } - close(rootdirfd); if (mount(opts.extroot, jail_root, "bind", MS_BIND, NULL)) { ERROR("extroot mount failed %m\n"); return -1; @@ -675,20 +669,14 @@ static int build_jail_fs(void) ERROR("failed to mount tmpfs for overlay (size=%s)\n", opts.tmpoverlaysize); return -1; } - overlaydir = strdup(tmpovdir); - if (!overlaydir) - return -1; + overlaydir = tmpovdir; } - if (opts.overlaydir) { - overlaydir = realpath(opts.overlaydir, NULL); - if (!overlaydir) - return errno; - } + if (opts.overlaydir) + overlaydir = opts.overlaydir; if (overlaydir) { ret = mount_overlay(jail_root, overlaydir); - free(overlaydir); if (ret) return ret; } @@ -2429,6 +2417,18 @@ jail_writepid(pid_t pid) return 0; } +static int checkpath(const char *path) +{ + int dirfd = open(path, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (dirfd == -1) { + ERROR("path %s open failed %m\n", path); + return -1; + } + close(dirfd); + + return 0; +} + static struct ubus_method container_methods[] = { UBUS_METHOD_NOARG("start", handle_start), UBUS_METHOD_NOARG("state", handle_state), @@ -2492,7 +2492,7 @@ int main(int argc, char **argv) opts.namespace |= CLONE_NEWCGROUP; break; case 'R': - opts.extroot = optarg; + opts.extroot = realpath(optarg, NULL); break; case 's': opts.namespace |= CLONE_NEWNS; @@ -2541,7 +2541,7 @@ int main(int argc, char **argv) opts.group = optarg; break; case 'O': - opts.overlaydir = optarg; + opts.overlaydir = realpath(optarg, NULL); break; case 'T': opts.tmpoverlaysize = optarg; @@ -2628,6 +2628,18 @@ int main(int argc, char **argv) goto errout; } + if (opts.extroot && checkpath(opts.extroot)) { + ERROR("invalid rootfs path '%s'", opts.extroot); + ret=-1; + goto errout; + } + + if (opts.overlaydir && checkpath(opts.overlaydir)) { + ERROR("invalid rootfs overlay path '%s'", opts.overlaydir); + ret=-1; + goto errout; + } + /* no param found */ if (!opts.ocibundle && (argc - optind < 1)) { usage(); -- 2.30.2