]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
jail: Try bind-mounting device nodes when we cannot use mknod()
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 15:30:28 +0000 (15:30 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 15:30:28 +0000 (15:30 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/util.h
src/libpakfire/mount.c
src/libpakfire/util.c

index fc99f820028ebca079b49e6bc9d2cf076437a8f0..4044bd2d2d0fea741f56a1ce4e22e586b6e8f108 100644 (file)
@@ -83,6 +83,7 @@ int __pakfire_path_join(char* dest, size_t length,
        const char* first, const char* second);
 const char* pakfire_path_relpath(const char* root, const char* path);
 
+int pakfire_touch(const char* path, mode_t mode);
 int pakfire_mkparentdir(const char* path, mode_t mode);
 int pakfire_mkdir(const char* path, mode_t mode);
 FILE* pakfire_mktemp(char* path);
index ae87aa660cd1617850979c1a854a79f36d514617..bff245f97ab70a42fa32247ac16a23160ec1ab1a 100644 (file)
@@ -239,10 +239,33 @@ static int pakfire_populate_dev(struct pakfire* pakfire) {
                dev_t dev = makedev(devnode->major, devnode->minor);
 
                r = mknod(path, devnode->mode, dev);
+
+               // Continue if mknod was successful
+               if (r == 0)
+                       continue;
+
+               // If we could not create the device node because of permission issues,
+               // it might be likely that we are running in a user namespace where creating
+               // device nodes is not permitted. Try bind-mounting them.
+               if (errno == EPERM)
+                       goto MOUNT;
+
+               // Otherwise log an error and end
+               ERROR(pakfire, "Could not create %s: %m\n", devnode->path);
+               return r;
+
+MOUNT:
+               // Create an empty file
+               r = pakfire_touch(path, 0444);
                if (r) {
-                       ERROR(pakfire, "Could not create %s: %m\n", devnode->path);
+                       ERROR(pakfire, "Could not create %s: %m\n", path);
                        return r;
                }
+
+               // Create a bind-mount over the file
+               r = pakfire_mount(pakfire, path, devnode->path, "bind", MS_BIND, NULL);
+               if (r)
+                       return r;
        }
 
        // Create symlinks
index 83f0b8608887e0bdf4ef8109689c2ae011b4a8d2..baf4c3020075422c5d7a458a8ddde93d1e936b2d 100644 (file)
@@ -930,6 +930,14 @@ int __pakfire_unhexlify(unsigned char* dst, const size_t l, const char* src) {
        return 0;
 }
 
+int pakfire_touch(const char* path, mode_t mode) {
+       FILE* f = fopen(path, "w");
+       if (!f)
+               return 1;
+
+       return fclose(f);
+}
+
 int pakfire_mkparentdir(const char* path, mode_t mode) {
        int r;