by Serge E. H » Sat, 06 Jan 2007 04:50:10
uoting Frederik Deweerdt ( XXXX@XXXXX.COM ):
Ah, since I set it anyway, good point.
Yes it should.
New patch attached.
(I suppose the testcase should check for the CAP_SYS_ADMIN
error case...)
Thanks for the close review!
-serge
From: Serge E. Hallyn < XXXX@XXXXX.COM >
Subject: [PATCH 8/8] user ns: implement user ns unshare
Implement CLONE_NEWUSER flag useable at clone/unshare.
Changes:
Jan 4: return the actual error value in copy_user_ns().
Signed-off-by: Serge E. Hallyn < XXXX@XXXXX.COM >
---
include/linux/sched.h | 1 +
include/linux/user_namespace.h | 10 +++++
kernel/fork.c | 22 ++++++++++--
kernel/nsproxy.c | 2 +
kernel/user_namespace.c | 74 +++++++++++++++++++++++++++++++++++++++-
5 files changed, 102 insertions(+), 7 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 73df38c..55ecf81 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -26,6 +26,7 @@ #define CLONE_CHILD_SETTID 0x01000000 /*
#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
#define CLONE_NEWIPC 0x08000000 /* New ipcs */
+#define CLONE_NEWUSER 0x10000000 /* New user namespace */
/*
* Scheduling policies
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 4ad4c0d..d577ede 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -25,6 +25,7 @@ static inline struct user_namespace *get
}
extern int copy_user_ns(int flags, struct task_struct *tsk);
+extern int unshare_user_ns(unsigned long flags, struct user_namespace **new_user);
extern void free_user_ns(struct kref *kref);
static inline void put_user_ns(struct user_namespace *ns)
@@ -40,6 +41,15 @@ static inline struct user_namespace *get
return NULL;
}
+static inline int unshare_user_ns(unsigned long flags,
+ struct user_namespace **new_user)
+{
+ if (flags & CLONE_NEWUSER)
+ return -EINVAL;
+
+ return 0;
+}
+
static inline int copy_user_ns(int flags, struct task_struct *tsk)
{
return 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index deafa6e..eead517 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -49,6 +49,7 @@ #include <linux/cn_proc.h>
#include <linux/delayacct.h>
#include <linux/taskstats_kern.h>
#include <linux/random.h>
+#include <linux/user_namespace.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -1620,6 +1621,7 @@ asmlinkage long sys_unshare(unsigned lon
struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
struct uts_namespace *uts, *new_uts = NULL;
struct ipc_namespace *ipc, *new_ipc = NULL;
+ struct user_namespace *user, *new_user = NULL;
check_unshare_flags(&unshare_flags);
@@ -1627,7 +1629,7 @@ asmlinkage long sys_unshare(unsigned lon
err = -EINVAL;
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
- CLONE_NEWUTS|CLONE_NEWIPC))
+ CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER))
goto bad_unshare_out;
if ((err = unshare_thread(unshare_flags)))
@@ -1648,18 +1650,20 @@ asmlinkage long sys_unshare(unsigned lon
goto bad_unshare_cleanup_semundo;
if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
goto bad_unshare_cleanup_uts;
+ if ((err = unshare_user_ns(unshare_flags, &