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

Commit acce292c authored by Cedric Le Goater's avatar Cedric Le Goater Committed by Linus Torvalds
Browse files

user namespace: add the framework



Basically, it will allow a process to unshare its user_struct table,
resetting at the same time its own user_struct and all the associated
accounting.

A new root user (uid == 0) is added to the user namespace upon creation.
Such root users have full privileges and it seems that theses privileges
should be controlled through some means (process capabilities ?)

The unshare is not included in this patch.

Changes since [try #4]:
	- Updated get_user_ns and put_user_ns to accept NULL, and
	  get_user_ns to return the namespace.

Changes since [try #3]:
	- moved struct user_namespace to files user_namespace.{c,h}

Changes since [try #2]:
	- removed struct user_namespace* argument from find_user()

Changes since [try #1]:
	- removed struct user_namespace* argument from find_user()
	- added a root_user per user namespace

Signed-off-by: default avatarCedric Le Goater <clg@fr.ibm.com>
Signed-off-by: default avatarSerge E. Hallyn <serue@us.ibm.com>
Acked-by: default avatarPavel Emelianov <xemul@openvz.org>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: Kirill Korotaev <dev@sw.ru>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: James Morris <jmorris@namei.org>
Cc: Andrew Morgan <agm@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7d69a1f4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/lockdep.h>
#include <linux/ipc.h>
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>

#define INIT_FDTABLE \
{							\
@@ -78,6 +79,7 @@ extern struct nsproxy init_nsproxy;
	.uts_ns		= &init_uts_ns,					\
	.mnt_ns		= NULL,						\
	INIT_IPC_NS(ipc_ns)						\
	.user_ns	= &init_user_ns,				\
}

#define INIT_SIGHAND(sighand) {						\
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct nsproxy {
	struct ipc_namespace *ipc_ns;
	struct mnt_namespace *mnt_ns;
	struct pid_namespace *pid_ns;
	struct user_namespace *user_ns;
};
extern struct nsproxy init_nsproxy;

+2 −1
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ extern signed long schedule_timeout_uninterruptible(signed long timeout);
asmlinkage void schedule(void);

struct nsproxy;
struct user_namespace;

/* Maximum number of active map areas.. This is a random (large) number */
#define DEFAULT_MAX_MAP_COUNT	65536
@@ -1408,7 +1409,7 @@ extern struct task_struct *find_task_by_pid_type(int type, int pid);
extern void __set_special_pids(pid_t session, pid_t pgrp);

/* per-UID process charging. */
extern struct user_struct * alloc_uid(uid_t);
extern struct user_struct * alloc_uid(struct user_namespace *, uid_t);
static inline struct user_struct *get_uid(struct user_struct *u)
{
	atomic_inc(&u->__count);
+57 −0
Original line number Diff line number Diff line
#ifndef _LINUX_USER_NAMESPACE_H
#define _LINUX_USER_NAMESPACE_H

#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <linux/sched.h>

#define UIDHASH_BITS	(CONFIG_BASE_SMALL ? 3 : 8)
#define UIDHASH_SZ	(1 << UIDHASH_BITS)

struct user_namespace {
	struct kref		kref;
	struct list_head	uidhash_table[UIDHASH_SZ];
	struct user_struct	*root_user;
};

extern struct user_namespace init_user_ns;

#ifdef CONFIG_USER_NS

static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
	if (ns)
		kref_get(&ns->kref);
	return ns;
}

extern struct user_namespace *copy_user_ns(int flags,
					   struct user_namespace *old_ns);
extern void free_user_ns(struct kref *kref);

static inline void put_user_ns(struct user_namespace *ns)
{
	if (ns)
		kref_put(&ns->kref, free_user_ns);
}

#else

static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
	return &init_user_ns;
}

static inline struct user_namespace *copy_user_ns(int flags,
						  struct user_namespace *old_ns)
{
	return NULL;
}

static inline void put_user_ns(struct user_namespace *ns)
{
}

#endif

#endif /* _LINUX_USER_H */
+9 −0
Original line number Diff line number Diff line
@@ -209,6 +209,15 @@ config TASK_IO_ACCOUNTING

	  Say N if unsure.

config USER_NS
	bool "User Namespaces (EXPERIMENTAL)"
	default n
	depends on EXPERIMENTAL
	help
	  Support user namespaces.  This allows containers, i.e.
	  vservers, to use user namespaces to provide different
	  user info for different servers.  If unsure, say N.

config AUDIT
	bool "Auditing support"
	depends on NET
Loading