Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 142e1d1d authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

userns: Allow unprivileged use of setns.



- Push the permission check from the core setns syscall into
  the setns install methods where the user namespace of the
  target namespace can be determined, and used in a ns_capable
  call.

Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent b33c77ef
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -161,8 +161,12 @@ static void ipcns_put(void *ns)
	return put_ipc_ns(ns);
}

static int ipcns_install(struct nsproxy *nsproxy, void *ns)
static int ipcns_install(struct nsproxy *nsproxy, void *new)
{
	struct ipc_namespace *ns = new;
	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
		return -EPERM;

	/* Ditch state from the old ipc namespace */
	exit_sem(current);
	put_ipc_ns(nsproxy->ipc_ns);
+0 −3
Original line number Diff line number Diff line
@@ -242,9 +242,6 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
	struct file *file;
	int err;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	file = proc_ns_fget(fd);
	if (IS_ERR(file))
		return PTR_ERR(file);
+6 −1
Original line number Diff line number Diff line
@@ -102,8 +102,13 @@ static void utsns_put(void *ns)
	put_uts_ns(ns);
}

static int utsns_install(struct nsproxy *nsproxy, void *ns)
static int utsns_install(struct nsproxy *nsproxy, void *new)
{
	struct uts_namespace *ns = new;

	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
		return -EPERM;

	get_uts_ns(ns);
	put_uts_ns(nsproxy->uts_ns);
	nsproxy->uts_ns = ns;
+6 −1
Original line number Diff line number Diff line
@@ -630,8 +630,13 @@ static void netns_put(void *ns)

static int netns_install(struct nsproxy *nsproxy, void *ns)
{
	struct net *net = ns;

	if (!ns_capable(net->user_ns, CAP_SYS_ADMIN))
		return -EPERM;

	put_net(nsproxy->net_ns);
	nsproxy->net_ns = get_net(ns);
	nsproxy->net_ns = get_net(net);
	return 0;
}