trace: use standard POSIX header for basename()
[project/procd.git] / jail / fs.c
index f70a751fa1a2813bd905a89bedeba70f332b28d0..423878b3398f1424ec823a75882de99e874243d6 100644 (file)
--- a/jail/fs.c
+++ b/jail/fs.c
@@ -61,20 +61,22 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
        struct stat s;
        char new[PATH_MAX];
        char *source = (char *)orig_source;
-       int fd;
+       int fd, ret = 0;
        bool is_bind = (orig_mountflags & MS_BIND);
        bool is_mask = (source == (void *)(-1));
        unsigned long mountflags = orig_mountflags;
 
+       assert(!(inner && is_mask));
+       assert(!(inner && !orig_source));
+
        if (source && is_bind && stat(source, &s)) {
                ERROR("stat(%s) failed: %m\n", source);
                return error;
        }
 
-       if (!is_mask && orig_source && inner) {
+       if (inner)
                if (asprintf(&source, "%s%s", root, orig_source) < 0)
                        return ENOMEM;
-       }
 
        snprintf(new, sizeof(new), "%s%s", root, target?target:source);
 
@@ -83,7 +85,7 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                        return 0; /* doesn't exists, nothing to mask */
 
                if (S_ISDIR(s.st_mode)) {/* use empty 0-sized tmpfs for directories */
-                       if (mount(NULL, new, "tmpfs", MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, "size=0,mode=000"))
+                       if (mount("none", new, "tmpfs", MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, "size=0,mode=000"))
                                return error;
                } else {
                        /* mount-bind 0-sized file having mode 000 */
@@ -104,12 +106,16 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
        } else if (is_bind && source) {
                mkdir_p(dirname(new), 0755);
                snprintf(new, sizeof(new), "%s%s", root, target?target:source);
-               fd = creat(new, 0644);
-               if (fd == -1) {
-                       ERROR("creat(%s) failed: %m\n", new);
-                       return error;
+               fd = open(new, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0644);
+               if (fd >= 0)
+                       close(fd);
+
+               if (error && fd < 0 && errno != EEXIST) {
+                       ERROR("failed to create mount target %s: %m\n", new);
+
+                       ret = errno;
+                       goto free_source_out;
                }
-               close(fd);
        }
 
        if (is_bind) {
@@ -117,10 +123,8 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                        if (error)
                                ERROR("failed to mount -B %s %s: %m\n", source, new);
 
-                       if (inner)
-                               free(source);
-
-                       return error;
+                       ret = error;
+                       goto free_source_out;
                }
                mountflags |= MS_REMOUNT;
        }
@@ -130,10 +134,8 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                if (error)
                        ERROR("failed to mount %s %s: %m\n", source, new);
 
-               if (inner)
-                       free(source);
-
-               return error;
+               ret = error;
+               goto free_source_out;
        }
 
        DEBUG("mount %s%s %s (%s)\n", (mountflags & MS_BIND)?"-B ":"", source, new,
@@ -143,16 +145,14 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                if (error)
                        ERROR("failed to mount --make-... %s \n", new);
 
-               if (inner)
-                       free(source);
-
-               return error;
+               ret = error;
        }
 
+free_source_out:
        if (inner)
                free(source);
 
-       return 0;
+       return ret;
 }
 
 static int _add_mount(const char *source, const char *target, const char *filesystemtype,
@@ -206,14 +206,19 @@ int add_mount_inner(const char *source, const char *target, const char *filesyst
        return _add_mount(source, target, filesystemtype, mountflags, propflags, optstr, error, true);
 }
 
-int add_mount_bind(const char *path, int readonly, int error)
+static int _add_mount_bind(const char *path, const char *path2, int readonly, int error)
 {
        unsigned long mountflags = MS_BIND;
 
        if (readonly)
                mountflags |= MS_RDONLY;
 
-       return add_mount(path, path, NULL, mountflags, 0, NULL, error);
+       return add_mount(path, path2, NULL, mountflags, 0, NULL, error);
+}
+
+int add_mount_bind(const char *path, int readonly, int error)
+{
+       return _add_mount_bind(path, path, readonly, error);
 }
 
 enum {
@@ -357,7 +362,7 @@ static int parseOCImountopts(struct blob_attr *msg, unsigned long *mount_flags,
 
        if (len) {
                *mount_data = calloc(len + 1, sizeof(char));
-               if (!mount_data)
+               if (!(*mount_data))
                        return ENOMEM;
 
                len = 0;
@@ -414,7 +419,7 @@ static void build_noafile(void) {
        int fd;
 
        fd = creat(UJAIL_NOAFILE, 0000);
-       if (fd == -1)
+       if (fd < 0)
                return;
 
        close(fd);
@@ -478,9 +483,10 @@ static int add_script_interp(const char *path, const char *map, int size)
        return add_path_and_deps(buf, 1, -1, 0);
 }
 
-int add_path_and_deps(const char *path, int readonly, int error, int lib)
+int add_2paths_and_deps(const char *path, const char *path2, int readonly, int error, int lib)
 {
        assert(path != NULL);
+       assert(path2 != NULL);
 
        if (lib == 0 && path[0] != '/') {
                ERROR("%s is not an absolute path\n", path);
@@ -490,18 +496,18 @@ int add_path_and_deps(const char *path, int readonly, int error, int lib)
        char *map = NULL;
        int fd, ret = -1;
        if (path[0] == '/') {
-               if (avl_find(&mounts, path))
+               if (avl_find(&mounts, path2))
                        return 0;
                fd = open(path, O_RDONLY|O_CLOEXEC);
-               if (fd == -1)
+               if (fd < 0)
                        return error;
-               add_mount_bind(path, readonly, error);
+               _add_mount_bind(path, path2, readonly, error);
        } else {
                if (avl_find(&libraries, path))
                        return 0;
                char *fullpath;
                fd = lib_open(&fullpath, path);
-               if (fd == -1)
+               if (fd < 0)
                        return error;
                if (fullpath) {
                        alloc_library(fullpath, path);