Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
09302fd1
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
09302fd1
编写于
10月 21, 2015
作者:
J
James Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'smack-for-4.4' of
https://github.com/cschaufler/smack-next
into next
上级
fbf98265
38416e53
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
248 addition
and
47 deletion
+248
-47
Documentation/security/Smack.txt
Documentation/security/Smack.txt
+10
-0
security/smack/smack.h
security/smack/smack.h
+3
-1
security/smack/smack_access.c
security/smack/smack_access.c
+3
-3
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+62
-5
security/smack/smackfs.c
security/smack/smackfs.c
+170
-38
未找到文件。
Documentation/security/Smack.txt
浏览文件 @
09302fd1
...
...
@@ -255,6 +255,16 @@ unconfined
the access permitted if it wouldn't be otherwise. Note that this
is dangerous and can ruin the proper labeling of your system.
It should never be used in production.
relabel-self
This interface contains a list of labels to which the process can
transition to, by writing to /proc/self/attr/current.
Normally a process can change its own label to any legal value, but only
if it has CAP_MAC_ADMIN. This interface allows a process without
CAP_MAC_ADMIN to relabel itself to one of labels from predefined list.
A process without CAP_MAC_ADMIN can change its label only once. When it
does, this list will be cleared.
The values are set by writing the desired labels, separated
by spaces, to the file or cleared by writing "-" to the file.
If you are using the smackload utility
you can add access rules in /etc/smack/accesses. They take the form:
...
...
security/smack/smack.h
浏览文件 @
09302fd1
...
...
@@ -115,6 +115,7 @@ struct task_smack {
struct
smack_known
*
smk_forked
;
/* label when forked */
struct
list_head
smk_rules
;
/* per task access rules */
struct
mutex
smk_rules_lock
;
/* lock for the rules */
struct
list_head
smk_relabel
;
/* transit allowed labels */
};
#define SMK_INODE_INSTANT 0x01
/* inode is instantiated */
...
...
@@ -169,7 +170,7 @@ struct smk_port_label {
};
#endif
/* SMACK_IPV6_PORT_LABELING */
struct
smack_
onlycap
{
struct
smack_
known_list_elem
{
struct
list_head
list
;
struct
smack_known
*
smk_label
;
};
...
...
@@ -301,6 +302,7 @@ struct smack_known *smk_import_entry(const char *, int);
void
smk_insert_entry
(
struct
smack_known
*
skp
);
struct
smack_known
*
smk_find_entry
(
const
char
*
);
int
smack_privileged
(
int
cap
);
void
smk_destroy_label_list
(
struct
list_head
*
list
);
/*
* Shared data.
...
...
security/smack/smack_access.c
浏览文件 @
09302fd1
...
...
@@ -637,7 +637,7 @@ DEFINE_MUTEX(smack_onlycap_lock);
int
smack_privileged
(
int
cap
)
{
struct
smack_known
*
skp
=
smk_of_current
();
struct
smack_
onlycap
*
so
p
;
struct
smack_
known_list_elem
*
skle
p
;
/*
* All kernel tasks are privileged
...
...
@@ -654,8 +654,8 @@ int smack_privileged(int cap)
return
1
;
}
list_for_each_entry_rcu
(
s
o
p
,
&
smack_onlycap_list
,
list
)
{
if
(
s
o
p
->
smk_label
==
skp
)
{
list_for_each_entry_rcu
(
s
kle
p
,
&
smack_onlycap_list
,
list
)
{
if
(
s
kle
p
->
smk_label
==
skp
)
{
rcu_read_unlock
();
return
1
;
}
...
...
security/smack/smack_lsm.c
浏览文件 @
09302fd1
...
...
@@ -52,7 +52,7 @@
#define SMK_SENDING 2
#ifdef SMACK_IPV6_PORT_LABELING
LIST_HEAD
(
smk_ipv6_port_list
);
static
LIST_HEAD
(
smk_ipv6_port_list
);
#endif
static
struct
kmem_cache
*
smack_inode_cache
;
int
smack_enabled
;
...
...
@@ -326,6 +326,7 @@ static struct task_smack *new_task_smack(struct smack_known *task,
tsp
->
smk_task
=
task
;
tsp
->
smk_forked
=
forked
;
INIT_LIST_HEAD
(
&
tsp
->
smk_rules
);
INIT_LIST_HEAD
(
&
tsp
->
smk_relabel
);
mutex_init
(
&
tsp
->
smk_rules_lock
);
return
tsp
;
...
...
@@ -360,6 +361,35 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
return
rc
;
}
/**
* smk_copy_relabel - copy smk_relabel labels list
* @nhead: new rules header pointer
* @ohead: old rules header pointer
* @gfp: type of the memory for the allocation
*
* Returns 0 on success, -ENOMEM on error
*/
static
int
smk_copy_relabel
(
struct
list_head
*
nhead
,
struct
list_head
*
ohead
,
gfp_t
gfp
)
{
struct
smack_known_list_elem
*
nklep
;
struct
smack_known_list_elem
*
oklep
;
INIT_LIST_HEAD
(
nhead
);
list_for_each_entry
(
oklep
,
ohead
,
list
)
{
nklep
=
kzalloc
(
sizeof
(
struct
smack_known_list_elem
),
gfp
);
if
(
nklep
==
NULL
)
{
smk_destroy_label_list
(
nhead
);
return
-
ENOMEM
;
}
nklep
->
smk_label
=
oklep
->
smk_label
;
list_add
(
&
nklep
->
list
,
nhead
);
}
return
0
;
}
/**
* smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
* @mode - input mode in form of PTRACE_MODE_*
...
...
@@ -1922,6 +1952,8 @@ static void smack_cred_free(struct cred *cred)
return
;
cred
->
security
=
NULL
;
smk_destroy_label_list
(
&
tsp
->
smk_relabel
);
list_for_each_safe
(
l
,
n
,
&
tsp
->
smk_rules
)
{
rp
=
list_entry
(
l
,
struct
smack_rule
,
list
);
list_del
(
&
rp
->
list
);
...
...
@@ -1953,6 +1985,11 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
if
(
rc
!=
0
)
return
rc
;
rc
=
smk_copy_relabel
(
&
new_tsp
->
smk_relabel
,
&
old_tsp
->
smk_relabel
,
gfp
);
if
(
rc
!=
0
)
return
rc
;
new
->
security
=
new_tsp
;
return
0
;
}
...
...
@@ -3354,6 +3391,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
isp
->
smk_inode
=
smk_of_current
();
break
;
case
PIPEFS_MAGIC
:
isp
->
smk_inode
=
smk_of_current
();
break
;
default:
isp
->
smk_inode
=
sbsp
->
smk_root
;
break
;
...
...
@@ -3549,9 +3589,11 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
static
int
smack_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
task_smack
*
tsp
;
struct
task_smack
*
tsp
=
current_security
()
;
struct
cred
*
new
;
struct
smack_known
*
skp
;
struct
smack_known_list_elem
*
sklep
;
int
rc
;
/*
* Changing another process' Smack value is too dangerous
...
...
@@ -3560,7 +3602,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
if
(
p
!=
current
)
return
-
EPERM
;
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
)
&&
list_empty
(
&
tsp
->
smk_relabel
)
)
return
-
EPERM
;
if
(
value
==
NULL
||
size
==
0
||
size
>=
SMK_LONGLABEL
)
...
...
@@ -3579,12 +3621,27 @@ static int smack_setprocattr(struct task_struct *p, char *name,
if
(
skp
==
&
smack_known_web
)
return
-
EPERM
;
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
{
rc
=
-
EPERM
;
list_for_each_entry
(
sklep
,
&
tsp
->
smk_relabel
,
list
)
if
(
sklep
->
smk_label
==
skp
)
{
rc
=
0
;
break
;
}
if
(
rc
)
return
rc
;
}
new
=
prepare_creds
();
if
(
new
==
NULL
)
return
-
ENOMEM
;
tsp
=
new
->
security
;
tsp
->
smk_task
=
skp
;
/*
* process can change its label only once
*/
smk_destroy_label_list
(
&
tsp
->
smk_relabel
);
commit_creds
(
new
);
return
size
;
...
...
@@ -4708,8 +4765,6 @@ static __init int smack_init(void)
if
(
!
security_module_enable
(
"smack"
))
return
0
;
smack_enabled
=
1
;
smack_inode_cache
=
KMEM_CACHE
(
inode_smack
,
0
);
if
(
!
smack_inode_cache
)
return
-
ENOMEM
;
...
...
@@ -4721,6 +4776,8 @@ static __init int smack_init(void)
return
-
ENOMEM
;
}
smack_enabled
=
1
;
pr_info
(
"Smack: Initializing.
\n
"
);
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
pr_info
(
"Smack: Netfilter enabled.
\n
"
);
...
...
security/smack/smackfs.c
浏览文件 @
09302fd1
...
...
@@ -61,6 +61,7 @@ enum smk_inos {
#if IS_ENABLED(CONFIG_IPV6)
SMK_NET6ADDR
=
23
,
/* single label IPv6 hosts */
#endif
/* CONFIG_IPV6 */
SMK_RELABEL_SELF
=
24
,
/* relabel possible without CAP_MAC_ADMIN */
};
/*
...
...
@@ -1501,8 +1502,8 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
*/
if
(
smack
[
0
]
!=
'-'
)
{
skp
=
smk_import_entry
(
smack
,
0
);
if
(
skp
==
NULL
)
{
rc
=
-
EINVAL
;
if
(
IS_ERR
(
skp
)
)
{
rc
=
PTR_ERR
(
skp
)
;
goto
free_out
;
}
}
else
{
...
...
@@ -1914,10 +1915,10 @@ static void *onlycap_seq_next(struct seq_file *s, void *v, loff_t *pos)
static
int
onlycap_seq_show
(
struct
seq_file
*
s
,
void
*
v
)
{
struct
list_head
*
list
=
v
;
struct
smack_
onlycap
*
so
p
=
list_entry_rcu
(
list
,
struct
smack_
onlycap
,
list
);
struct
smack_
known_list_elem
*
skle
p
=
list_entry_rcu
(
list
,
struct
smack_
known_list_elem
,
list
);
seq_puts
(
s
,
s
o
p
->
smk_label
->
smk_known
);
seq_puts
(
s
,
s
kle
p
->
smk_label
->
smk_known
);
seq_putc
(
s
,
' '
);
return
0
;
...
...
@@ -1973,6 +1974,54 @@ static void smk_list_swap_rcu(struct list_head *public,
}
}
/**
* smk_parse_label_list - parse list of Smack labels, separated by spaces
*
* @data: the string to parse
* @private: destination list
*
* Returns zero on success or error code, as appropriate
*/
static
int
smk_parse_label_list
(
char
*
data
,
struct
list_head
*
list
)
{
char
*
tok
;
struct
smack_known
*
skp
;
struct
smack_known_list_elem
*
sklep
;
while
((
tok
=
strsep
(
&
data
,
" "
))
!=
NULL
)
{
if
(
!*
tok
)
continue
;
skp
=
smk_import_entry
(
tok
,
0
);
if
(
IS_ERR
(
skp
))
return
PTR_ERR
(
skp
);
sklep
=
kzalloc
(
sizeof
(
*
sklep
),
GFP_KERNEL
);
if
(
sklep
==
NULL
)
return
-
ENOMEM
;
sklep
->
smk_label
=
skp
;
list_add
(
&
sklep
->
list
,
list
);
}
return
0
;
}
/**
* smk_destroy_label_list - destroy a list of smack_known_list_elem
* @head: header pointer of the list to destroy
*/
void
smk_destroy_label_list
(
struct
list_head
*
list
)
{
struct
smack_known_list_elem
*
sklep
;
struct
smack_known_list_elem
*
sklep2
;
list_for_each_entry_safe
(
sklep
,
sklep2
,
list
,
list
)
kfree
(
sklep
);
INIT_LIST_HEAD
(
list
);
}
/**
* smk_write_onlycap - write() for smackfs/onlycap
* @file: file pointer, not actually used
...
...
@@ -1986,13 +2035,8 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
char
*
data
;
char
*
data_parse
;
char
*
tok
;
struct
smack_known
*
skp
;
struct
smack_onlycap
*
sop
;
struct
smack_onlycap
*
sop2
;
LIST_HEAD
(
list_tmp
);
int
rc
=
count
;
int
rc
;
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
return
-
EPERM
;
...
...
@@ -2006,26 +2050,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
return
-
EFAULT
;
}
data_parse
=
data
;
while
((
tok
=
strsep
(
&
data_parse
,
" "
))
!=
NULL
)
{
if
(
!*
tok
)
continue
;
skp
=
smk_import_entry
(
tok
,
0
);
if
(
IS_ERR
(
skp
))
{
rc
=
PTR_ERR
(
skp
);
break
;
}
sop
=
kzalloc
(
sizeof
(
*
sop
),
GFP_KERNEL
);
if
(
sop
==
NULL
)
{
rc
=
-
ENOMEM
;
break
;
}
sop
->
smk_label
=
skp
;
list_add_rcu
(
&
sop
->
list
,
&
list_tmp
);
}
rc
=
smk_parse_label_list
(
data
,
&
list_tmp
);
kfree
(
data
);
/*
...
...
@@ -2038,17 +2063,14 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
* But do so only on invalid label, not on system errors.
* The invalid label must be first to count as clearing attempt.
*/
if
(
rc
==
-
EINVAL
&&
list_empty
(
&
list_tmp
))
rc
=
count
;
if
(
rc
>=
0
)
{
if
(
!
rc
||
(
rc
==
-
EINVAL
&&
list_empty
(
&
list_tmp
)))
{
mutex_lock
(
&
smack_onlycap_lock
);
smk_list_swap_rcu
(
&
smack_onlycap_list
,
&
list_tmp
);
mutex_unlock
(
&
smack_onlycap_lock
);
rc
=
count
;
}
list_for_each_entry_safe
(
sop
,
sop2
,
&
list_tmp
,
list
)
kfree
(
sop
);
smk_destroy_label_list
(
&
list_tmp
);
return
rc
;
}
...
...
@@ -2698,6 +2720,113 @@ static const struct file_operations smk_syslog_ops = {
.
llseek
=
default_llseek
,
};
/*
* Seq_file read operations for /smack/relabel-self
*/
static
void
*
relabel_self_seq_start
(
struct
seq_file
*
s
,
loff_t
*
pos
)
{
struct
task_smack
*
tsp
=
current_security
();
return
smk_seq_start
(
s
,
pos
,
&
tsp
->
smk_relabel
);
}
static
void
*
relabel_self_seq_next
(
struct
seq_file
*
s
,
void
*
v
,
loff_t
*
pos
)
{
struct
task_smack
*
tsp
=
current_security
();
return
smk_seq_next
(
s
,
v
,
pos
,
&
tsp
->
smk_relabel
);
}
static
int
relabel_self_seq_show
(
struct
seq_file
*
s
,
void
*
v
)
{
struct
list_head
*
list
=
v
;
struct
smack_known_list_elem
*
sklep
=
list_entry
(
list
,
struct
smack_known_list_elem
,
list
);
seq_puts
(
s
,
sklep
->
smk_label
->
smk_known
);
seq_putc
(
s
,
' '
);
return
0
;
}
static
const
struct
seq_operations
relabel_self_seq_ops
=
{
.
start
=
relabel_self_seq_start
,
.
next
=
relabel_self_seq_next
,
.
show
=
relabel_self_seq_show
,
.
stop
=
smk_seq_stop
,
};
/**
* smk_open_relabel_self - open() for /smack/relabel-self
* @inode: inode structure representing file
* @file: "relabel-self" file pointer
*
* Connect our relabel_self_seq_* operations with /smack/relabel-self
* file_operations
*/
static
int
smk_open_relabel_self
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
relabel_self_seq_ops
);
}
/**
* smk_write_relabel_self - write() for /smack/relabel-self
* @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start - must be 0
*
*/
static
ssize_t
smk_write_relabel_self
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
task_smack
*
tsp
=
current_security
();
char
*
data
;
int
rc
;
LIST_HEAD
(
list_tmp
);
/*
* Must have privilege.
*/
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
return
-
EPERM
;
/*
* Enough data must be present.
*/
if
(
*
ppos
!=
0
)
return
-
EINVAL
;
data
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
data
==
NULL
)
return
-
ENOMEM
;
if
(
copy_from_user
(
data
,
buf
,
count
)
!=
0
)
{
kfree
(
data
);
return
-
EFAULT
;
}
rc
=
smk_parse_label_list
(
data
,
&
list_tmp
);
kfree
(
data
);
if
(
!
rc
||
(
rc
==
-
EINVAL
&&
list_empty
(
&
list_tmp
)))
{
smk_destroy_label_list
(
&
tsp
->
smk_relabel
);
list_splice
(
&
list_tmp
,
&
tsp
->
smk_relabel
);
return
count
;
}
smk_destroy_label_list
(
&
list_tmp
);
return
rc
;
}
static
const
struct
file_operations
smk_relabel_self_ops
=
{
.
open
=
smk_open_relabel_self
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
write
=
smk_write_relabel_self
,
.
release
=
seq_release
,
};
/**
* smk_read_ptrace - read() for /smack/ptrace
...
...
@@ -2824,6 +2953,9 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
[
SMK_NET6ADDR
]
=
{
"ipv6host"
,
&
smk_net6addr_ops
,
S_IRUGO
|
S_IWUSR
},
#endif
/* CONFIG_IPV6 */
[
SMK_RELABEL_SELF
]
=
{
"relabel-self"
,
&
smk_relabel_self_ops
,
S_IRUGO
|
S_IWUGO
},
/* last one */
{
""
}
};
...
...
@@ -2892,7 +3024,7 @@ static int __init init_smk_fs(void)
int
err
;
int
rc
;
if
(
!
security_module_enable
(
"smack"
)
)
if
(
smack_enabled
==
0
)
return
0
;
err
=
smk_init_sysfs
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录