Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
3496f92b
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3496f92b
编写于
16年前
作者:
J
James Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'serge-next' into next
上级
200036ca
6ded6ab9
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
96 addition
and
129 deletion
+96
-129
fs/ecryptfs/messaging.c
fs/ecryptfs/messaging.c
+6
-7
fs/ecryptfs/miscdev.c
fs/ecryptfs/miscdev.c
+7
-12
include/linux/cred.h
include/linux/cred.h
+2
-0
include/linux/init_task.h
include/linux/init_task.h
+0
-1
include/linux/nsproxy.h
include/linux/nsproxy.h
+0
-1
include/linux/sched.h
include/linux/sched.h
+1
-0
include/linux/user_namespace.h
include/linux/user_namespace.h
+4
-9
kernel/cred.c
kernel/cred.c
+13
-2
kernel/fork.c
kernel/fork.c
+16
-3
kernel/nsproxy.c
kernel/nsproxy.c
+2
-13
kernel/sys.c
kernel/sys.c
+2
-2
kernel/user.c
kernel/user.c
+13
-34
kernel/user_namespace.c
kernel/user_namespace.c
+30
-45
未找到文件。
fs/ecryptfs/messaging.c
浏览文件 @
3496f92b
...
...
@@ -360,7 +360,7 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
struct
ecryptfs_msg_ctx
*
msg_ctx
;
size_t
msg_size
;
struct
nsproxy
*
nsproxy
;
struct
user_namespace
*
current
_user_ns
;
struct
user_namespace
*
tsk
_user_ns
;
uid_t
ctx_euid
;
int
rc
;
...
...
@@ -385,9 +385,9 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
mutex_unlock
(
&
ecryptfs_daemon_hash_mux
);
goto
wake_up
;
}
current_user_ns
=
nsproxy
->
user_ns
;
tsk_user_ns
=
__task_cred
(
msg_ctx
->
task
)
->
user
->
user_ns
;
ctx_euid
=
task_euid
(
msg_ctx
->
task
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
ctx_euid
,
current
_user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
ctx_euid
,
tsk
_user_ns
);
rcu_read_unlock
();
mutex_unlock
(
&
ecryptfs_daemon_hash_mux
);
if
(
rc
)
{
...
...
@@ -405,11 +405,11 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
euid
,
ctx_euid
);
goto
unlock
;
}
if
(
current
_user_ns
!=
user_ns
)
{
if
(
tsk
_user_ns
!=
user_ns
)
{
rc
=
-
EBADMSG
;
printk
(
KERN_WARNING
"%s: Received message from user_ns "
"[0x%p]; expected message from user_ns [0x%p]
\n
"
,
__func__
,
user_ns
,
nsproxy
->
user_ns
);
__func__
,
user_ns
,
tsk_
user_ns
);
goto
unlock
;
}
if
(
daemon
->
pid
!=
pid
)
{
...
...
@@ -468,8 +468,7 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
uid_t
euid
=
current_euid
();
int
rc
;
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current_user_ns
());
if
(
rc
||
!
daemon
)
{
rc
=
-
ENOTCONN
;
printk
(
KERN_ERR
"%s: User [%d] does not have a daemon "
...
...
This diff is collapsed.
Click to expand it.
fs/ecryptfs/miscdev.c
浏览文件 @
3496f92b
...
...
@@ -47,8 +47,7 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
mutex_lock
(
&
ecryptfs_daemon_hash_mux
);
/* TODO: Just use file->private_data? */
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current_user_ns
());
BUG_ON
(
rc
||
!
daemon
);
mutex_lock
(
&
daemon
->
mux
);
mutex_unlock
(
&
ecryptfs_daemon_hash_mux
);
...
...
@@ -95,11 +94,9 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
"count; rc = [%d]
\n
"
,
__func__
,
rc
);
goto
out_unlock_daemon_list
;
}
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current_user_ns
());
if
(
rc
||
!
daemon
)
{
rc
=
ecryptfs_spawn_daemon
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
,
rc
=
ecryptfs_spawn_daemon
(
&
daemon
,
euid
,
current_user_ns
(),
task_pid
(
current
));
if
(
rc
)
{
printk
(
KERN_ERR
"%s: Error attempting to spawn daemon; "
...
...
@@ -153,8 +150,7 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file)
int
rc
;
mutex_lock
(
&
ecryptfs_daemon_hash_mux
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current_user_ns
());
BUG_ON
(
rc
||
!
daemon
);
mutex_lock
(
&
daemon
->
mux
);
BUG_ON
(
daemon
->
pid
!=
task_pid
(
current
));
...
...
@@ -254,8 +250,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
mutex_lock
(
&
ecryptfs_daemon_hash_mux
);
/* TODO: Just use file->private_data? */
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current
->
nsproxy
->
user_ns
);
rc
=
ecryptfs_find_daemon_by_euid
(
&
daemon
,
euid
,
current_user_ns
());
BUG_ON
(
rc
||
!
daemon
);
mutex_lock
(
&
daemon
->
mux
);
if
(
daemon
->
flags
&
ECRYPTFS_DAEMON_ZOMBIE
)
{
...
...
@@ -295,7 +290,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
goto
check_list
;
}
BUG_ON
(
euid
!=
daemon
->
euid
);
BUG_ON
(
current
->
nsproxy
->
user_ns
!=
daemon
->
user_ns
);
BUG_ON
(
current
_user_ns
()
!=
daemon
->
user_ns
);
BUG_ON
(
task_pid
(
current
)
!=
daemon
->
pid
);
msg_ctx
=
list_first_entry
(
&
daemon
->
msg_ctx_out_queue
,
struct
ecryptfs_msg_ctx
,
daemon_out_list
);
...
...
@@ -468,7 +463,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
goto
out_free
;
}
rc
=
ecryptfs_miscdev_response
(
&
data
[
i
],
packet_size
,
euid
,
current
->
nsproxy
->
user_ns
,
euid
,
current
_user_ns
()
,
task_pid
(
current
),
seq
);
if
(
rc
)
printk
(
KERN_WARNING
"%s: Failed to deliver miscdev "
...
...
This diff is collapsed.
Click to expand it.
include/linux/cred.h
浏览文件 @
3496f92b
...
...
@@ -60,6 +60,7 @@ do { \
} while (0)
extern
struct
group_info
*
groups_alloc
(
int
);
extern
struct
group_info
init_groups
;
extern
void
groups_free
(
struct
group_info
*
);
extern
int
set_current_groups
(
struct
group_info
*
);
extern
int
set_groups
(
struct
cred
*
,
struct
group_info
*
);
...
...
@@ -315,6 +316,7 @@ static inline void put_cred(const struct cred *_cred)
#define current_fsgid() (current_cred_xxx(fsgid))
#define current_cap() (current_cred_xxx(cap_effective))
#define current_user() (current_cred_xxx(user))
#define current_user_ns() (current_cred_xxx(user)->user_ns)
#define current_security() (current_cred_xxx(security))
#define current_uid_gid(_uid, _gid) \
...
...
This diff is collapsed.
Click to expand it.
include/linux/init_task.h
浏览文件 @
3496f92b
...
...
@@ -57,7 +57,6 @@ extern struct nsproxy init_nsproxy;
.mnt_ns = NULL, \
INIT_NET_NS(net_ns) \
INIT_IPC_NS(ipc_ns) \
.user_ns = &init_user_ns, \
}
#define INIT_SIGHAND(sighand) { \
...
...
This diff is collapsed.
Click to expand it.
include/linux/nsproxy.h
浏览文件 @
3496f92b
...
...
@@ -27,7 +27,6 @@ struct nsproxy {
struct
ipc_namespace
*
ipc_ns
;
struct
mnt_namespace
*
mnt_ns
;
struct
pid_namespace
*
pid_ns
;
struct
user_namespace
*
user_ns
;
struct
net
*
net_ns
;
};
extern
struct
nsproxy
init_nsproxy
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/sched.h
浏览文件 @
3496f92b
...
...
@@ -638,6 +638,7 @@ struct user_struct {
/* Hash table maintenance information */
struct
hlist_node
uidhash_node
;
uid_t
uid
;
struct
user_namespace
*
user_ns
;
#ifdef CONFIG_USER_SCHED
struct
task_group
*
tg
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/user_namespace.h
浏览文件 @
3496f92b
...
...
@@ -12,7 +12,7 @@
struct
user_namespace
{
struct
kref
kref
;
struct
hlist_head
uidhash_table
[
UIDHASH_SZ
];
struct
user_struct
*
root_use
r
;
struct
user_struct
*
creato
r
;
};
extern
struct
user_namespace
init_user_ns
;
...
...
@@ -26,8 +26,7 @@ static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
return
ns
;
}
extern
struct
user_namespace
*
copy_user_ns
(
int
flags
,
struct
user_namespace
*
old_ns
);
extern
int
create_user_ns
(
struct
cred
*
new
);
extern
void
free_user_ns
(
struct
kref
*
kref
);
static
inline
void
put_user_ns
(
struct
user_namespace
*
ns
)
...
...
@@ -43,13 +42,9 @@ 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
)
static
inline
int
create_user_ns
(
struct
cred
*
new
)
{
if
(
flags
&
CLONE_NEWUSER
)
return
ERR_PTR
(
-
EINVAL
);
return
old_ns
;
return
-
EINVAL
;
}
static
inline
void
put_user_ns
(
struct
user_namespace
*
ns
)
...
...
This diff is collapsed.
Click to expand it.
kernel/cred.c
浏览文件 @
3496f92b
...
...
@@ -274,6 +274,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
struct
thread_group_cred
*
tgcred
;
#endif
struct
cred
*
new
;
int
ret
;
mutex_init
(
&
p
->
cred_exec_mutex
);
...
...
@@ -293,6 +294,12 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
if
(
!
new
)
return
-
ENOMEM
;
if
(
clone_flags
&
CLONE_NEWUSER
)
{
ret
=
create_user_ns
(
new
);
if
(
ret
<
0
)
goto
error_put
;
}
#ifdef CONFIG_KEYS
/* new threads get their own thread keyrings if their parent already
* had one */
...
...
@@ -309,8 +316,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
if
(
!
(
clone_flags
&
CLONE_THREAD
))
{
tgcred
=
kmalloc
(
sizeof
(
*
tgcred
),
GFP_KERNEL
);
if
(
!
tgcred
)
{
put_cred
(
new
)
;
return
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
error_put
;
}
atomic_set
(
&
tgcred
->
usage
,
1
);
spin_lock_init
(
&
tgcred
->
lock
);
...
...
@@ -325,6 +332,10 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
atomic_inc
(
&
new
->
user
->
processes
);
p
->
cred
=
p
->
real_cred
=
get_cred
(
new
);
return
0
;
error_put:
put_cred
(
new
);
return
ret
;
}
/**
...
...
This diff is collapsed.
Click to expand it.
kernel/fork.c
浏览文件 @
3496f92b
...
...
@@ -976,7 +976,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if
(
atomic_read
(
&
p
->
real_cred
->
user
->
processes
)
>=
p
->
signal
->
rlim
[
RLIMIT_NPROC
].
rlim_cur
)
{
if
(
!
capable
(
CAP_SYS_ADMIN
)
&&
!
capable
(
CAP_SYS_RESOURCE
)
&&
p
->
real_cred
->
user
!=
current
->
nsproxy
->
user_ns
->
root_user
)
p
->
real_cred
->
user
!=
INIT_USER
)
goto
bad_fork_free
;
}
...
...
@@ -1334,6 +1334,20 @@ long do_fork(unsigned long clone_flags,
int
trace
=
0
;
long
nr
;
/*
* Do some preliminary argument and permissions checking before we
* actually start allocating stuff
*/
if
(
clone_flags
&
CLONE_NEWUSER
)
{
if
(
clone_flags
&
CLONE_THREAD
)
return
-
EINVAL
;
/* hopefully this check will go away when userns support is
* complete
*/
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
}
/*
* We hope to recycle these flags after 2.6.26
*/
...
...
@@ -1581,8 +1595,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
err
=
-
EINVAL
;
if
(
unshare_flags
&
~
(
CLONE_THREAD
|
CLONE_FS
|
CLONE_NEWNS
|
CLONE_SIGHAND
|
CLONE_VM
|
CLONE_FILES
|
CLONE_SYSVSEM
|
CLONE_NEWUTS
|
CLONE_NEWIPC
|
CLONE_NEWUSER
|
CLONE_NEWNET
))
CLONE_NEWUTS
|
CLONE_NEWIPC
|
CLONE_NEWNET
))
goto
bad_unshare_out
;
/*
...
...
This diff is collapsed.
Click to expand it.
kernel/nsproxy.c
浏览文件 @
3496f92b
...
...
@@ -80,12 +80,6 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
goto
out_pid
;
}
new_nsp
->
user_ns
=
copy_user_ns
(
flags
,
tsk
->
nsproxy
->
user_ns
);
if
(
IS_ERR
(
new_nsp
->
user_ns
))
{
err
=
PTR_ERR
(
new_nsp
->
user_ns
);
goto
out_user
;
}
new_nsp
->
net_ns
=
copy_net_ns
(
flags
,
tsk
->
nsproxy
->
net_ns
);
if
(
IS_ERR
(
new_nsp
->
net_ns
))
{
err
=
PTR_ERR
(
new_nsp
->
net_ns
);
...
...
@@ -95,9 +89,6 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
return
new_nsp
;
out_net:
if
(
new_nsp
->
user_ns
)
put_user_ns
(
new_nsp
->
user_ns
);
out_user:
if
(
new_nsp
->
pid_ns
)
put_pid_ns
(
new_nsp
->
pid_ns
);
out_pid:
...
...
@@ -130,7 +121,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
get_nsproxy
(
old_ns
);
if
(
!
(
flags
&
(
CLONE_NEWNS
|
CLONE_NEWUTS
|
CLONE_NEWIPC
|
CLONE_NEW
USER
|
CLONE_NEW
PID
|
CLONE_NEWNET
)))
CLONE_NEWPID
|
CLONE_NEWNET
)))
return
0
;
if
(
!
capable
(
CAP_SYS_ADMIN
))
{
...
...
@@ -173,8 +164,6 @@ void free_nsproxy(struct nsproxy *ns)
put_ipc_ns
(
ns
->
ipc_ns
);
if
(
ns
->
pid_ns
)
put_pid_ns
(
ns
->
pid_ns
);
if
(
ns
->
user_ns
)
put_user_ns
(
ns
->
user_ns
);
put_net
(
ns
->
net_ns
);
kmem_cache_free
(
nsproxy_cachep
,
ns
);
}
...
...
@@ -189,7 +178,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
int
err
=
0
;
if
(
!
(
unshare_flags
&
(
CLONE_NEWNS
|
CLONE_NEWUTS
|
CLONE_NEWIPC
|
CLONE_NEW
USER
|
CLONE_NEW
NET
)))
CLONE_NEWNET
)))
return
0
;
if
(
!
capable
(
CAP_SYS_ADMIN
))
...
...
This diff is collapsed.
Click to expand it.
kernel/sys.c
浏览文件 @
3496f92b
...
...
@@ -565,13 +565,13 @@ static int set_user(struct cred *new)
{
struct
user_struct
*
new_user
;
new_user
=
alloc_uid
(
current
->
nsproxy
->
user_ns
,
new
->
uid
);
new_user
=
alloc_uid
(
current
_user_ns
()
,
new
->
uid
);
if
(
!
new_user
)
return
-
EAGAIN
;
if
(
atomic_read
(
&
new_user
->
processes
)
>=
current
->
signal
->
rlim
[
RLIMIT_NPROC
].
rlim_cur
&&
new_user
!=
current
->
nsproxy
->
user_ns
->
root_user
)
{
new_user
!=
INIT_USER
)
{
free_uid
(
new_user
);
return
-
EAGAIN
;
}
...
...
This diff is collapsed.
Click to expand it.
kernel/user.c
浏览文件 @
3496f92b
...
...
@@ -20,9 +20,9 @@
struct
user_namespace
init_user_ns
=
{
.
kref
=
{
.
refcount
=
ATOMIC_INIT
(
2
),
.
refcount
=
ATOMIC_INIT
(
1
),
},
.
root_use
r
=
&
root_user
,
.
creato
r
=
&
root_user
,
};
EXPORT_SYMBOL_GPL
(
init_user_ns
);
...
...
@@ -48,12 +48,14 @@ static struct kmem_cache *uid_cachep;
*/
static
DEFINE_SPINLOCK
(
uidhash_lock
);
/* root_user.__count is 2, 1 for init task cred, 1 for init_user_ns->creator */
struct
user_struct
root_user
=
{
.
__count
=
ATOMIC_INIT
(
1
),
.
__count
=
ATOMIC_INIT
(
2
),
.
processes
=
ATOMIC_INIT
(
1
),
.
files
=
ATOMIC_INIT
(
0
),
.
sigpending
=
ATOMIC_INIT
(
0
),
.
locked_shm
=
0
,
.
user_ns
=
&
init_user_ns
,
#ifdef CONFIG_USER_SCHED
.
tg
=
&
init_task_group
,
#endif
...
...
@@ -314,12 +316,13 @@ static void remove_user_sysfs_dir(struct work_struct *w)
* IRQ state (as stored in flags) is restored and uidhash_lock released
* upon function exit.
*/
static
inline
void
free_user
(
struct
user_struct
*
up
,
unsigned
long
flags
)
static
void
free_user
(
struct
user_struct
*
up
,
unsigned
long
flags
)
{
/* restore back the count */
atomic_inc
(
&
up
->
__count
);
spin_unlock_irqrestore
(
&
uidhash_lock
,
flags
);
put_user_ns
(
up
->
user_ns
);
INIT_WORK
(
&
up
->
work
,
remove_user_sysfs_dir
);
schedule_work
(
&
up
->
work
);
}
...
...
@@ -335,13 +338,14 @@ static inline void uids_mutex_unlock(void) { }
* IRQ state (as stored in flags) is restored and uidhash_lock released
* upon function exit.
*/
static
inline
void
free_user
(
struct
user_struct
*
up
,
unsigned
long
flags
)
static
void
free_user
(
struct
user_struct
*
up
,
unsigned
long
flags
)
{
uid_hash_remove
(
up
);
spin_unlock_irqrestore
(
&
uidhash_lock
,
flags
);
sched_destroy_user
(
up
);
key_put
(
up
->
uid_keyring
);
key_put
(
up
->
session_keyring
);
put_user_ns
(
up
->
user_ns
);
kmem_cache_free
(
uid_cachep
,
up
);
}
...
...
@@ -357,7 +361,7 @@ struct user_struct *find_user(uid_t uid)
{
struct
user_struct
*
ret
;
unsigned
long
flags
;
struct
user_namespace
*
ns
=
current
->
nsproxy
->
user_ns
;
struct
user_namespace
*
ns
=
current
_user_ns
()
;
spin_lock_irqsave
(
&
uidhash_lock
,
flags
);
ret
=
uid_hash_find
(
uid
,
uidhashentry
(
ns
,
uid
));
...
...
@@ -404,6 +408,8 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
if
(
sched_create_user
(
new
)
<
0
)
goto
out_free_user
;
new
->
user_ns
=
get_user_ns
(
ns
);
if
(
uids_user_create
(
new
))
goto
out_destoy_sched
;
...
...
@@ -427,7 +433,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
up
=
new
;
}
spin_unlock_irq
(
&
uidhash_lock
);
}
uids_mutex_unlock
();
...
...
@@ -436,6 +441,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
out_destoy_sched:
sched_destroy_user
(
new
);
put_user_ns
(
new
->
user_ns
);
out_free_user:
kmem_cache_free
(
uid_cachep
,
new
);
out_unlock:
...
...
@@ -443,33 +449,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
return
NULL
;
}
#ifdef CONFIG_USER_NS
void
release_uids
(
struct
user_namespace
*
ns
)
{
int
i
;
unsigned
long
flags
;
struct
hlist_head
*
head
;
struct
hlist_node
*
nd
;
spin_lock_irqsave
(
&
uidhash_lock
,
flags
);
/*
* collapse the chains so that the user_struct-s will
* be still alive, but not in hashes. subsequent free_uid()
* will free them.
*/
for
(
i
=
0
;
i
<
UIDHASH_SZ
;
i
++
)
{
head
=
ns
->
uidhash_table
+
i
;
while
(
!
hlist_empty
(
head
))
{
nd
=
head
->
first
;
hlist_del_init
(
nd
);
}
}
spin_unlock_irqrestore
(
&
uidhash_lock
,
flags
);
free_uid
(
ns
->
root_user
);
}
#endif
static
int
__init
uid_cache_init
(
void
)
{
int
n
;
...
...
This diff is collapsed.
Click to expand it.
kernel/user_namespace.c
浏览文件 @
3496f92b
...
...
@@ -9,70 +9,55 @@
#include <linux/nsproxy.h>
#include <linux/slab.h>
#include <linux/user_namespace.h>
#include <linux/cred.h>
/*
* Clone a new ns copying an original user ns, setting refcount to 1
* @old_ns: namespace to clone
* Return NULL on error (failure to kmalloc), new ns otherwise
* Create a new user namespace, deriving the creator from the user in the
* passed credentials, and replacing that user with the new root user for the
* new namespace.
*
* This is called by copy_creds(), which will finish setting the target task's
* credentials.
*/
static
struct
user_namespace
*
clone_user_ns
(
struct
user_namespace
*
old_ns
)
int
create_user_ns
(
struct
cred
*
new
)
{
struct
user_namespace
*
ns
;
struct
user_struct
*
new_user
;
struct
cred
*
new
;
struct
user_struct
*
root_user
;
int
n
;
ns
=
kmalloc
(
sizeof
(
struct
user_namespace
),
GFP_KERNEL
);
if
(
!
ns
)
return
ERR_PTR
(
-
ENOMEM
)
;
return
-
ENOMEM
;
kref_init
(
&
ns
->
kref
);
for
(
n
=
0
;
n
<
UIDHASH_SZ
;
++
n
)
INIT_HLIST_HEAD
(
ns
->
uidhash_table
+
n
);
/*
Insert
new root user. */
ns
->
root_user
=
alloc_uid
(
ns
,
0
);
if
(
!
ns
->
root_user
)
{
/*
Alloc
new root user. */
root_user
=
alloc_uid
(
ns
,
0
);
if
(
!
root_user
)
{
kfree
(
ns
);
return
ERR_PTR
(
-
ENOMEM
)
;
return
-
ENOMEM
;
}
/* Reset current->user with a new one */
new_user
=
alloc_uid
(
ns
,
current_uid
());
if
(
!
new_user
)
{
free_uid
(
ns
->
root_user
);
kfree
(
ns
);
return
ERR_PTR
(
-
ENOMEM
);
}
/* Install the new user */
new
=
prepare_creds
();
if
(
!
new
)
{
free_uid
(
new_user
);
free_uid
(
ns
->
root_user
);
kfree
(
ns
);
}
free_uid
(
new
->
user
);
new
->
user
=
new_user
;
commit_creds
(
new
);
return
ns
;
}
struct
user_namespace
*
copy_user_ns
(
int
flags
,
struct
user_namespace
*
old_ns
)
{
struct
user_namespace
*
new_ns
;
BUG_ON
(
!
old_ns
);
get_user_ns
(
old_ns
);
if
(
!
(
flags
&
CLONE_NEWUSER
))
return
old_ns
;
/* set the new root user in the credentials under preparation */
ns
->
creator
=
new
->
user
;
new
->
user
=
root_user
;
new
->
uid
=
new
->
euid
=
new
->
suid
=
new
->
fsuid
=
0
;
new
->
gid
=
new
->
egid
=
new
->
sgid
=
new
->
fsgid
=
0
;
put_group_info
(
new
->
group_info
);
new
->
group_info
=
get_group_info
(
&
init_groups
);
#ifdef CONFIG_KEYS
key_put
(
new
->
request_key_auth
);
new
->
request_key_auth
=
NULL
;
#endif
/* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */
new_ns
=
clone_user_ns
(
old_ns
);
/* alloc_uid() incremented the userns refcount. Just set it to 1 */
kref_set
(
&
ns
->
kref
,
1
);
put_user_ns
(
old_ns
);
return
new_ns
;
return
0
;
}
void
free_user_ns
(
struct
kref
*
kref
)
...
...
@@ -80,7 +65,7 @@ void free_user_ns(struct kref *kref)
struct
user_namespace
*
ns
;
ns
=
container_of
(
kref
,
struct
user_namespace
,
kref
);
release_uids
(
ns
);
free_uid
(
ns
->
creator
);
kfree
(
ns
);
}
EXPORT_SYMBOL
(
free_user_ns
);
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录