Use bind mounts instead of mknod

Instead of creating real device nodes we just bind mount the system
ones. This means that we require no mknod capabilities, which is good
in itself, but it also allows us to eventually run completely
unprivileged with user namespaces.
tingping/wmclass
Alexander Larsson 2015-02-19 14:16:36 +01:00
parent 6584ba71e3
commit cf2a39fe84
2 changed files with 20 additions and 18 deletions

View File

@ -104,7 +104,7 @@ if PRIV_MODE_SETUID
$(SUDO_BIN) chmod u+s $(DESTDIR)$(bindir)/xdg-app-helper
else
if PRIV_MODE_FILECAPS
$(SUDO_BIN) setcap cap_sys_admin,cap_mknod+ep $(DESTDIR)$(bindir)/xdg-app-helper
$(SUDO_BIN) setcap cap_sys_admin+ep $(DESTDIR)$(bindir)/xdg-app-helper
endif
endif

View File

@ -332,12 +332,12 @@ static const create_table_t create[] = {
{ FILE_TYPE_MOUNT, "dev/pts"},
{ FILE_TYPE_DIR, "dev/shm", 0755},
{ FILE_TYPE_SHM, "dev/shm"},
{ FILE_TYPE_DEVICE, "dev/null", S_IFCHR|0666, "/dev/null"},
{ FILE_TYPE_DEVICE, "dev/zero", S_IFCHR|0666, "/dev/zero"},
{ FILE_TYPE_DEVICE, "dev/full", S_IFCHR|0666, "/dev/full"},
{ FILE_TYPE_DEVICE, "dev/random", S_IFCHR|0666, "/dev/random"},
{ FILE_TYPE_DEVICE, "dev/urandom", S_IFCHR|0666, "/dev/urandom"},
{ FILE_TYPE_DEVICE, "dev/tty", S_IFCHR|0666, "/dev/tty"},
{ FILE_TYPE_DEVICE, "dev/null", 0666},
{ FILE_TYPE_DEVICE, "dev/zero", 0666},
{ FILE_TYPE_DEVICE, "dev/full", 0666},
{ FILE_TYPE_DEVICE, "dev/random", 0666},
{ FILE_TYPE_DEVICE, "dev/urandom", 0666},
{ FILE_TYPE_DEVICE, "dev/tty", 0666},
{ FILE_TYPE_DIR, "dev/dri", 0755},
{ FILE_TYPE_BIND_RO, "dev/dri", 0755, "/dev/dri", FILE_FLAGS_NON_FATAL|FILE_FLAGS_DEVICES},
{ FILE_TYPE_REMOUNT, "dev", MS_RDONLY|MS_NOSUID|MS_NOEXEC},
@ -553,7 +553,7 @@ create_files (const create_table_t *create, int n_create, int ignore_shm, int sy
mode_t mode = create[i].mode;
file_flags_t flags = create[i].flags;
int *option = create[i].option;
struct stat st;
char *in_root;
int k;
int found;
int res;
@ -586,9 +586,8 @@ create_files (const create_table_t *create, int n_create, int ignore_shm, int sy
case FILE_TYPE_SYSTEM_SYMLINK:
if (system_mode)
{
char *in_root = strconcat ("/", name);
struct stat buf;
in_root = strconcat ("/", name);
if (stat (in_root, &buf) == 0)
{
if (mkdir (name, mode) != 0)
@ -661,14 +660,17 @@ create_files (const create_table_t *create, int n_create, int ignore_shm, int sy
break;
case FILE_TYPE_DEVICE:
if (stat (data, &st) < 0)
die_with_error ("stat node %s", data);
if (create_file (name, mode, NULL))
die_with_error ("creating file %s", name);
if (!S_ISCHR (st.st_mode) && !S_ISBLK (st.st_mode))
die_with_error ("node %s is not a device", data);
if (mknod (name, mode, st.st_rdev) < 0)
die_with_error ("mknod %s", name);
in_root = strconcat ("/", name);
if ((res = bind_mount (in_root, name,
BIND_DEVICES)))
{
if (res > 1 || (flags & FILE_FLAGS_NON_FATAL) == 0)
die_with_error ("binding device %s", name);
}
free (in_root);
break;
@ -1075,7 +1077,7 @@ do_init (int event_fd, pid_t initial_pid)
return initial_exit_status;
}
#define REQUIRED_CAPS (CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_MKNOD))
#define REQUIRED_CAPS (CAP_TO_MASK(CAP_SYS_ADMIN))
static void
acquire_caps (void)