diff --git a/src/core/namespace.c b/src/core/namespace.c index aed11c18ee6..d5b050fadc8 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -496,6 +496,40 @@ static void drop_outside_root(const char *root_directory, MountEntry *m, unsigne *n = t - m; } +static int clone_device_node(const char *d, const char *temporary_mount) +{ + _cleanup_free_ char *dn = NULL; + struct stat st; + int r; + + r = stat(d, &st); + if (r < 0) { + if (errno == ENOENT) + return 0; + return -errno; + } + + if (!S_ISBLK(st.st_mode) && + !S_ISCHR(st.st_mode)) + return -EINVAL; + + if (st.st_rdev == 0) + return 0; + + dn = strappend(temporary_mount, d); + if (!dn) + return -ENOMEM; + + mac_selinux_create_file_prepare(d, st.st_mode); + r = mknod(dn, st.st_mode, st.st_rdev); + mac_selinux_create_file_clear(); + + if (r < 0) + return -errno; + + return 0; +} + static int mount_private_dev(MountEntry *m) { static const char devnodes[] = "/dev/null\0" @@ -557,42 +591,9 @@ static int mount_private_dev(MountEntry *m) { (void) symlink("/run/systemd/journal/dev-log", devlog); NULSTR_FOREACH(d, devnodes) { - _cleanup_free_ char *dn = NULL; - struct stat st; - - r = stat(d, &st); - if (r < 0) { - - if (errno == ENOENT) - continue; - - r = -errno; + r = clone_device_node(d, temporary_mount); + if (r < 0) goto fail; - } - - if (!S_ISBLK(st.st_mode) && - !S_ISCHR(st.st_mode)) { - r = -EINVAL; - goto fail; - } - - if (st.st_rdev == 0) - continue; - - dn = strappend(temporary_mount, d); - if (!dn) { - r = -ENOMEM; - goto fail; - } - - mac_selinux_create_file_prepare(d, st.st_mode); - r = mknod(dn, st.st_mode, st.st_rdev); - mac_selinux_create_file_clear(); - - if (r < 0) { - r = -errno; - goto fail; - } } dev_setup(temporary_mount, UID_INVALID, GID_INVALID);