Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
707c5960
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
707c5960
编写于
12月 10, 2014
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'nsfs' into for-next
上级
ba00410b
3d3d35b1
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
353 addition
and
297 deletion
+353
-297
fs/Makefile
fs/Makefile
+1
-1
fs/internal.h
fs/internal.h
+5
-0
fs/mount.h
fs/mount.h
+2
-1
fs/namespace.c
fs/namespace.c
+22
-29
fs/nsfs.c
fs/nsfs.c
+161
-0
fs/proc/inode.c
fs/proc/inode.c
+1
-9
fs/proc/internal.h
fs/proc/internal.h
+1
-1
fs/proc/namespaces.c
fs/proc/namespaces.c
+14
-139
include/linux/ipc_namespace.h
include/linux/ipc_namespace.h
+2
-1
include/linux/ns_common.h
include/linux/ns_common.h
+12
-0
include/linux/pid_namespace.h
include/linux/pid_namespace.h
+2
-1
include/linux/proc_ns.h
include/linux/proc_ns.h
+23
-20
include/linux/user_namespace.h
include/linux/user_namespace.h
+2
-1
include/linux/utsname.h
include/linux/utsname.h
+2
-1
include/net/net_namespace.h
include/net/net_namespace.h
+2
-1
include/uapi/linux/magic.h
include/uapi/linux/magic.h
+1
-0
init/main.c
init/main.c
+2
-0
init/version.c
init/version.c
+4
-1
ipc/msgutil.c
ipc/msgutil.c
+4
-1
ipc/namespace.c
ipc/namespace.c
+15
-17
kernel/nsproxy.c
kernel/nsproxy.c
+4
-6
kernel/pid.c
kernel/pid.c
+4
-1
kernel/pid_namespace.c
kernel/pid_namespace.c
+14
-15
kernel/user.c
kernel/user.c
+4
-1
kernel/user_namespace.c
kernel/user_namespace.c
+14
-15
kernel/utsname.c
kernel/utsname.c
+15
-16
net/core/net_namespace.c
net/core/net_namespace.c
+20
-19
未找到文件。
fs/Makefile
浏览文件 @
707c5960
...
...
@@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \
attr.o bad_inode.o file.o filesystems.o namespace.o
\
seq_file.o xattr.o libfs.o fs-writeback.o
\
pnode.o splice.o sync.o utimes.o
\
stack.o fs_struct.o statfs.o fs_pin.o
stack.o fs_struct.o statfs.o fs_pin.o
nsfs.o
ifeq
($(CONFIG_BLOCK),y)
obj-y
+=
buffer.o block_dev.o direct-io.o mpage.o
...
...
fs/internal.h
浏览文件 @
707c5960
...
...
@@ -147,3 +147,8 @@ extern const struct file_operations pipefifo_fops;
*/
extern
void
sb_pin_kill
(
struct
super_block
*
sb
);
extern
void
mnt_pin_kill
(
struct
mount
*
m
);
/*
* fs/nsfs.c
*/
extern
struct
dentry_operations
ns_dentry_operations
;
fs/mount.h
浏览文件 @
707c5960
#include <linux/mount.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/ns_common.h>
struct
mnt_namespace
{
atomic_t
count
;
unsigned
int
proc_inum
;
struct
ns_common
ns
;
struct
mount
*
root
;
struct
list_head
list
;
struct
user_namespace
*
user_ns
;
...
...
fs/namespace.c
浏览文件 @
707c5960
...
...
@@ -1569,17 +1569,13 @@ SYSCALL_DEFINE1(oldumount, char __user *, name)
static
bool
is_mnt_ns_file
(
struct
dentry
*
dentry
)
{
/* Is this a proxy for a mount namespace? */
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
proc_ns
*
ei
;
if
(
!
proc_ns_inode
(
inode
))
return
false
;
ei
=
get_proc_ns
(
inode
);
if
(
ei
->
ns_ops
!=
&
mntns_operations
)
return
false
;
return
dentry
->
d_op
==
&
ns_dentry_operations
&&
dentry
->
d_fsdata
==
&
mntns_operations
;
}
return
true
;
struct
mnt_namespace
*
to_mnt_ns
(
struct
ns_common
*
ns
)
{
return
container_of
(
ns
,
struct
mnt_namespace
,
ns
);
}
static
bool
mnt_ns_loop
(
struct
dentry
*
dentry
)
...
...
@@ -1591,7 +1587,7 @@ static bool mnt_ns_loop(struct dentry *dentry)
if
(
!
is_mnt_ns_file
(
dentry
))
return
false
;
mnt_ns
=
get_proc_ns
(
dentry
->
d_inode
)
->
ns
;
mnt_ns
=
to_mnt_ns
(
get_proc_ns
(
dentry
->
d_inode
))
;
return
current
->
nsproxy
->
mnt_ns
->
seq
>=
mnt_ns
->
seq
;
}
...
...
@@ -2020,7 +2016,10 @@ static int do_loopback(struct path *path, const char *old_name,
if
(
IS_MNT_UNBINDABLE
(
old
))
goto
out2
;
if
(
!
check_mnt
(
parent
)
||
!
check_mnt
(
old
))
if
(
!
check_mnt
(
parent
))
goto
out2
;
if
(
!
check_mnt
(
old
)
&&
old_path
.
dentry
->
d_op
!=
&
ns_dentry_operations
)
goto
out2
;
if
(
!
recurse
&&
has_locked_children
(
old
,
old_path
.
dentry
))
...
...
@@ -2640,7 +2639,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
static
void
free_mnt_ns
(
struct
mnt_namespace
*
ns
)
{
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
put_user_ns
(
ns
->
user_ns
);
kfree
(
ns
);
}
...
...
@@ -2662,11 +2661,12 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
new_ns
=
kmalloc
(
sizeof
(
struct
mnt_namespace
),
GFP_KERNEL
);
if
(
!
new_ns
)
return
ERR_PTR
(
-
ENOMEM
);
ret
=
proc_alloc_inum
(
&
new_ns
->
proc_inum
);
ret
=
ns_alloc_inum
(
&
new_ns
->
ns
);
if
(
ret
)
{
kfree
(
new_ns
);
return
ERR_PTR
(
ret
);
}
new_ns
->
ns
.
ops
=
&
mntns_operations
;
new_ns
->
seq
=
atomic64_add_return
(
1
,
&
mnt_ns_seq
);
atomic_set
(
&
new_ns
->
count
,
1
);
new_ns
->
root
=
NULL
;
...
...
@@ -3144,31 +3144,31 @@ bool fs_fully_visible(struct file_system_type *type)
return
visible
;
}
static
void
*
mntns_get
(
struct
task_struct
*
task
)
static
struct
ns_common
*
mntns_get
(
struct
task_struct
*
task
)
{
struct
mnt_namespace
*
ns
=
NULL
;
struct
ns_common
*
ns
=
NULL
;
struct
nsproxy
*
nsproxy
;
task_lock
(
task
);
nsproxy
=
task
->
nsproxy
;
if
(
nsproxy
)
{
ns
=
nsproxy
->
mnt_
ns
;
get_mnt_ns
(
ns
);
ns
=
&
nsproxy
->
mnt_ns
->
ns
;
get_mnt_ns
(
to_mnt_ns
(
ns
)
);
}
task_unlock
(
task
);
return
ns
;
}
static
void
mntns_put
(
void
*
ns
)
static
void
mntns_put
(
struct
ns_common
*
ns
)
{
put_mnt_ns
(
ns
);
put_mnt_ns
(
to_mnt_ns
(
ns
)
);
}
static
int
mntns_install
(
struct
nsproxy
*
nsproxy
,
void
*
ns
)
static
int
mntns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
ns
)
{
struct
fs_struct
*
fs
=
current
->
fs
;
struct
mnt_namespace
*
mnt_ns
=
ns
;
struct
mnt_namespace
*
mnt_ns
=
to_mnt_ns
(
ns
)
;
struct
path
root
;
if
(
!
ns_capable
(
mnt_ns
->
user_ns
,
CAP_SYS_ADMIN
)
||
...
...
@@ -3198,17 +3198,10 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns)
return
0
;
}
static
unsigned
int
mntns_inum
(
void
*
ns
)
{
struct
mnt_namespace
*
mnt_ns
=
ns
;
return
mnt_ns
->
proc_inum
;
}
const
struct
proc_ns_operations
mntns_operations
=
{
.
name
=
"mnt"
,
.
type
=
CLONE_NEWNS
,
.
get
=
mntns_get
,
.
put
=
mntns_put
,
.
install
=
mntns_install
,
.
inum
=
mntns_inum
,
};
fs/nsfs.c
0 → 100644
浏览文件 @
707c5960
#include <linux/mount.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/proc_ns.h>
#include <linux/magic.h>
#include <linux/ktime.h>
static
struct
vfsmount
*
nsfs_mnt
;
static
const
struct
file_operations
ns_file_operations
=
{
.
llseek
=
no_llseek
,
};
static
char
*
ns_dname
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
const
struct
proc_ns_operations
*
ns_ops
=
dentry
->
d_fsdata
;
return
dynamic_dname
(
dentry
,
buffer
,
buflen
,
"%s:[%lu]"
,
ns_ops
->
name
,
inode
->
i_ino
);
}
static
void
ns_prune_dentry
(
struct
dentry
*
dentry
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
if
(
inode
)
{
struct
ns_common
*
ns
=
inode
->
i_private
;
atomic_long_set
(
&
ns
->
stashed
,
0
);
}
}
const
struct
dentry_operations
ns_dentry_operations
=
{
.
d_prune
=
ns_prune_dentry
,
.
d_delete
=
always_delete_dentry
,
.
d_dname
=
ns_dname
,
};
static
void
nsfs_evict
(
struct
inode
*
inode
)
{
struct
ns_common
*
ns
=
inode
->
i_private
;
clear_inode
(
inode
);
ns
->
ops
->
put
(
ns
);
}
void
*
ns_get_path
(
struct
path
*
path
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ns_ops
)
{
struct
vfsmount
*
mnt
=
mntget
(
nsfs_mnt
);
struct
qstr
qname
=
{
.
name
=
""
,
};
struct
dentry
*
dentry
;
struct
inode
*
inode
;
struct
ns_common
*
ns
;
unsigned
long
d
;
again:
ns
=
ns_ops
->
get
(
task
);
if
(
!
ns
)
{
mntput
(
mnt
);
return
ERR_PTR
(
-
ENOENT
);
}
rcu_read_lock
();
d
=
atomic_long_read
(
&
ns
->
stashed
);
if
(
!
d
)
goto
slow
;
dentry
=
(
struct
dentry
*
)
d
;
if
(
!
lockref_get_not_dead
(
&
dentry
->
d_lockref
))
goto
slow
;
rcu_read_unlock
();
ns_ops
->
put
(
ns
);
got_it:
path
->
mnt
=
mnt
;
path
->
dentry
=
dentry
;
return
NULL
;
slow:
rcu_read_unlock
();
inode
=
new_inode_pseudo
(
mnt
->
mnt_sb
);
if
(
!
inode
)
{
ns_ops
->
put
(
ns
);
mntput
(
mnt
);
return
ERR_PTR
(
-
ENOMEM
);
}
inode
->
i_ino
=
ns
->
inum
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_flags
|=
S_IMMUTABLE
;
inode
->
i_mode
=
S_IFREG
|
S_IRUGO
;
inode
->
i_fop
=
&
ns_file_operations
;
inode
->
i_private
=
ns
;
dentry
=
d_alloc_pseudo
(
mnt
->
mnt_sb
,
&
qname
);
if
(
!
dentry
)
{
iput
(
inode
);
mntput
(
mnt
);
return
ERR_PTR
(
-
ENOMEM
);
}
d_instantiate
(
dentry
,
inode
);
dentry
->
d_fsdata
=
(
void
*
)
ns_ops
;
d
=
atomic_long_cmpxchg
(
&
ns
->
stashed
,
0
,
(
unsigned
long
)
dentry
);
if
(
d
)
{
d_delete
(
dentry
);
/* make sure ->d_prune() does nothing */
dput
(
dentry
);
cpu_relax
();
goto
again
;
}
goto
got_it
;
}
int
ns_get_name
(
char
*
buf
,
size_t
size
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ns_ops
)
{
struct
ns_common
*
ns
;
int
res
=
-
ENOENT
;
ns
=
ns_ops
->
get
(
task
);
if
(
ns
)
{
res
=
snprintf
(
buf
,
size
,
"%s:[%u]"
,
ns_ops
->
name
,
ns
->
inum
);
ns_ops
->
put
(
ns
);
}
return
res
;
}
struct
file
*
proc_ns_fget
(
int
fd
)
{
struct
file
*
file
;
file
=
fget
(
fd
);
if
(
!
file
)
return
ERR_PTR
(
-
EBADF
);
if
(
file
->
f_op
!=
&
ns_file_operations
)
goto
out_invalid
;
return
file
;
out_invalid:
fput
(
file
);
return
ERR_PTR
(
-
EINVAL
);
}
static
const
struct
super_operations
nsfs_ops
=
{
.
statfs
=
simple_statfs
,
.
evict_inode
=
nsfs_evict
,
};
static
struct
dentry
*
nsfs_mount
(
struct
file_system_type
*
fs_type
,
int
flags
,
const
char
*
dev_name
,
void
*
data
)
{
return
mount_pseudo
(
fs_type
,
"nsfs:"
,
&
nsfs_ops
,
&
ns_dentry_operations
,
NSFS_MAGIC
);
}
static
struct
file_system_type
nsfs
=
{
.
name
=
"nsfs"
,
.
mount
=
nsfs_mount
,
.
kill_sb
=
kill_anon_super
,
};
void
__init
nsfs_init
(
void
)
{
nsfs_mnt
=
kern_mount
(
&
nsfs
);
if
(
IS_ERR
(
nsfs_mnt
))
panic
(
"can't set nsfs up
\n
"
);
nsfs_mnt
->
mnt_sb
->
s_flags
&=
~
MS_NOUSER
;
}
fs/proc/inode.c
浏览文件 @
707c5960
...
...
@@ -32,8 +32,6 @@ static void proc_evict_inode(struct inode *inode)
{
struct
proc_dir_entry
*
de
;
struct
ctl_table_header
*
head
;
const
struct
proc_ns_operations
*
ns_ops
;
void
*
ns
;
truncate_inode_pages_final
(
&
inode
->
i_data
);
clear_inode
(
inode
);
...
...
@@ -50,11 +48,6 @@ static void proc_evict_inode(struct inode *inode)
RCU_INIT_POINTER
(
PROC_I
(
inode
)
->
sysctl
,
NULL
);
sysctl_head_put
(
head
);
}
/* Release any associated namespace */
ns_ops
=
PROC_I
(
inode
)
->
ns
.
ns_ops
;
ns
=
PROC_I
(
inode
)
->
ns
.
ns
;
if
(
ns_ops
&&
ns
)
ns_ops
->
put
(
ns
);
}
static
struct
kmem_cache
*
proc_inode_cachep
;
...
...
@@ -73,8 +66,7 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
ei
->
pde
=
NULL
;
ei
->
sysctl
=
NULL
;
ei
->
sysctl_entry
=
NULL
;
ei
->
ns
.
ns
=
NULL
;
ei
->
ns
.
ns_ops
=
NULL
;
ei
->
ns_ops
=
NULL
;
inode
=
&
ei
->
vfs_inode
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
return
inode
;
...
...
fs/proc/internal.h
浏览文件 @
707c5960
...
...
@@ -64,7 +64,7 @@ struct proc_inode {
struct
proc_dir_entry
*
pde
;
struct
ctl_table_header
*
sysctl
;
struct
ctl_table
*
sysctl_entry
;
struct
proc_ns
n
s
;
const
struct
proc_ns_operations
*
ns_op
s
;
struct
inode
vfs_inode
;
};
...
...
fs/proc/namespaces.c
浏览文件 @
707c5960
#include <linux/proc_fs.h>
#include <linux/nsproxy.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/fs_struct.h>
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/file.h>
#include <linux/utsname.h>
...
...
@@ -34,138 +30,45 @@ static const struct proc_ns_operations *ns_entries[] = {
&
mntns_operations
,
};
static
const
struct
file_operations
ns_file_operations
=
{
.
llseek
=
no_llseek
,
};
static
const
struct
inode_operations
ns_inode_operations
=
{
.
setattr
=
proc_setattr
,
};
static
char
*
ns_dname
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
const
struct
proc_ns_operations
*
ns_ops
=
PROC_I
(
inode
)
->
ns
.
ns_ops
;
return
dynamic_dname
(
dentry
,
buffer
,
buflen
,
"%s:[%lu]"
,
ns_ops
->
name
,
inode
->
i_ino
);
}
const
struct
dentry_operations
ns_dentry_operations
=
{
.
d_delete
=
always_delete_dentry
,
.
d_dname
=
ns_dname
,
};
static
struct
dentry
*
proc_ns_get_dentry
(
struct
super_block
*
sb
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ns_ops
)
{
struct
dentry
*
dentry
,
*
result
;
struct
inode
*
inode
;
struct
proc_inode
*
ei
;
struct
qstr
qname
=
{
.
name
=
""
,
};
void
*
ns
;
ns
=
ns_ops
->
get
(
task
);
if
(
!
ns
)
return
ERR_PTR
(
-
ENOENT
);
dentry
=
d_alloc_pseudo
(
sb
,
&
qname
);
if
(
!
dentry
)
{
ns_ops
->
put
(
ns
);
return
ERR_PTR
(
-
ENOMEM
);
}
inode
=
iget_locked
(
sb
,
ns_ops
->
inum
(
ns
));
if
(
!
inode
)
{
dput
(
dentry
);
ns_ops
->
put
(
ns
);
return
ERR_PTR
(
-
ENOMEM
);
}
ei
=
PROC_I
(
inode
);
if
(
inode
->
i_state
&
I_NEW
)
{
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_op
=
&
ns_inode_operations
;
inode
->
i_mode
=
S_IFREG
|
S_IRUGO
;
inode
->
i_fop
=
&
ns_file_operations
;
ei
->
ns
.
ns_ops
=
ns_ops
;
ei
->
ns
.
ns
=
ns
;
unlock_new_inode
(
inode
);
}
else
{
ns_ops
->
put
(
ns
);
}
d_set_d_op
(
dentry
,
&
ns_dentry_operations
);
result
=
d_instantiate_unique
(
dentry
,
inode
);
if
(
result
)
{
dput
(
dentry
);
dentry
=
result
;
}
return
dentry
;
}
static
void
*
proc_ns_follow_link
(
struct
dentry
*
dentry
,
struct
nameidata
*
nd
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
super_block
*
sb
=
inode
->
i_sb
;
struct
proc_inode
*
ei
=
PROC_I
(
inode
);
const
struct
proc_ns_operations
*
ns_ops
=
PROC_I
(
inode
)
->
ns_ops
;
struct
task_struct
*
task
;
struct
path
ns_path
;
void
*
error
=
ERR_PTR
(
-
EACCES
);
task
=
get_proc_task
(
inode
);
if
(
!
task
)
goto
out
;
return
error
;
if
(
!
ptrace_may_access
(
task
,
PTRACE_MODE_READ
))
goto
out_put_task
;
ns_path
.
dentry
=
proc_ns_get_dentry
(
sb
,
task
,
ei
->
ns
.
ns_ops
);
if
(
IS_ERR
(
ns_path
.
dentry
))
{
error
=
ERR_CAST
(
ns_path
.
dentry
);
goto
out_put_task
;
if
(
ptrace_may_access
(
task
,
PTRACE_MODE_READ
))
{
error
=
ns_get_path
(
&
ns_path
,
task
,
ns_ops
);
if
(
!
error
)
nd_jump_link
(
nd
,
&
ns_path
);
}
ns_path
.
mnt
=
mntget
(
nd
->
path
.
mnt
);
nd_jump_link
(
nd
,
&
ns_path
);
error
=
NULL
;
out_put_task:
put_task_struct
(
task
);
out:
return
error
;
}
static
int
proc_ns_readlink
(
struct
dentry
*
dentry
,
char
__user
*
buffer
,
int
buflen
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
proc_inode
*
ei
=
PROC_I
(
inode
);
const
struct
proc_ns_operations
*
ns_ops
=
ei
->
ns
.
ns_ops
;
const
struct
proc_ns_operations
*
ns_ops
=
PROC_I
(
inode
)
->
ns_ops
;
struct
task_struct
*
task
;
void
*
ns
;
char
name
[
50
];
int
res
=
-
EACCES
;
task
=
get_proc_task
(
inode
);
if
(
!
task
)
goto
out
;
if
(
!
ptrace_may_access
(
task
,
PTRACE_MODE_READ
))
goto
out_put_task
;
return
res
;
res
=
-
ENOENT
;
ns
=
ns_ops
->
get
(
task
);
if
(
!
ns
)
goto
out_put_task
;
snprintf
(
name
,
sizeof
(
name
),
"%s:[%u]"
,
ns_ops
->
name
,
ns_ops
->
inum
(
ns
));
res
=
readlink_copy
(
buffer
,
buflen
,
name
);
ns_ops
->
put
(
ns
);
out_put_task:
if
(
ptrace_may_access
(
task
,
PTRACE_MODE_READ
))
{
res
=
ns_get_name
(
name
,
sizeof
(
name
),
task
,
ns_ops
);
if
(
res
>=
0
)
res
=
readlink_copy
(
buffer
,
buflen
,
name
);
}
put_task_struct
(
task
);
out:
return
res
;
}
...
...
@@ -189,7 +92,7 @@ static int proc_ns_instantiate(struct inode *dir,
ei
=
PROC_I
(
inode
);
inode
->
i_mode
=
S_IFLNK
|
S_IRWXUGO
;
inode
->
i_op
=
&
proc_ns_link_inode_operations
;
ei
->
ns
.
ns
_ops
=
ns_ops
;
ei
->
ns_ops
=
ns_ops
;
d_set_d_op
(
dentry
,
&
pid_dentry_operations
);
d_add
(
dentry
,
inode
);
...
...
@@ -267,31 +170,3 @@ const struct inode_operations proc_ns_dir_inode_operations = {
.
getattr
=
pid_getattr
,
.
setattr
=
proc_setattr
,
};
struct
file
*
proc_ns_fget
(
int
fd
)
{
struct
file
*
file
;
file
=
fget
(
fd
);
if
(
!
file
)
return
ERR_PTR
(
-
EBADF
);
if
(
file
->
f_op
!=
&
ns_file_operations
)
goto
out_invalid
;
return
file
;
out_invalid:
fput
(
file
);
return
ERR_PTR
(
-
EINVAL
);
}
struct
proc_ns
*
get_proc_ns
(
struct
inode
*
inode
)
{
return
&
PROC_I
(
inode
)
->
ns
;
}
bool
proc_ns_inode
(
struct
inode
*
inode
)
{
return
inode
->
i_fop
==
&
ns_file_operations
;
}
include/linux/ipc_namespace.h
浏览文件 @
707c5960
...
...
@@ -6,6 +6,7 @@
#include <linux/rwsem.h>
#include <linux/notifier.h>
#include <linux/nsproxy.h>
#include <linux/ns_common.h>
/*
* ipc namespace events
...
...
@@ -68,7 +69,7 @@ struct ipc_namespace {
/* user_ns which owns the ipc ns */
struct
user_namespace
*
user_ns
;
unsigned
int
proc_inum
;
struct
ns_common
ns
;
};
extern
struct
ipc_namespace
init_ipc_ns
;
...
...
include/linux/ns_common.h
0 → 100644
浏览文件 @
707c5960
#ifndef _LINUX_NS_COMMON_H
#define _LINUX_NS_COMMON_H
struct
proc_ns_operations
;
struct
ns_common
{
atomic_long_t
stashed
;
const
struct
proc_ns_operations
*
ops
;
unsigned
int
inum
;
};
#endif
include/linux/pid_namespace.h
浏览文件 @
707c5960
...
...
@@ -8,6 +8,7 @@
#include <linux/threads.h>
#include <linux/nsproxy.h>
#include <linux/kref.h>
#include <linux/ns_common.h>
struct
pidmap
{
atomic_t
nr_free
;
...
...
@@ -43,7 +44,7 @@ struct pid_namespace {
kgid_t
pid_gid
;
int
hide_pid
;
int
reboot
;
/* group exit code if this pidns was rebooted */
unsigned
int
proc_inum
;
struct
ns_common
ns
;
};
extern
struct
pid_namespace
init_pid_ns
;
...
...
include/linux/proc_ns.h
浏览文件 @
707c5960
...
...
@@ -4,21 +4,18 @@
#ifndef _LINUX_PROC_NS_H
#define _LINUX_PROC_NS_H
#include <linux/ns_common.h>
struct
pid_namespace
;
struct
nsproxy
;
struct
path
;
struct
proc_ns_operations
{
const
char
*
name
;
int
type
;
void
*
(
*
get
)(
struct
task_struct
*
task
);
void
(
*
put
)(
void
*
ns
);
int
(
*
install
)(
struct
nsproxy
*
nsproxy
,
void
*
ns
);
unsigned
int
(
*
inum
)(
void
*
ns
);
};
struct
proc_ns
{
void
*
ns
;
const
struct
proc_ns_operations
*
ns_ops
;
struct
ns_common
*
(
*
get
)(
struct
task_struct
*
task
);
void
(
*
put
)(
struct
ns_common
*
ns
);
int
(
*
install
)(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
ns
);
};
extern
const
struct
proc_ns_operations
netns_operations
;
...
...
@@ -43,32 +40,38 @@ enum {
extern
int
pid_ns_prepare_proc
(
struct
pid_namespace
*
ns
);
extern
void
pid_ns_release_proc
(
struct
pid_namespace
*
ns
);
extern
struct
file
*
proc_ns_fget
(
int
fd
);
extern
struct
proc_ns
*
get_proc_ns
(
struct
inode
*
);
extern
int
proc_alloc_inum
(
unsigned
int
*
pino
);
extern
void
proc_free_inum
(
unsigned
int
inum
);
extern
bool
proc_ns_inode
(
struct
inode
*
inode
);
#else
/* CONFIG_PROC_FS */
static
inline
int
pid_ns_prepare_proc
(
struct
pid_namespace
*
ns
)
{
return
0
;
}
static
inline
void
pid_ns_release_proc
(
struct
pid_namespace
*
ns
)
{}
static
inline
struct
file
*
proc_ns_fget
(
int
fd
)
{
return
ERR_PTR
(
-
EINVAL
);
}
static
inline
struct
proc_ns
*
get_proc_ns
(
struct
inode
*
inode
)
{
return
NULL
;
}
static
inline
int
proc_alloc_inum
(
unsigned
int
*
inum
)
{
*
inum
=
1
;
return
0
;
}
static
inline
void
proc_free_inum
(
unsigned
int
inum
)
{}
static
inline
bool
proc_ns_inode
(
struct
inode
*
inode
)
{
return
false
;
}
#endif
/* CONFIG_PROC_FS */
static
inline
int
ns_alloc_inum
(
struct
ns_common
*
ns
)
{
atomic_long_set
(
&
ns
->
stashed
,
0
);
return
proc_alloc_inum
(
&
ns
->
inum
);
}
#define ns_free_inum(ns) proc_free_inum((ns)->inum)
extern
struct
file
*
proc_ns_fget
(
int
fd
);
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
extern
void
*
ns_get_path
(
struct
path
*
path
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ns_ops
);
extern
int
ns_get_name
(
char
*
buf
,
size_t
size
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ns_ops
);
extern
void
nsfs_init
(
void
);
#endif
/* _LINUX_PROC_NS_H */
include/linux/user_namespace.h
浏览文件 @
707c5960
...
...
@@ -3,6 +3,7 @@
#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <linux/ns_common.h>
#include <linux/sched.h>
#include <linux/err.h>
...
...
@@ -26,7 +27,7 @@ struct user_namespace {
int
level
;
kuid_t
owner
;
kgid_t
group
;
unsigned
int
proc_inum
;
struct
ns_common
ns
;
/* Register of per-UID persistent keyrings for this namespace */
#ifdef CONFIG_PERSISTENT_KEYRINGS
...
...
include/linux/utsname.h
浏览文件 @
707c5960
...
...
@@ -5,6 +5,7 @@
#include <linux/sched.h>
#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <linux/ns_common.h>
#include <linux/err.h>
#include <uapi/linux/utsname.h>
...
...
@@ -23,7 +24,7 @@ struct uts_namespace {
struct
kref
kref
;
struct
new_utsname
name
;
struct
user_namespace
*
user_ns
;
unsigned
int
proc_inum
;
struct
ns_common
ns
;
};
extern
struct
uts_namespace
init_uts_ns
;
...
...
include/net/net_namespace.h
浏览文件 @
707c5960
...
...
@@ -26,6 +26,7 @@
#endif
#include <net/netns/nftables.h>
#include <net/netns/xfrm.h>
#include <linux/ns_common.h>
struct
user_namespace
;
struct
proc_dir_entry
;
...
...
@@ -60,7 +61,7 @@ struct net {
struct
user_namespace
*
user_ns
;
/* Owning user namespace */
unsigned
int
proc_inum
;
struct
ns_common
ns
;
struct
proc_dir_entry
*
proc_net
;
struct
proc_dir_entry
*
proc_net_stat
;
...
...
include/uapi/linux/magic.h
浏览文件 @
707c5960
...
...
@@ -72,5 +72,6 @@
#define MTD_INODE_FS_MAGIC 0x11307854
#define ANON_INODE_FS_MAGIC 0x09041934
#define BTRFS_TEST_MAGIC 0x73727279
#define NSFS_MAGIC 0x6e736673
#endif
/* __LINUX_MAGIC_H__ */
init/main.c
浏览文件 @
707c5960
...
...
@@ -78,6 +78,7 @@
#include <linux/context_tracking.h>
#include <linux/random.h>
#include <linux/list.h>
#include <linux/proc_ns.h>
#include <asm/io.h>
#include <asm/bugs.h>
...
...
@@ -660,6 +661,7 @@ asmlinkage __visible void __init start_kernel(void)
/* rootfs populating might need page-writeback */
page_writeback_init
();
proc_root_init
();
nsfs_init
();
cgroup_init
();
cpuset_init
();
taskstats_init_early
();
...
...
init/version.c
浏览文件 @
707c5960
...
...
@@ -35,7 +35,10 @@ struct uts_namespace init_uts_ns = {
.
domainname
=
UTS_DOMAINNAME
,
},
.
user_ns
=
&
init_user_ns
,
.
proc_inum
=
PROC_UTS_INIT_INO
,
.
ns
.
inum
=
PROC_UTS_INIT_INO
,
#ifdef CONFIG_UTS_NS
.
ns
.
ops
=
&
utsns_operations
,
#endif
};
EXPORT_SYMBOL_GPL
(
init_uts_ns
);
...
...
ipc/msgutil.c
浏览文件 @
707c5960
...
...
@@ -31,7 +31,10 @@ DEFINE_SPINLOCK(mq_lock);
struct
ipc_namespace
init_ipc_ns
=
{
.
count
=
ATOMIC_INIT
(
1
),
.
user_ns
=
&
init_user_ns
,
.
proc_inum
=
PROC_IPC_INIT_INO
,
.
ns
.
inum
=
PROC_IPC_INIT_INO
,
#ifdef CONFIG_IPC_NS
.
ns
.
ops
=
&
ipcns_operations
,
#endif
};
atomic_t
nr_ipc_ns
=
ATOMIC_INIT
(
1
);
...
...
ipc/namespace.c
浏览文件 @
707c5960
...
...
@@ -26,16 +26,17 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
if
(
ns
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
err
=
proc_alloc_inum
(
&
ns
->
proc_inum
);
err
=
ns_alloc_inum
(
&
ns
->
ns
);
if
(
err
)
{
kfree
(
ns
);
return
ERR_PTR
(
err
);
}
ns
->
ns
.
ops
=
&
ipcns_operations
;
atomic_set
(
&
ns
->
count
,
1
);
err
=
mq_init_ns
(
ns
);
if
(
err
)
{
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
kfree
(
ns
);
return
ERR_PTR
(
err
);
}
...
...
@@ -119,7 +120,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
*/
ipcns_notify
(
IPCNS_REMOVED
);
put_user_ns
(
ns
->
user_ns
);
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
kfree
(
ns
);
}
...
...
@@ -149,7 +150,12 @@ void put_ipc_ns(struct ipc_namespace *ns)
}
}
static
void
*
ipcns_get
(
struct
task_struct
*
task
)
static
inline
struct
ipc_namespace
*
to_ipc_ns
(
struct
ns_common
*
ns
)
{
return
container_of
(
ns
,
struct
ipc_namespace
,
ns
);
}
static
struct
ns_common
*
ipcns_get
(
struct
task_struct
*
task
)
{
struct
ipc_namespace
*
ns
=
NULL
;
struct
nsproxy
*
nsproxy
;
...
...
@@ -160,17 +166,17 @@ static void *ipcns_get(struct task_struct *task)
ns
=
get_ipc_ns
(
nsproxy
->
ipc_ns
);
task_unlock
(
task
);
return
ns
;
return
ns
?
&
ns
->
ns
:
NULL
;
}
static
void
ipcns_put
(
void
*
ns
)
static
void
ipcns_put
(
struct
ns_common
*
ns
)
{
return
put_ipc_ns
(
ns
);
return
put_ipc_ns
(
to_ipc_ns
(
ns
)
);
}
static
int
ipcns_install
(
struct
nsproxy
*
nsproxy
,
void
*
new
)
static
int
ipcns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
new
)
{
struct
ipc_namespace
*
ns
=
new
;
struct
ipc_namespace
*
ns
=
to_ipc_ns
(
new
)
;
if
(
!
ns_capable
(
ns
->
user_ns
,
CAP_SYS_ADMIN
)
||
!
ns_capable
(
current_user_ns
(),
CAP_SYS_ADMIN
))
return
-
EPERM
;
...
...
@@ -182,18 +188,10 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new)
return
0
;
}
static
unsigned
int
ipcns_inum
(
void
*
vp
)
{
struct
ipc_namespace
*
ns
=
vp
;
return
ns
->
proc_inum
;
}
const
struct
proc_ns_operations
ipcns_operations
=
{
.
name
=
"ipc"
,
.
type
=
CLONE_NEWIPC
,
.
get
=
ipcns_get
,
.
put
=
ipcns_put
,
.
install
=
ipcns_install
,
.
inum
=
ipcns_inum
,
};
kernel/nsproxy.c
浏览文件 @
707c5960
...
...
@@ -220,11 +220,10 @@ void exit_task_namespaces(struct task_struct *p)
SYSCALL_DEFINE2
(
setns
,
int
,
fd
,
int
,
nstype
)
{
const
struct
proc_ns_operations
*
ops
;
struct
task_struct
*
tsk
=
current
;
struct
nsproxy
*
new_nsproxy
;
struct
proc_ns
*
ei
;
struct
file
*
file
;
struct
ns_common
*
ns
;
int
err
;
file
=
proc_ns_fget
(
fd
);
...
...
@@ -232,9 +231,8 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
return
PTR_ERR
(
file
);
err
=
-
EINVAL
;
ei
=
get_proc_ns
(
file_inode
(
file
));
ops
=
ei
->
ns_ops
;
if
(
nstype
&&
(
ops
->
type
!=
nstype
))
ns
=
get_proc_ns
(
file_inode
(
file
));
if
(
nstype
&&
(
ns
->
ops
->
type
!=
nstype
))
goto
out
;
new_nsproxy
=
create_new_namespaces
(
0
,
tsk
,
current_user_ns
(),
tsk
->
fs
);
...
...
@@ -243,7 +241,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
goto
out
;
}
err
=
ops
->
install
(
new_nsproxy
,
ei
->
ns
);
err
=
ns
->
ops
->
install
(
new_nsproxy
,
ns
);
if
(
err
)
{
free_nsproxy
(
new_nsproxy
);
goto
out
;
...
...
kernel/pid.c
浏览文件 @
707c5960
...
...
@@ -79,7 +79,10 @@ struct pid_namespace init_pid_ns = {
.
level
=
0
,
.
child_reaper
=
&
init_task
,
.
user_ns
=
&
init_user_ns
,
.
proc_inum
=
PROC_PID_INIT_INO
,
.
ns
.
inum
=
PROC_PID_INIT_INO
,
#ifdef CONFIG_PID_NS
.
ns
.
ops
=
&
pidns_operations
,
#endif
};
EXPORT_SYMBOL_GPL
(
init_pid_ns
);
...
...
kernel/pid_namespace.c
浏览文件 @
707c5960
...
...
@@ -105,9 +105,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
if
(
ns
->
pid_cachep
==
NULL
)
goto
out_free_map
;
err
=
proc_alloc_inum
(
&
ns
->
proc_inum
);
err
=
ns_alloc_inum
(
&
ns
->
ns
);
if
(
err
)
goto
out_free_map
;
ns
->
ns
.
ops
=
&
pidns_operations
;
kref_init
(
&
ns
->
kref
);
ns
->
level
=
level
;
...
...
@@ -142,7 +143,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
{
int
i
;
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
for
(
i
=
0
;
i
<
PIDMAP_ENTRIES
;
i
++
)
kfree
(
ns
->
pidmap
[
i
].
page
);
put_user_ns
(
ns
->
user_ns
);
...
...
@@ -313,7 +314,12 @@ int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)
return
0
;
}
static
void
*
pidns_get
(
struct
task_struct
*
task
)
static
inline
struct
pid_namespace
*
to_pid_ns
(
struct
ns_common
*
ns
)
{
return
container_of
(
ns
,
struct
pid_namespace
,
ns
);
}
static
struct
ns_common
*
pidns_get
(
struct
task_struct
*
task
)
{
struct
pid_namespace
*
ns
;
...
...
@@ -323,18 +329,18 @@ static void *pidns_get(struct task_struct *task)
get_pid_ns
(
ns
);
rcu_read_unlock
();
return
ns
;
return
ns
?
&
ns
->
ns
:
NULL
;
}
static
void
pidns_put
(
void
*
ns
)
static
void
pidns_put
(
struct
ns_common
*
ns
)
{
put_pid_ns
(
ns
);
put_pid_ns
(
to_pid_ns
(
ns
)
);
}
static
int
pidns_install
(
struct
nsproxy
*
nsproxy
,
void
*
ns
)
static
int
pidns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
ns
)
{
struct
pid_namespace
*
active
=
task_active_pid_ns
(
current
);
struct
pid_namespace
*
ancestor
,
*
new
=
ns
;
struct
pid_namespace
*
ancestor
,
*
new
=
to_pid_ns
(
ns
)
;
if
(
!
ns_capable
(
new
->
user_ns
,
CAP_SYS_ADMIN
)
||
!
ns_capable
(
current_user_ns
(),
CAP_SYS_ADMIN
))
...
...
@@ -362,19 +368,12 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns)
return
0
;
}
static
unsigned
int
pidns_inum
(
void
*
ns
)
{
struct
pid_namespace
*
pid_ns
=
ns
;
return
pid_ns
->
proc_inum
;
}
const
struct
proc_ns_operations
pidns_operations
=
{
.
name
=
"pid"
,
.
type
=
CLONE_NEWPID
,
.
get
=
pidns_get
,
.
put
=
pidns_put
,
.
install
=
pidns_install
,
.
inum
=
pidns_inum
,
};
static
__init
int
pid_namespaces_init
(
void
)
...
...
kernel/user.c
浏览文件 @
707c5960
...
...
@@ -50,7 +50,10 @@ struct user_namespace init_user_ns = {
.
count
=
ATOMIC_INIT
(
3
),
.
owner
=
GLOBAL_ROOT_UID
,
.
group
=
GLOBAL_ROOT_GID
,
.
proc_inum
=
PROC_USER_INIT_INO
,
.
ns
.
inum
=
PROC_USER_INIT_INO
,
#ifdef CONFIG_USER_NS
.
ns
.
ops
=
&
userns_operations
,
#endif
#ifdef CONFIG_PERSISTENT_KEYRINGS
.
persistent_keyring_register_sem
=
__RWSEM_INITIALIZER
(
init_user_ns
.
persistent_keyring_register_sem
),
...
...
kernel/user_namespace.c
浏览文件 @
707c5960
...
...
@@ -86,11 +86,12 @@ int create_user_ns(struct cred *new)
if
(
!
ns
)
return
-
ENOMEM
;
ret
=
proc_alloc_inum
(
&
ns
->
proc_inum
);
ret
=
ns_alloc_inum
(
&
ns
->
ns
);
if
(
ret
)
{
kmem_cache_free
(
user_ns_cachep
,
ns
);
return
ret
;
}
ns
->
ns
.
ops
=
&
userns_operations
;
atomic_set
(
&
ns
->
count
,
1
);
/* Leave the new->user_ns reference with the new user namespace. */
...
...
@@ -136,7 +137,7 @@ void free_user_ns(struct user_namespace *ns)
#ifdef CONFIG_PERSISTENT_KEYRINGS
key_put
(
ns
->
persistent_keyring_register
);
#endif
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
kmem_cache_free
(
user_ns_cachep
,
ns
);
ns
=
parent
;
}
while
(
atomic_dec_and_test
(
&
parent
->
count
));
...
...
@@ -841,7 +842,12 @@ static bool new_idmap_permitted(const struct file *file,
return
false
;
}
static
void
*
userns_get
(
struct
task_struct
*
task
)
static
inline
struct
user_namespace
*
to_user_ns
(
struct
ns_common
*
ns
)
{
return
container_of
(
ns
,
struct
user_namespace
,
ns
);
}
static
struct
ns_common
*
userns_get
(
struct
task_struct
*
task
)
{
struct
user_namespace
*
user_ns
;
...
...
@@ -849,17 +855,17 @@ static void *userns_get(struct task_struct *task)
user_ns
=
get_user_ns
(
__task_cred
(
task
)
->
user_ns
);
rcu_read_unlock
();
return
user_ns
;
return
user_ns
?
&
user_ns
->
ns
:
NULL
;
}
static
void
userns_put
(
void
*
ns
)
static
void
userns_put
(
struct
ns_common
*
ns
)
{
put_user_ns
(
ns
);
put_user_ns
(
to_user_ns
(
ns
)
);
}
static
int
userns_install
(
struct
nsproxy
*
nsproxy
,
void
*
ns
)
static
int
userns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
ns
)
{
struct
user_namespace
*
user_ns
=
ns
;
struct
user_namespace
*
user_ns
=
to_user_ns
(
ns
)
;
struct
cred
*
cred
;
/* Don't allow gaining capabilities by reentering
...
...
@@ -888,19 +894,12 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
return
commit_creds
(
cred
);
}
static
unsigned
int
userns_inum
(
void
*
ns
)
{
struct
user_namespace
*
user_ns
=
ns
;
return
user_ns
->
proc_inum
;
}
const
struct
proc_ns_operations
userns_operations
=
{
.
name
=
"user"
,
.
type
=
CLONE_NEWUSER
,
.
get
=
userns_get
,
.
put
=
userns_put
,
.
install
=
userns_install
,
.
inum
=
userns_inum
,
};
static
__init
int
user_namespaces_init
(
void
)
...
...
kernel/utsname.c
浏览文件 @
707c5960
...
...
@@ -42,12 +42,14 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
if
(
!
ns
)
return
ERR_PTR
(
-
ENOMEM
);
err
=
proc_alloc_inum
(
&
ns
->
proc_inum
);
err
=
ns_alloc_inum
(
&
ns
->
ns
);
if
(
err
)
{
kfree
(
ns
);
return
ERR_PTR
(
err
);
}
ns
->
ns
.
ops
=
&
utsns_operations
;
down_read
(
&
uts_sem
);
memcpy
(
&
ns
->
name
,
&
old_ns
->
name
,
sizeof
(
ns
->
name
));
ns
->
user_ns
=
get_user_ns
(
user_ns
);
...
...
@@ -84,11 +86,16 @@ void free_uts_ns(struct kref *kref)
ns
=
container_of
(
kref
,
struct
uts_namespace
,
kref
);
put_user_ns
(
ns
->
user_ns
);
proc_free_inum
(
ns
->
proc_inum
);
ns_free_inum
(
&
ns
->
ns
);
kfree
(
ns
);
}
static
void
*
utsns_get
(
struct
task_struct
*
task
)
static
inline
struct
uts_namespace
*
to_uts_ns
(
struct
ns_common
*
ns
)
{
return
container_of
(
ns
,
struct
uts_namespace
,
ns
);
}
static
struct
ns_common
*
utsns_get
(
struct
task_struct
*
task
)
{
struct
uts_namespace
*
ns
=
NULL
;
struct
nsproxy
*
nsproxy
;
...
...
@@ -101,17 +108,17 @@ static void *utsns_get(struct task_struct *task)
}
task_unlock
(
task
);
return
ns
;
return
ns
?
&
ns
->
ns
:
NULL
;
}
static
void
utsns_put
(
void
*
ns
)
static
void
utsns_put
(
struct
ns_common
*
ns
)
{
put_uts_ns
(
ns
);
put_uts_ns
(
to_uts_ns
(
ns
)
);
}
static
int
utsns_install
(
struct
nsproxy
*
nsproxy
,
void
*
new
)
static
int
utsns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
new
)
{
struct
uts_namespace
*
ns
=
new
;
struct
uts_namespace
*
ns
=
to_uts_ns
(
new
)
;
if
(
!
ns_capable
(
ns
->
user_ns
,
CAP_SYS_ADMIN
)
||
!
ns_capable
(
current_user_ns
(),
CAP_SYS_ADMIN
))
...
...
@@ -123,18 +130,10 @@ static int utsns_install(struct nsproxy *nsproxy, void *new)
return
0
;
}
static
unsigned
int
utsns_inum
(
void
*
vp
)
{
struct
uts_namespace
*
ns
=
vp
;
return
ns
->
proc_inum
;
}
const
struct
proc_ns_operations
utsns_operations
=
{
.
name
=
"uts"
,
.
type
=
CLONE_NEWUTS
,
.
get
=
utsns_get
,
.
put
=
utsns_put
,
.
install
=
utsns_install
,
.
inum
=
utsns_inum
,
};
net/core/net_namespace.c
浏览文件 @
707c5960
...
...
@@ -337,17 +337,17 @@ EXPORT_SYMBOL_GPL(__put_net);
struct
net
*
get_net_ns_by_fd
(
int
fd
)
{
struct
proc_ns
*
ei
;
struct
file
*
file
;
struct
ns_common
*
ns
;
struct
net
*
net
;
file
=
proc_ns_fget
(
fd
);
if
(
IS_ERR
(
file
))
return
ERR_CAST
(
file
);
ei
=
get_proc_ns
(
file_inode
(
file
));
if
(
ei
->
ns_
ops
==
&
netns_operations
)
net
=
get_net
(
ei
->
ns
);
ns
=
get_proc_ns
(
file_inode
(
file
));
if
(
ns
->
ops
==
&
netns_operations
)
net
=
get_net
(
container_of
(
ns
,
struct
net
,
ns
)
);
else
net
=
ERR_PTR
(
-
EINVAL
);
...
...
@@ -386,12 +386,15 @@ EXPORT_SYMBOL_GPL(get_net_ns_by_pid);
static
__net_init
int
net_ns_net_init
(
struct
net
*
net
)
{
return
proc_alloc_inum
(
&
net
->
proc_inum
);
#ifdef CONFIG_NET_NS
net
->
ns
.
ops
=
&
netns_operations
;
#endif
return
ns_alloc_inum
(
&
net
->
ns
);
}
static
__net_exit
void
net_ns_net_exit
(
struct
net
*
net
)
{
proc_free_inum
(
net
->
proc_inum
);
ns_free_inum
(
&
net
->
ns
);
}
static
struct
pernet_operations
__net_initdata
net_ns_ops
=
{
...
...
@@ -629,7 +632,7 @@ void unregister_pernet_device(struct pernet_operations *ops)
EXPORT_SYMBOL_GPL
(
unregister_pernet_device
);
#ifdef CONFIG_NET_NS
static
void
*
netns_get
(
struct
task_struct
*
task
)
static
struct
ns_common
*
netns_get
(
struct
task_struct
*
task
)
{
struct
net
*
net
=
NULL
;
struct
nsproxy
*
nsproxy
;
...
...
@@ -640,17 +643,22 @@ static void *netns_get(struct task_struct *task)
net
=
get_net
(
nsproxy
->
net_ns
);
task_unlock
(
task
);
return
net
;
return
net
?
&
net
->
ns
:
NULL
;
}
static
void
netns_put
(
void
*
ns
)
static
inline
struct
net
*
to_net_ns
(
struct
ns_common
*
ns
)
{
put_net
(
ns
);
return
container_of
(
ns
,
struct
net
,
ns
);
}
static
int
netns_install
(
struct
nsproxy
*
nsproxy
,
void
*
ns
)
static
void
netns_put
(
struct
ns_common
*
ns
)
{
struct
net
*
net
=
ns
;
put_net
(
to_net_ns
(
ns
));
}
static
int
netns_install
(
struct
nsproxy
*
nsproxy
,
struct
ns_common
*
ns
)
{
struct
net
*
net
=
to_net_ns
(
ns
);
if
(
!
ns_capable
(
net
->
user_ns
,
CAP_SYS_ADMIN
)
||
!
ns_capable
(
current_user_ns
(),
CAP_SYS_ADMIN
))
...
...
@@ -661,18 +669,11 @@ static int netns_install(struct nsproxy *nsproxy, void *ns)
return
0
;
}
static
unsigned
int
netns_inum
(
void
*
ns
)
{
struct
net
*
net
=
ns
;
return
net
->
proc_inum
;
}
const
struct
proc_ns_operations
netns_operations
=
{
.
name
=
"net"
,
.
type
=
CLONE_NEWNET
,
.
get
=
netns_get
,
.
put
=
netns_put
,
.
install
=
netns_install
,
.
inum
=
netns_inum
,
};
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录