Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
ff2bb047
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看板
提交
ff2bb047
编写于
5月 22, 2012
作者:
J
James Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.infradead.org/users/eparis/selinux
into next
Per pull request, for 3.5.
上级
cffee16e
c737f828
变更
33
展开全部
隐藏空白更改
内联
并排
Showing
33 changed file
with
422 addition
and
350 deletion
+422
-350
fs/open.c
fs/open.c
+1
-1
include/linux/lsm_audit.h
include/linux/lsm_audit.h
+0
-6
include/linux/security.h
include/linux/security.h
+5
-8
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_policy.c
+1
-0
security/apparmor/audit.c
security/apparmor/audit.c
+9
-2
security/apparmor/capability.c
security/apparmor/capability.c
+2
-2
security/apparmor/file.c
security/apparmor/file.c
+1
-1
security/apparmor/include/audit.h
security/apparmor/include/audit.h
+1
-0
security/apparmor/ipc.c
security/apparmor/ipc.c
+1
-1
security/apparmor/lib.c
security/apparmor/lib.c
+1
-1
security/apparmor/lsm.c
security/apparmor/lsm.c
+3
-3
security/apparmor/policy.c
security/apparmor/policy.c
+1
-1
security/apparmor/policy_unpack.c
security/apparmor/policy_unpack.c
+1
-1
security/apparmor/resource.c
security/apparmor/resource.c
+1
-1
security/capability.c
security/capability.c
+2
-2
security/lsm_audit.c
security/lsm_audit.c
+9
-6
security/security.c
security/security.c
+2
-2
security/selinux/avc.c
security/selinux/avc.c
+24
-106
security/selinux/hooks.c
security/selinux/hooks.c
+118
-140
security/selinux/include/avc.h
security/selinux/include/avc.h
+77
-23
security/selinux/include/security.h
security/selinux/include/security.h
+3
-1
security/selinux/netif.c
security/selinux/netif.c
+2
-4
security/selinux/netnode.c
security/selinux/netnode.c
+2
-4
security/selinux/netport.c
security/selinux/netport.c
+2
-4
security/selinux/selinuxfs.c
security/selinux/selinuxfs.c
+4
-7
security/selinux/ss/context.h
security/selinux/ss/context.h
+20
-0
security/selinux/ss/mls.c
security/selinux/ss/mls.c
+24
-0
security/selinux/ss/policydb.c
security/selinux/ss/policydb.c
+44
-0
security/selinux/ss/policydb.h
security/selinux/ss/policydb.h
+14
-0
security/selinux/ss/services.c
security/selinux/ss/services.c
+40
-16
security/smack/smack.h
security/smack/smack.h
+1
-1
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+3
-3
security/tomoyo/tomoyo.c
security/tomoyo/tomoyo.c
+3
-3
未找到文件。
fs/open.c
浏览文件 @
ff2bb047
...
@@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
...
@@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f
->
f_op
=
fops_get
(
inode
->
i_fop
);
f
->
f_op
=
fops_get
(
inode
->
i_fop
);
error
=
security_
dentry
_open
(
f
,
cred
);
error
=
security_
file
_open
(
f
,
cred
);
if
(
error
)
if
(
error
)
goto
cleanup_all
;
goto
cleanup_all
;
...
...
include/linux/lsm_audit.h
浏览文件 @
ff2bb047
...
@@ -53,7 +53,6 @@ struct common_audit_data {
...
@@ -53,7 +53,6 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9
#define LSM_AUDIT_DATA_INODE 9
#define LSM_AUDIT_DATA_DENTRY 10
#define LSM_AUDIT_DATA_DENTRY 10
struct
task_struct
*
tsk
;
union
{
union
{
struct
path
path
;
struct
path
path
;
struct
dentry
*
dentry
;
struct
dentry
*
dentry
;
...
@@ -93,11 +92,6 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
...
@@ -93,11 +92,6 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
int
ipv6_skb_to_auditdata
(
struct
sk_buff
*
skb
,
int
ipv6_skb_to_auditdata
(
struct
sk_buff
*
skb
,
struct
common_audit_data
*
ad
,
u8
*
proto
);
struct
common_audit_data
*
ad
,
u8
*
proto
);
/* Initialize an LSM audit data structure. */
#define COMMON_AUDIT_DATA_INIT(_d, _t) \
{ memset((_d), 0, sizeof(struct common_audit_data)); \
(_d)->type = LSM_AUDIT_DATA_##_t; }
void
common_lsm_audit
(
struct
common_audit_data
*
a
,
void
common_lsm_audit
(
struct
common_audit_data
*
a
,
void
(
*
pre_audit
)(
struct
audit_buffer
*
,
void
*
),
void
(
*
pre_audit
)(
struct
audit_buffer
*
,
void
*
),
void
(
*
post_audit
)(
struct
audit_buffer
*
,
void
*
));
void
(
*
post_audit
)(
struct
audit_buffer
*
,
void
*
));
...
...
include/linux/security.h
浏览文件 @
ff2bb047
...
@@ -640,10 +640,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
...
@@ -640,10 +640,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* to receive an open file descriptor via socket IPC.
* to receive an open file descriptor via socket IPC.
* @file contains the file structure being received.
* @file contains the file structure being received.
* Return 0 if permission is granted.
* Return 0 if permission is granted.
*
* @file_open
* Security hook for dentry
*
* @dentry_open
* Save open-time permission checking state for later use upon
* Save open-time permission checking state for later use upon
* file_permission, and recheck access if anything has changed
* file_permission, and recheck access if anything has changed
* since inode_permission.
* since inode_permission.
...
@@ -1498,7 +1495,7 @@ struct security_operations {
...
@@ -1498,7 +1495,7 @@ struct security_operations {
int
(
*
file_send_sigiotask
)
(
struct
task_struct
*
tsk
,
int
(
*
file_send_sigiotask
)
(
struct
task_struct
*
tsk
,
struct
fown_struct
*
fown
,
int
sig
);
struct
fown_struct
*
fown
,
int
sig
);
int
(
*
file_receive
)
(
struct
file
*
file
);
int
(
*
file_receive
)
(
struct
file
*
file
);
int
(
*
dentry
_open
)
(
struct
file
*
file
,
const
struct
cred
*
cred
);
int
(
*
file
_open
)
(
struct
file
*
file
,
const
struct
cred
*
cred
);
int
(
*
task_create
)
(
unsigned
long
clone_flags
);
int
(
*
task_create
)
(
unsigned
long
clone_flags
);
void
(
*
task_free
)
(
struct
task_struct
*
task
);
void
(
*
task_free
)
(
struct
task_struct
*
task
);
...
@@ -1757,7 +1754,7 @@ int security_file_set_fowner(struct file *file);
...
@@ -1757,7 +1754,7 @@ int security_file_set_fowner(struct file *file);
int
security_file_send_sigiotask
(
struct
task_struct
*
tsk
,
int
security_file_send_sigiotask
(
struct
task_struct
*
tsk
,
struct
fown_struct
*
fown
,
int
sig
);
struct
fown_struct
*
fown
,
int
sig
);
int
security_file_receive
(
struct
file
*
file
);
int
security_file_receive
(
struct
file
*
file
);
int
security_
dentry
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
);
int
security_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
);
int
security_task_create
(
unsigned
long
clone_flags
);
int
security_task_create
(
unsigned
long
clone_flags
);
void
security_task_free
(
struct
task_struct
*
task
);
void
security_task_free
(
struct
task_struct
*
task
);
int
security_cred_alloc_blank
(
struct
cred
*
cred
,
gfp_t
gfp
);
int
security_cred_alloc_blank
(
struct
cred
*
cred
,
gfp_t
gfp
);
...
@@ -2228,8 +2225,8 @@ static inline int security_file_receive(struct file *file)
...
@@ -2228,8 +2225,8 @@ static inline int security_file_receive(struct file *file)
return
0
;
return
0
;
}
}
static
inline
int
security_
dentry
_open
(
struct
file
*
file
,
static
inline
int
security_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
const
struct
cred
*
cred
)
{
{
return
0
;
return
0
;
}
}
...
...
net/xfrm/xfrm_policy.c
浏览文件 @
ff2bb047
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <linux/cache.h>
#include <linux/cache.h>
#include <linux/audit.h>
#include <linux/audit.h>
#include <net/dst.h>
#include <net/dst.h>
#include <net/flow.h>
#include <net/xfrm.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/ip.h>
#ifdef CONFIG_XFRM_STATISTICS
#ifdef CONFIG_XFRM_STATISTICS
...
...
security/apparmor/audit.c
浏览文件 @
ff2bb047
...
@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = {
...
@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = {
static
void
audit_pre
(
struct
audit_buffer
*
ab
,
void
*
ca
)
static
void
audit_pre
(
struct
audit_buffer
*
ab
,
void
*
ca
)
{
{
struct
common_audit_data
*
sa
=
ca
;
struct
common_audit_data
*
sa
=
ca
;
struct
task_struct
*
tsk
=
sa
->
tsk
?
sa
->
tsk
:
current
;
struct
task_struct
*
tsk
=
sa
->
aad
->
tsk
?
sa
->
aad
->
tsk
:
current
;
if
(
aa_g_audit_header
)
{
if
(
aa_g_audit_header
)
{
audit_log_format
(
ab
,
"apparmor="
);
audit_log_format
(
ab
,
"apparmor="
);
...
@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
...
@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
audit_log_format
(
ab
,
" name="
);
audit_log_format
(
ab
,
" name="
);
audit_log_untrustedstring
(
ab
,
sa
->
aad
->
name
);
audit_log_untrustedstring
(
ab
,
sa
->
aad
->
name
);
}
}
if
(
sa
->
aad
->
tsk
)
{
audit_log_format
(
ab
,
" pid=%d comm="
,
tsk
->
pid
);
audit_log_untrustedstring
(
ab
,
tsk
->
comm
);
}
}
}
/**
/**
...
@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
...
@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
aa_audit_msg
(
type
,
sa
,
cb
);
aa_audit_msg
(
type
,
sa
,
cb
);
if
(
sa
->
aad
->
type
==
AUDIT_APPARMOR_KILL
)
if
(
sa
->
aad
->
type
==
AUDIT_APPARMOR_KILL
)
(
void
)
send_sig_info
(
SIGKILL
,
NULL
,
sa
->
tsk
?
sa
->
tsk
:
current
);
(
void
)
send_sig_info
(
SIGKILL
,
NULL
,
sa
->
aad
->
tsk
?
sa
->
aad
->
tsk
:
current
);
if
(
sa
->
aad
->
type
==
AUDIT_APPARMOR_ALLOWED
)
if
(
sa
->
aad
->
type
==
AUDIT_APPARMOR_ALLOWED
)
return
complain_error
(
sa
->
aad
->
error
);
return
complain_error
(
sa
->
aad
->
error
);
...
...
security/apparmor/capability.c
浏览文件 @
ff2bb047
...
@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
...
@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
int
type
=
AUDIT_APPARMOR_AUTO
;
int
type
=
AUDIT_APPARMOR_AUTO
;
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
CAP
)
;
sa
.
type
=
LSM_AUDIT_DATA_CAP
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
sa
.
tsk
=
task
;
sa
.
u
.
cap
=
cap
;
sa
.
u
.
cap
=
cap
;
sa
.
aad
->
tsk
=
task
;
sa
.
aad
->
op
=
OP_CAPABLE
;
sa
.
aad
->
op
=
OP_CAPABLE
;
sa
.
aad
->
error
=
error
;
sa
.
aad
->
error
=
error
;
...
...
security/apparmor/file.c
浏览文件 @
ff2bb047
...
@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
...
@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
int
type
=
AUDIT_APPARMOR_AUTO
;
int
type
=
AUDIT_APPARMOR_AUTO
;
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
op
=
op
,
aad
.
op
=
op
,
aad
.
fs
.
request
=
request
;
aad
.
fs
.
request
=
request
;
...
...
security/apparmor/include/audit.h
浏览文件 @
ff2bb047
...
@@ -110,6 +110,7 @@ struct apparmor_audit_data {
...
@@ -110,6 +110,7 @@ struct apparmor_audit_data {
void
*
profile
;
void
*
profile
;
const
char
*
name
;
const
char
*
name
;
const
char
*
info
;
const
char
*
info
;
struct
task_struct
*
tsk
;
union
{
union
{
void
*
target
;
void
*
target
;
struct
{
struct
{
...
...
security/apparmor/ipc.c
浏览文件 @
ff2bb047
...
@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile,
...
@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile,
{
{
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
op
=
OP_PTRACE
;
aad
.
op
=
OP_PTRACE
;
aad
.
target
=
target
;
aad
.
target
=
target
;
...
...
security/apparmor/lib.c
浏览文件 @
ff2bb047
...
@@ -66,7 +66,7 @@ void aa_info_message(const char *str)
...
@@ -66,7 +66,7 @@ void aa_info_message(const char *str)
if
(
audit_enabled
)
{
if
(
audit_enabled
)
{
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
info
=
str
;
aad
.
info
=
str
;
aa_audit_msg
(
AUDIT_APPARMOR_STATUS
,
&
sa
,
NULL
);
aa_audit_msg
(
AUDIT_APPARMOR_STATUS
,
&
sa
,
NULL
);
...
...
security/apparmor/lsm.c
浏览文件 @
ff2bb047
...
@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
...
@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
AA_MAY_META_READ
);
AA_MAY_META_READ
);
}
}
static
int
apparmor_
dentry
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
static
int
apparmor_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
{
struct
aa_file_cxt
*
fcxt
=
file
->
f_security
;
struct
aa_file_cxt
*
fcxt
=
file
->
f_security
;
struct
aa_profile
*
profile
;
struct
aa_profile
*
profile
;
...
@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
...
@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
}
else
{
}
else
{
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
op
=
OP_SETPROCATTR
;
aad
.
op
=
OP_SETPROCATTR
;
aad
.
info
=
name
;
aad
.
info
=
name
;
...
@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = {
...
@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = {
.
path_chmod
=
apparmor_path_chmod
,
.
path_chmod
=
apparmor_path_chmod
,
.
path_chown
=
apparmor_path_chown
,
.
path_chown
=
apparmor_path_chown
,
.
path_truncate
=
apparmor_path_truncate
,
.
path_truncate
=
apparmor_path_truncate
,
.
dentry_open
=
apparmor_dentry_open
,
.
inode_getattr
=
apparmor_inode_getattr
,
.
inode_getattr
=
apparmor_inode_getattr
,
.
file_open
=
apparmor_file_open
,
.
file_permission
=
apparmor_file_permission
,
.
file_permission
=
apparmor_file_permission
,
.
file_alloc_security
=
apparmor_file_alloc_security
,
.
file_alloc_security
=
apparmor_file_alloc_security
,
.
file_free_security
=
apparmor_file_free_security
,
.
file_free_security
=
apparmor_file_free_security
,
...
...
security/apparmor/policy.c
浏览文件 @
ff2bb047
...
@@ -969,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
...
@@ -969,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
{
{
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
op
=
op
;
aad
.
op
=
op
;
aad
.
name
=
name
;
aad
.
name
=
name
;
...
...
security/apparmor/policy_unpack.c
浏览文件 @
ff2bb047
...
@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name,
...
@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name,
struct
aa_profile
*
profile
=
__aa_current_profile
();
struct
aa_profile
*
profile
=
__aa_current_profile
();
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
if
(
e
)
if
(
e
)
aad
.
iface
.
pos
=
e
->
pos
-
e
->
start
;
aad
.
iface
.
pos
=
e
->
pos
-
e
->
start
;
...
...
security/apparmor/resource.c
浏览文件 @
ff2bb047
...
@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource,
...
@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource,
struct
common_audit_data
sa
;
struct
common_audit_data
sa
;
struct
apparmor_audit_data
aad
=
{
0
,};
struct
apparmor_audit_data
aad
=
{
0
,};
COMMON_AUDIT_DATA_INIT
(
&
sa
,
NONE
)
;
sa
.
type
=
LSM_AUDIT_DATA_NONE
;
sa
.
aad
=
&
aad
;
sa
.
aad
=
&
aad
;
aad
.
op
=
OP_SETRLIMIT
,
aad
.
op
=
OP_SETRLIMIT
,
aad
.
rlim
.
rlim
=
resource
;
aad
.
rlim
.
rlim
=
resource
;
...
...
security/capability.c
浏览文件 @
ff2bb047
...
@@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file)
...
@@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file)
return
0
;
return
0
;
}
}
static
int
cap_
dentry
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
static
int
cap_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
{
return
0
;
return
0
;
}
}
...
@@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops)
...
@@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null
(
ops
,
file_set_fowner
);
set_to_cap_if_null
(
ops
,
file_set_fowner
);
set_to_cap_if_null
(
ops
,
file_send_sigiotask
);
set_to_cap_if_null
(
ops
,
file_send_sigiotask
);
set_to_cap_if_null
(
ops
,
file_receive
);
set_to_cap_if_null
(
ops
,
file_receive
);
set_to_cap_if_null
(
ops
,
dentry
_open
);
set_to_cap_if_null
(
ops
,
file
_open
);
set_to_cap_if_null
(
ops
,
task_create
);
set_to_cap_if_null
(
ops
,
task_create
);
set_to_cap_if_null
(
ops
,
task_free
);
set_to_cap_if_null
(
ops
,
task_free
);
set_to_cap_if_null
(
ops
,
cred_alloc_blank
);
set_to_cap_if_null
(
ops
,
cred_alloc_blank
);
...
...
security/lsm_audit.c
浏览文件 @
ff2bb047
...
@@ -213,12 +213,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
...
@@ -213,12 +213,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
{
{
struct
task_struct
*
tsk
=
current
;
struct
task_struct
*
tsk
=
current
;
if
(
a
->
tsk
)
/*
tsk
=
a
->
tsk
;
* To keep stack sizes in check force programers to notice if they
if
(
tsk
&&
tsk
->
pid
)
{
* start making this union too large! See struct lsm_network_audit
audit_log_format
(
ab
,
" pid=%d comm="
,
tsk
->
pid
);
* as an example of how to deal with large data.
audit_log_untrustedstring
(
ab
,
tsk
->
comm
);
*/
}
BUILD_BUG_ON
(
sizeof
(
a
->
u
)
>
sizeof
(
void
*
)
*
2
);
audit_log_format
(
ab
,
" pid=%d comm="
,
tsk
->
pid
);
audit_log_untrustedstring
(
ab
,
tsk
->
comm
);
switch
(
a
->
type
)
{
switch
(
a
->
type
)
{
case
LSM_AUDIT_DATA_NONE
:
case
LSM_AUDIT_DATA_NONE
:
...
...
security/security.c
浏览文件 @
ff2bb047
...
@@ -701,11 +701,11 @@ int security_file_receive(struct file *file)
...
@@ -701,11 +701,11 @@ int security_file_receive(struct file *file)
return
security_ops
->
file_receive
(
file
);
return
security_ops
->
file_receive
(
file
);
}
}
int
security_
dentry
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
int
security_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
{
int
ret
;
int
ret
;
ret
=
security_ops
->
dentry
_open
(
file
,
cred
);
ret
=
security_ops
->
file
_open
(
file
,
cred
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
...
security/selinux/avc.c
浏览文件 @
ff2bb047
...
@@ -65,14 +65,8 @@ struct avc_cache {
...
@@ -65,14 +65,8 @@ struct avc_cache {
};
};
struct
avc_callback_node
{
struct
avc_callback_node
{
int
(
*
callback
)
(
u32
event
,
u32
ssid
,
u32
tsid
,
int
(
*
callback
)
(
u32
event
);
u16
tclass
,
u32
perms
,
u32
*
out_retained
);
u32
events
;
u32
events
;
u32
ssid
;
u32
tsid
;
u16
tclass
;
u32
perms
;
struct
avc_callback_node
*
next
;
struct
avc_callback_node
*
next
;
};
};
...
@@ -436,9 +430,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
...
@@ -436,9 +430,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
{
{
struct
common_audit_data
*
ad
=
a
;
struct
common_audit_data
*
ad
=
a
;
audit_log_format
(
ab
,
"avc: %s "
,
audit_log_format
(
ab
,
"avc: %s "
,
ad
->
selinux_audit_data
->
slad
->
denied
?
"denied"
:
"granted"
);
ad
->
selinux_audit_data
->
denied
?
"denied"
:
"granted"
);
avc_dump_av
(
ab
,
ad
->
selinux_audit_data
->
slad
->
tclass
,
avc_dump_av
(
ab
,
ad
->
selinux_audit_data
->
tclass
,
ad
->
selinux_audit_data
->
slad
->
audited
);
ad
->
selinux_audit_data
->
audited
);
audit_log_format
(
ab
,
" for "
);
audit_log_format
(
ab
,
" for "
);
}
}
...
@@ -452,25 +446,23 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
...
@@ -452,25 +446,23 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
{
{
struct
common_audit_data
*
ad
=
a
;
struct
common_audit_data
*
ad
=
a
;
audit_log_format
(
ab
,
" "
);
audit_log_format
(
ab
,
" "
);
avc_dump_query
(
ab
,
ad
->
selinux_audit_data
->
s
lad
->
s
sid
,
avc_dump_query
(
ab
,
ad
->
selinux_audit_data
->
ssid
,
ad
->
selinux_audit_data
->
slad
->
tsid
,
ad
->
selinux_audit_data
->
tsid
,
ad
->
selinux_audit_data
->
slad
->
tclass
);
ad
->
selinux_audit_data
->
tclass
);
}
}
/* This is the slow part of avc audit with big stack footprint */
/* This is the slow part of avc audit with big stack footprint */
static
noinline
int
slow_avc_audit
(
u32
ssid
,
u32
tsid
,
u16
tclass
,
noinline
int
slow_avc_audit
(
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
requested
,
u32
audited
,
u32
denied
,
u32
requested
,
u32
audited
,
u32
denied
,
struct
common_audit_data
*
a
,
struct
common_audit_data
*
a
,
unsigned
flags
)
unsigned
flags
)
{
{
struct
common_audit_data
stack_data
;
struct
common_audit_data
stack_data
;
struct
selinux_audit_data
sad
=
{
0
,};
struct
selinux_audit_data
sad
;
struct
selinux_late_audit_data
slad
;
if
(
!
a
)
{
if
(
!
a
)
{
a
=
&
stack_data
;
a
=
&
stack_data
;
COMMON_AUDIT_DATA_INIT
(
a
,
NONE
);
a
->
type
=
LSM_AUDIT_DATA_NONE
;
a
->
selinux_audit_data
=
&
sad
;
}
}
/*
/*
...
@@ -484,104 +476,34 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
...
@@ -484,104 +476,34 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
(
flags
&
MAY_NOT_BLOCK
))
(
flags
&
MAY_NOT_BLOCK
))
return
-
ECHILD
;
return
-
ECHILD
;
slad
.
tclass
=
tclass
;
sad
.
tclass
=
tclass
;
slad
.
requested
=
requested
;
sad
.
requested
=
requested
;
slad
.
ssid
=
ssid
;
sad
.
ssid
=
ssid
;
slad
.
tsid
=
tsid
;
sad
.
tsid
=
tsid
;
slad
.
audited
=
audited
;
sad
.
audited
=
audited
;
slad
.
denied
=
denied
;
sad
.
denied
=
denied
;
a
->
selinux_audit_data
=
&
sad
;
a
->
selinux_audit_data
->
slad
=
&
slad
;
common_lsm_audit
(
a
,
avc_audit_pre_callback
,
avc_audit_post_callback
);
common_lsm_audit
(
a
,
avc_audit_pre_callback
,
avc_audit_post_callback
);
return
0
;
return
0
;
}
}
/**
* avc_audit - Audit the granting or denial of permissions.
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
* @requested: requested permissions
* @avd: access vector decisions
* @result: result from avc_has_perm_noaudit
* @a: auxiliary audit data
* @flags: VFS walk flags
*
* Audit the granting or denial of permissions in accordance
* with the policy. This function is typically called by
* avc_has_perm() after a permission check, but can also be
* called directly by callers who use avc_has_perm_noaudit()
* in order to separate the permission check from the auditing.
* For example, this separation is useful when the permission check must
* be performed under a lock, to allow the lock to be released
* before calling the auditing code.
*/
inline
int
avc_audit
(
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
requested
,
struct
av_decision
*
avd
,
int
result
,
struct
common_audit_data
*
a
,
unsigned
flags
)
{
u32
denied
,
audited
;
denied
=
requested
&
~
avd
->
allowed
;
if
(
unlikely
(
denied
))
{
audited
=
denied
&
avd
->
auditdeny
;
/*
* a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in
* this field means that ANY denials should NOT be audited if
* the policy contains an explicit dontaudit rule for that
* permission. Take notice that this is unrelated to the
* actual permissions that were denied. As an example lets
* assume:
*
* denied == READ
* avd.auditdeny & ACCESS == 0 (not set means explicit rule)
* selinux_audit_data->auditdeny & ACCESS == 1
*
* We will NOT audit the denial even though the denied
* permission was READ and the auditdeny checks were for
* ACCESS
*/
if
(
a
&&
a
->
selinux_audit_data
->
auditdeny
&&
!
(
a
->
selinux_audit_data
->
auditdeny
&
avd
->
auditdeny
))
audited
=
0
;
}
else
if
(
result
)
audited
=
denied
=
requested
;
else
audited
=
requested
&
avd
->
auditallow
;
if
(
likely
(
!
audited
))
return
0
;
return
slow_avc_audit
(
ssid
,
tsid
,
tclass
,
requested
,
audited
,
denied
,
a
,
flags
);
}
/**
/**
* avc_add_callback - Register a callback for security events.
* avc_add_callback - Register a callback for security events.
* @callback: callback function
* @callback: callback function
* @events: security events
* @events: security events
* @ssid: source security identifier or %SECSID_WILD
* @tsid: target security identifier or %SECSID_WILD
* @tclass: target security class
* @perms: permissions
*
*
* Register a callback function for events in the set @events
* Register a callback function for events in the set @events.
* related to the SID pair (@ssid, @tsid)
* Returns %0 on success or -%ENOMEM if insufficient memory
* and the permissions @perms, interpreting
* exists to add the callback.
* @perms based on @tclass. Returns %0 on success or
* -%ENOMEM if insufficient memory exists to add the callback.
*/
*/
int
avc_add_callback
(
int
(
*
callback
)(
u32
event
,
u32
ssid
,
u32
tsid
,
int
__init
avc_add_callback
(
int
(
*
callback
)(
u32
event
),
u32
events
)
u16
tclass
,
u32
perms
,
u32
*
out_retained
),
u32
events
,
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
perms
)
{
{
struct
avc_callback_node
*
c
;
struct
avc_callback_node
*
c
;
int
rc
=
0
;
int
rc
=
0
;
c
=
kmalloc
(
sizeof
(
*
c
),
GFP_
ATOMIC
);
c
=
kmalloc
(
sizeof
(
*
c
),
GFP_
KERNEL
);
if
(
!
c
)
{
if
(
!
c
)
{
rc
=
-
ENOMEM
;
rc
=
-
ENOMEM
;
goto
out
;
goto
out
;
...
@@ -589,9 +511,6 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
...
@@ -589,9 +511,6 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
c
->
callback
=
callback
;
c
->
callback
=
callback
;
c
->
events
=
events
;
c
->
events
=
events
;
c
->
ssid
=
ssid
;
c
->
tsid
=
tsid
;
c
->
perms
=
perms
;
c
->
next
=
avc_callbacks
;
c
->
next
=
avc_callbacks
;
avc_callbacks
=
c
;
avc_callbacks
=
c
;
out:
out:
...
@@ -731,8 +650,7 @@ int avc_ss_reset(u32 seqno)
...
@@ -731,8 +650,7 @@ int avc_ss_reset(u32 seqno)
for
(
c
=
avc_callbacks
;
c
;
c
=
c
->
next
)
{
for
(
c
=
avc_callbacks
;
c
;
c
=
c
->
next
)
{
if
(
c
->
events
&
AVC_CALLBACK_RESET
)
{
if
(
c
->
events
&
AVC_CALLBACK_RESET
)
{
tmprc
=
c
->
callback
(
AVC_CALLBACK_RESET
,
tmprc
=
c
->
callback
(
AVC_CALLBACK_RESET
);
0
,
0
,
0
,
0
,
NULL
);
/* save the first error encountered for the return
/* save the first error encountered for the return
value and continue processing the callbacks */
value and continue processing the callbacks */
if
(
!
rc
)
if
(
!
rc
)
...
...
security/selinux/hooks.c
浏览文件 @
ff2bb047
此差异已折叠。
点击以展开。
security/selinux/include/avc.h
浏览文件 @
ff2bb047
...
@@ -49,7 +49,7 @@ struct avc_cache_stats {
...
@@ -49,7 +49,7 @@ struct avc_cache_stats {
/*
/*
* We only need this data after we have decided to send an audit message.
* We only need this data after we have decided to send an audit message.
*/
*/
struct
selinux_
late_
audit_data
{
struct
selinux_audit_data
{
u32
ssid
;
u32
ssid
;
u32
tsid
;
u32
tsid
;
u16
tclass
;
u16
tclass
;
...
@@ -59,29 +59,87 @@ struct selinux_late_audit_data {
...
@@ -59,29 +59,87 @@ struct selinux_late_audit_data {
int
result
;
int
result
;
};
};
/*
* We collect this at the beginning or during an selinux security operation
*/
struct
selinux_audit_data
{
/*
* auditdeny is a bit tricky and unintuitive. See the
* comments in avc.c for it's meaning and usage.
*/
u32
auditdeny
;
struct
selinux_late_audit_data
*
slad
;
};
/*
/*
* AVC operations
* AVC operations
*/
*/
void
__init
avc_init
(
void
);
void
__init
avc_init
(
void
);
int
avc_audit
(
u32
ssid
,
u32
tsid
,
static
inline
u32
avc_audit_required
(
u32
requested
,
u16
tclass
,
u32
requested
,
struct
av_decision
*
avd
,
struct
av_decision
*
avd
,
int
result
,
int
result
,
u32
auditdeny
,
struct
common_audit_data
*
a
,
unsigned
flags
);
u32
*
deniedp
)
{
u32
denied
,
audited
;
denied
=
requested
&
~
avd
->
allowed
;
if
(
unlikely
(
denied
))
{
audited
=
denied
&
avd
->
auditdeny
;
/*
* auditdeny is TRICKY! Setting a bit in
* this field means that ANY denials should NOT be audited if
* the policy contains an explicit dontaudit rule for that
* permission. Take notice that this is unrelated to the
* actual permissions that were denied. As an example lets
* assume:
*
* denied == READ
* avd.auditdeny & ACCESS == 0 (not set means explicit rule)
* auditdeny & ACCESS == 1
*
* We will NOT audit the denial even though the denied
* permission was READ and the auditdeny checks were for
* ACCESS
*/
if
(
auditdeny
&&
!
(
auditdeny
&
avd
->
auditdeny
))
audited
=
0
;
}
else
if
(
result
)
audited
=
denied
=
requested
;
else
audited
=
requested
&
avd
->
auditallow
;
*
deniedp
=
denied
;
return
audited
;
}
int
slow_avc_audit
(
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
requested
,
u32
audited
,
u32
denied
,
struct
common_audit_data
*
a
,
unsigned
flags
);
/**
* avc_audit - Audit the granting or denial of permissions.
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
* @requested: requested permissions
* @avd: access vector decisions
* @result: result from avc_has_perm_noaudit
* @a: auxiliary audit data
* @flags: VFS walk flags
*
* Audit the granting or denial of permissions in accordance
* with the policy. This function is typically called by
* avc_has_perm() after a permission check, but can also be
* called directly by callers who use avc_has_perm_noaudit()
* in order to separate the permission check from the auditing.
* For example, this separation is useful when the permission check must
* be performed under a lock, to allow the lock to be released
* before calling the auditing code.
*/
static
inline
int
avc_audit
(
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
requested
,
struct
av_decision
*
avd
,
int
result
,
struct
common_audit_data
*
a
,
unsigned
flags
)
{
u32
audited
,
denied
;
audited
=
avc_audit_required
(
requested
,
avd
,
result
,
0
,
&
denied
);
if
(
likely
(
!
audited
))
return
0
;
return
slow_avc_audit
(
ssid
,
tsid
,
tclass
,
requested
,
audited
,
denied
,
a
,
flags
);
}
#define AVC_STRICT 1
/* Ignore permissive mode. */
#define AVC_STRICT 1
/* Ignore permissive mode. */
int
avc_has_perm_noaudit
(
u32
ssid
,
u32
tsid
,
int
avc_has_perm_noaudit
(
u32
ssid
,
u32
tsid
,
...
@@ -112,11 +170,7 @@ u32 avc_policy_seqno(void);
...
@@ -112,11 +170,7 @@ u32 avc_policy_seqno(void);
#define AVC_CALLBACK_AUDITDENY_ENABLE 64
#define AVC_CALLBACK_AUDITDENY_ENABLE 64
#define AVC_CALLBACK_AUDITDENY_DISABLE 128
#define AVC_CALLBACK_AUDITDENY_DISABLE 128
int
avc_add_callback
(
int
(
*
callback
)(
u32
event
,
u32
ssid
,
u32
tsid
,
int
avc_add_callback
(
int
(
*
callback
)(
u32
event
),
u32
events
);
u16
tclass
,
u32
perms
,
u32
*
out_retained
),
u32
events
,
u32
ssid
,
u32
tsid
,
u16
tclass
,
u32
perms
);
/* Exported to selinuxfs */
/* Exported to selinuxfs */
int
avc_get_hash_stats
(
char
*
page
);
int
avc_get_hash_stats
(
char
*
page
);
...
...
security/selinux/include/security.h
浏览文件 @
ff2bb047
...
@@ -31,13 +31,15 @@
...
@@ -31,13 +31,15 @@
#define POLICYDB_VERSION_BOUNDARY 24
#define POLICYDB_VERSION_BOUNDARY 24
#define POLICYDB_VERSION_FILENAME_TRANS 25
#define POLICYDB_VERSION_FILENAME_TRANS 25
#define POLICYDB_VERSION_ROLETRANS 26
#define POLICYDB_VERSION_ROLETRANS 26
#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
#define POLICYDB_VERSION_DEFAULT_TYPE 28
/* Range of policy versions we understand*/
/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#else
#else
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_
ROLETRANS
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_
DEFAULT_TYPE
#endif
#endif
/* Mask for just the mount related flags */
/* Mask for just the mount related flags */
...
...
security/selinux/netif.c
浏览文件 @
ff2bb047
...
@@ -252,8 +252,7 @@ static void sel_netif_flush(void)
...
@@ -252,8 +252,7 @@ static void sel_netif_flush(void)
spin_unlock_bh
(
&
sel_netif_lock
);
spin_unlock_bh
(
&
sel_netif_lock
);
}
}
static
int
sel_netif_avc_callback
(
u32
event
,
u32
ssid
,
u32
tsid
,
static
int
sel_netif_avc_callback
(
u32
event
)
u16
class
,
u32
perms
,
u32
*
retained
)
{
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
sel_netif_flush
();
sel_netif_flush
();
...
@@ -292,8 +291,7 @@ static __init int sel_netif_init(void)
...
@@ -292,8 +291,7 @@ static __init int sel_netif_init(void)
register_netdevice_notifier
(
&
sel_netif_netdev_notifier
);
register_netdevice_notifier
(
&
sel_netif_netdev_notifier
);
err
=
avc_add_callback
(
sel_netif_avc_callback
,
AVC_CALLBACK_RESET
,
err
=
avc_add_callback
(
sel_netif_avc_callback
,
AVC_CALLBACK_RESET
);
SECSID_NULL
,
SECSID_NULL
,
SECCLASS_NULL
,
0
);
if
(
err
)
if
(
err
)
panic
(
"avc_add_callback() failed, error %d
\n
"
,
err
);
panic
(
"avc_add_callback() failed, error %d
\n
"
,
err
);
...
...
security/selinux/netnode.c
浏览文件 @
ff2bb047
...
@@ -297,8 +297,7 @@ static void sel_netnode_flush(void)
...
@@ -297,8 +297,7 @@ static void sel_netnode_flush(void)
spin_unlock_bh
(
&
sel_netnode_lock
);
spin_unlock_bh
(
&
sel_netnode_lock
);
}
}
static
int
sel_netnode_avc_callback
(
u32
event
,
u32
ssid
,
u32
tsid
,
static
int
sel_netnode_avc_callback
(
u32
event
)
u16
class
,
u32
perms
,
u32
*
retained
)
{
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
sel_netnode_flush
();
sel_netnode_flush
();
...
@@ -320,8 +319,7 @@ static __init int sel_netnode_init(void)
...
@@ -320,8 +319,7 @@ static __init int sel_netnode_init(void)
sel_netnode_hash
[
iter
].
size
=
0
;
sel_netnode_hash
[
iter
].
size
=
0
;
}
}
ret
=
avc_add_callback
(
sel_netnode_avc_callback
,
AVC_CALLBACK_RESET
,
ret
=
avc_add_callback
(
sel_netnode_avc_callback
,
AVC_CALLBACK_RESET
);
SECSID_NULL
,
SECSID_NULL
,
SECCLASS_NULL
,
0
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
panic
(
"avc_add_callback() failed, error %d
\n
"
,
ret
);
panic
(
"avc_add_callback() failed, error %d
\n
"
,
ret
);
...
...
security/selinux/netport.c
浏览文件 @
ff2bb047
...
@@ -234,8 +234,7 @@ static void sel_netport_flush(void)
...
@@ -234,8 +234,7 @@ static void sel_netport_flush(void)
spin_unlock_bh
(
&
sel_netport_lock
);
spin_unlock_bh
(
&
sel_netport_lock
);
}
}
static
int
sel_netport_avc_callback
(
u32
event
,
u32
ssid
,
u32
tsid
,
static
int
sel_netport_avc_callback
(
u32
event
)
u16
class
,
u32
perms
,
u32
*
retained
)
{
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
if
(
event
==
AVC_CALLBACK_RESET
)
{
sel_netport_flush
();
sel_netport_flush
();
...
@@ -257,8 +256,7 @@ static __init int sel_netport_init(void)
...
@@ -257,8 +256,7 @@ static __init int sel_netport_init(void)
sel_netport_hash
[
iter
].
size
=
0
;
sel_netport_hash
[
iter
].
size
=
0
;
}
}
ret
=
avc_add_callback
(
sel_netport_avc_callback
,
AVC_CALLBACK_RESET
,
ret
=
avc_add_callback
(
sel_netport_avc_callback
,
AVC_CALLBACK_RESET
);
SECSID_NULL
,
SECSID_NULL
,
SECCLASS_NULL
,
0
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
panic
(
"avc_add_callback() failed, error %d
\n
"
,
ret
);
panic
(
"avc_add_callback() failed, error %d
\n
"
,
ret
);
...
...
security/selinux/selinuxfs.c
浏览文件 @
ff2bb047
...
@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = {
...
@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = {
.
read
=
sel_read_policy
,
.
read
=
sel_read_policy
,
.
mmap
=
sel_mmap_policy
,
.
mmap
=
sel_mmap_policy
,
.
release
=
sel_release_policy
,
.
release
=
sel_release_policy
,
.
llseek
=
generic_file_llseek
,
};
};
static
ssize_t
sel_write_load
(
struct
file
*
file
,
const
char
__user
*
buf
,
static
ssize_t
sel_write_load
(
struct
file
*
file
,
const
char
__user
*
buf
,
...
@@ -1232,6 +1233,7 @@ static int sel_make_bools(void)
...
@@ -1232,6 +1233,7 @@ static int sel_make_bools(void)
kfree
(
bool_pending_names
[
i
]);
kfree
(
bool_pending_names
[
i
]);
kfree
(
bool_pending_names
);
kfree
(
bool_pending_names
);
kfree
(
bool_pending_values
);
kfree
(
bool_pending_values
);
bool_num
=
0
;
bool_pending_names
=
NULL
;
bool_pending_names
=
NULL
;
bool_pending_values
=
NULL
;
bool_pending_values
=
NULL
;
...
@@ -1532,11 +1534,6 @@ static int sel_make_initcon_files(struct dentry *dir)
...
@@ -1532,11 +1534,6 @@ static int sel_make_initcon_files(struct dentry *dir)
return
0
;
return
0
;
}
}
static
inline
unsigned
int
sel_div
(
unsigned
long
a
,
unsigned
long
b
)
{
return
a
/
b
-
(
a
%
b
<
0
);
}
static
inline
unsigned
long
sel_class_to_ino
(
u16
class
)
static
inline
unsigned
long
sel_class_to_ino
(
u16
class
)
{
{
return
(
class
*
(
SEL_VEC_MAX
+
1
))
|
SEL_CLASS_INO_OFFSET
;
return
(
class
*
(
SEL_VEC_MAX
+
1
))
|
SEL_CLASS_INO_OFFSET
;
...
@@ -1544,7 +1541,7 @@ static inline unsigned long sel_class_to_ino(u16 class)
...
@@ -1544,7 +1541,7 @@ static inline unsigned long sel_class_to_ino(u16 class)
static
inline
u16
sel_ino_to_class
(
unsigned
long
ino
)
static
inline
u16
sel_ino_to_class
(
unsigned
long
ino
)
{
{
return
sel_div
(
ino
&
SEL_INO_MASK
,
SEL_VEC_MAX
+
1
);
return
(
ino
&
SEL_INO_MASK
)
/
(
SEL_VEC_MAX
+
1
);
}
}
static
inline
unsigned
long
sel_perm_to_ino
(
u16
class
,
u32
perm
)
static
inline
unsigned
long
sel_perm_to_ino
(
u16
class
,
u32
perm
)
...
@@ -1831,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
...
@@ -1831,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
[
SEL_REJECT_UNKNOWN
]
=
{
"reject_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_REJECT_UNKNOWN
]
=
{
"reject_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_DENY_UNKNOWN
]
=
{
"deny_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_DENY_UNKNOWN
]
=
{
"deny_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_STATUS
]
=
{
"status"
,
&
sel_handle_status_ops
,
S_IRUGO
},
[
SEL_STATUS
]
=
{
"status"
,
&
sel_handle_status_ops
,
S_IRUGO
},
[
SEL_POLICY
]
=
{
"policy"
,
&
sel_policy_ops
,
S_IRU
SR
},
[
SEL_POLICY
]
=
{
"policy"
,
&
sel_policy_ops
,
S_IRU
GO
},
/* last one */
{
""
}
/* last one */
{
""
}
};
};
ret
=
simple_fill_super
(
sb
,
SELINUX_MAGIC
,
selinux_files
);
ret
=
simple_fill_super
(
sb
,
SELINUX_MAGIC
,
selinux_files
);
...
...
security/selinux/ss/context.h
浏览文件 @
ff2bb047
...
@@ -74,6 +74,26 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
...
@@ -74,6 +74,26 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
return
rc
;
return
rc
;
}
}
/*
* Sets both levels in the MLS range of 'dst' to the high level of 'src'.
*/
static
inline
int
mls_context_cpy_high
(
struct
context
*
dst
,
struct
context
*
src
)
{
int
rc
;
dst
->
range
.
level
[
0
].
sens
=
src
->
range
.
level
[
1
].
sens
;
rc
=
ebitmap_cpy
(
&
dst
->
range
.
level
[
0
].
cat
,
&
src
->
range
.
level
[
1
].
cat
);
if
(
rc
)
goto
out
;
dst
->
range
.
level
[
1
].
sens
=
src
->
range
.
level
[
1
].
sens
;
rc
=
ebitmap_cpy
(
&
dst
->
range
.
level
[
1
].
cat
,
&
src
->
range
.
level
[
1
].
cat
);
if
(
rc
)
ebitmap_destroy
(
&
dst
->
range
.
level
[
0
].
cat
);
out:
return
rc
;
}
static
inline
int
mls_context_cmp
(
struct
context
*
c1
,
struct
context
*
c2
)
static
inline
int
mls_context_cmp
(
struct
context
*
c1
,
struct
context
*
c2
)
{
{
return
((
c1
->
range
.
level
[
0
].
sens
==
c2
->
range
.
level
[
0
].
sens
)
&&
return
((
c1
->
range
.
level
[
0
].
sens
==
c2
->
range
.
level
[
0
].
sens
)
&&
...
...
security/selinux/ss/mls.c
浏览文件 @
ff2bb047
...
@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext,
...
@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext,
{
{
struct
range_trans
rtr
;
struct
range_trans
rtr
;
struct
mls_range
*
r
;
struct
mls_range
*
r
;
struct
class_datum
*
cladatum
;
int
default_range
=
0
;
if
(
!
policydb
.
mls_enabled
)
if
(
!
policydb
.
mls_enabled
)
return
0
;
return
0
;
...
@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext,
...
@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext,
r
=
hashtab_search
(
policydb
.
range_tr
,
&
rtr
);
r
=
hashtab_search
(
policydb
.
range_tr
,
&
rtr
);
if
(
r
)
if
(
r
)
return
mls_range_set
(
newcontext
,
r
);
return
mls_range_set
(
newcontext
,
r
);
if
(
tclass
&&
tclass
<=
policydb
.
p_classes
.
nprim
)
{
cladatum
=
policydb
.
class_val_to_struct
[
tclass
-
1
];
if
(
cladatum
)
default_range
=
cladatum
->
default_range
;
}
switch
(
default_range
)
{
case
DEFAULT_SOURCE_LOW
:
return
mls_context_cpy_low
(
newcontext
,
scontext
);
case
DEFAULT_SOURCE_HIGH
:
return
mls_context_cpy_high
(
newcontext
,
scontext
);
case
DEFAULT_SOURCE_LOW_HIGH
:
return
mls_context_cpy
(
newcontext
,
scontext
);
case
DEFAULT_TARGET_LOW
:
return
mls_context_cpy_low
(
newcontext
,
tcontext
);
case
DEFAULT_TARGET_HIGH
:
return
mls_context_cpy_high
(
newcontext
,
tcontext
);
case
DEFAULT_TARGET_LOW_HIGH
:
return
mls_context_cpy
(
newcontext
,
tcontext
);
}
/* Fallthrough */
/* Fallthrough */
case
AVTAB_CHANGE
:
case
AVTAB_CHANGE
:
if
((
tclass
==
policydb
.
process_class
)
||
(
sock
==
true
))
if
((
tclass
==
policydb
.
process_class
)
||
(
sock
==
true
))
...
...
security/selinux/ss/policydb.c
浏览文件 @
ff2bb047
...
@@ -133,6 +133,16 @@ static struct policydb_compat_info policydb_compat[] = {
...
@@ -133,6 +133,16 @@ static struct policydb_compat_info policydb_compat[] = {
.
sym_num
=
SYM_NUM
,
.
sym_num
=
SYM_NUM
,
.
ocon_num
=
OCON_NUM
,
.
ocon_num
=
OCON_NUM
,
},
},
{
.
version
=
POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
,
.
sym_num
=
SYM_NUM
,
.
ocon_num
=
OCON_NUM
,
},
{
.
version
=
POLICYDB_VERSION_DEFAULT_TYPE
,
.
sym_num
=
SYM_NUM
,
.
ocon_num
=
OCON_NUM
,
},
};
};
static
struct
policydb_compat_info
*
policydb_lookup_compat
(
int
version
)
static
struct
policydb_compat_info
*
policydb_lookup_compat
(
int
version
)
...
@@ -1306,6 +1316,23 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
...
@@ -1306,6 +1316,23 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
goto
bad
;
goto
bad
;
}
}
if
(
p
->
policyvers
>=
POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
)
{
rc
=
next_entry
(
buf
,
fp
,
sizeof
(
u32
)
*
3
);
if
(
rc
)
goto
bad
;
cladatum
->
default_user
=
le32_to_cpu
(
buf
[
0
]);
cladatum
->
default_role
=
le32_to_cpu
(
buf
[
1
]);
cladatum
->
default_range
=
le32_to_cpu
(
buf
[
2
]);
}
if
(
p
->
policyvers
>=
POLICYDB_VERSION_DEFAULT_TYPE
)
{
rc
=
next_entry
(
buf
,
fp
,
sizeof
(
u32
)
*
1
);
if
(
rc
)
goto
bad
;
cladatum
->
default_type
=
le32_to_cpu
(
buf
[
0
]);
}
rc
=
hashtab_insert
(
h
,
key
,
cladatum
);
rc
=
hashtab_insert
(
h
,
key
,
cladatum
);
if
(
rc
)
if
(
rc
)
goto
bad
;
goto
bad
;
...
@@ -2832,6 +2859,23 @@ static int class_write(void *vkey, void *datum, void *ptr)
...
@@ -2832,6 +2859,23 @@ static int class_write(void *vkey, void *datum, void *ptr)
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
if
(
p
->
policyvers
>=
POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
)
{
buf
[
0
]
=
cpu_to_le32
(
cladatum
->
default_user
);
buf
[
1
]
=
cpu_to_le32
(
cladatum
->
default_role
);
buf
[
2
]
=
cpu_to_le32
(
cladatum
->
default_range
);
rc
=
put_entry
(
buf
,
sizeof
(
uint32_t
),
3
,
fp
);
if
(
rc
)
return
rc
;
}
if
(
p
->
policyvers
>=
POLICYDB_VERSION_DEFAULT_TYPE
)
{
buf
[
0
]
=
cpu_to_le32
(
cladatum
->
default_type
);
rc
=
put_entry
(
buf
,
sizeof
(
uint32_t
),
1
,
fp
);
if
(
rc
)
return
rc
;
}
return
0
;
return
0
;
}
}
...
...
security/selinux/ss/policydb.h
浏览文件 @
ff2bb047
...
@@ -60,6 +60,20 @@ struct class_datum {
...
@@ -60,6 +60,20 @@ struct class_datum {
struct
symtab
permissions
;
/* class-specific permission symbol table */
struct
symtab
permissions
;
/* class-specific permission symbol table */
struct
constraint_node
*
constraints
;
/* constraints on class permissions */
struct
constraint_node
*
constraints
;
/* constraints on class permissions */
struct
constraint_node
*
validatetrans
;
/* special transition rules */
struct
constraint_node
*
validatetrans
;
/* special transition rules */
/* Options how a new object user, role, and type should be decided */
#define DEFAULT_SOURCE 1
#define DEFAULT_TARGET 2
char
default_user
;
char
default_role
;
char
default_type
;
/* Options how a new object range should be decided */
#define DEFAULT_SOURCE_LOW 1
#define DEFAULT_SOURCE_HIGH 2
#define DEFAULT_SOURCE_LOW_HIGH 3
#define DEFAULT_TARGET_LOW 4
#define DEFAULT_TARGET_HIGH 5
#define DEFAULT_TARGET_LOW_HIGH 6
char
default_range
;
};
};
/* Role attributes */
/* Role attributes */
...
...
security/selinux/ss/services.c
浏览文件 @
ff2bb047
...
@@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
...
@@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
if
(
context
->
len
)
{
if
(
context
->
len
)
{
*
scontext_len
=
context
->
len
;
*
scontext_len
=
context
->
len
;
*
scontext
=
kstrdup
(
context
->
str
,
GFP_ATOMIC
);
if
(
scontext
)
{
if
(
!
(
*
scontext
))
*
scontext
=
kstrdup
(
context
->
str
,
GFP_ATOMIC
);
return
-
ENOMEM
;
if
(
!
(
*
scontext
))
return
-
ENOMEM
;
}
return
0
;
return
0
;
}
}
...
@@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid,
...
@@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid,
u32
*
out_sid
,
u32
*
out_sid
,
bool
kern
)
bool
kern
)
{
{
struct
class_datum
*
cladatum
=
NULL
;
struct
context
*
scontext
=
NULL
,
*
tcontext
=
NULL
,
newcontext
;
struct
context
*
scontext
=
NULL
,
*
tcontext
=
NULL
,
newcontext
;
struct
role_trans
*
roletr
=
NULL
;
struct
role_trans
*
roletr
=
NULL
;
struct
avtab_key
avkey
;
struct
avtab_key
avkey
;
...
@@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid,
...
@@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid,
goto
out_unlock
;
goto
out_unlock
;
}
}
if
(
tclass
&&
tclass
<=
policydb
.
p_classes
.
nprim
)
cladatum
=
policydb
.
class_val_to_struct
[
tclass
-
1
];
/* Set the user identity. */
/* Set the user identity. */
switch
(
specified
)
{
switch
(
specified
)
{
case
AVTAB_TRANSITION
:
case
AVTAB_TRANSITION
:
case
AVTAB_CHANGE
:
case
AVTAB_CHANGE
:
/* Use the process user identity. */
if
(
cladatum
&&
cladatum
->
default_user
==
DEFAULT_TARGET
)
{
newcontext
.
user
=
scontext
->
user
;
newcontext
.
user
=
tcontext
->
user
;
}
else
{
/* notice this gets both DEFAULT_SOURCE and unset */
/* Use the process user identity. */
newcontext
.
user
=
scontext
->
user
;
}
break
;
break
;
case
AVTAB_MEMBER
:
case
AVTAB_MEMBER
:
/* Use the related object owner. */
/* Use the related object owner. */
...
@@ -1450,16 +1461,31 @@ static int security_compute_sid(u32 ssid,
...
@@ -1450,16 +1461,31 @@ static int security_compute_sid(u32 ssid,
break
;
break
;
}
}
/* Set the role and type to default values. */
/* Set the role to default values. */
if
((
tclass
==
policydb
.
process_class
)
||
(
sock
==
true
))
{
if
(
cladatum
&&
cladatum
->
default_role
==
DEFAULT_SOURCE
)
{
/* Use the current role and type of process. */
newcontext
.
role
=
scontext
->
role
;
newcontext
.
role
=
scontext
->
role
;
newcontext
.
type
=
scontext
->
type
;
}
else
if
(
cladatum
&&
cladatum
->
default_role
==
DEFAULT_TARGET
)
{
newcontext
.
role
=
tcontext
->
role
;
}
else
{
}
else
{
/* Use the well-defined object role. */
if
((
tclass
==
policydb
.
process_class
)
||
(
sock
==
true
))
newcontext
.
role
=
OBJECT_R_VAL
;
newcontext
.
role
=
scontext
->
role
;
/* Use the type of the related object. */
else
newcontext
.
role
=
OBJECT_R_VAL
;
}
/* Set the type to default values. */
if
(
cladatum
&&
cladatum
->
default_type
==
DEFAULT_SOURCE
)
{
newcontext
.
type
=
scontext
->
type
;
}
else
if
(
cladatum
&&
cladatum
->
default_type
==
DEFAULT_TARGET
)
{
newcontext
.
type
=
tcontext
->
type
;
newcontext
.
type
=
tcontext
->
type
;
}
else
{
if
((
tclass
==
policydb
.
process_class
)
||
(
sock
==
true
))
{
/* Use the type of process. */
newcontext
.
type
=
scontext
->
type
;
}
else
{
/* Use the type of the related object. */
newcontext
.
type
=
tcontext
->
type
;
}
}
}
/* Look for a type transition/member/change rule. */
/* Look for a type transition/member/change rule. */
...
@@ -3018,8 +3044,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
...
@@ -3018,8 +3044,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
static
int
(
*
aurule_callback
)(
void
)
=
audit_update_lsm_rules
;
static
int
(
*
aurule_callback
)(
void
)
=
audit_update_lsm_rules
;
static
int
aurule_avc_callback
(
u32
event
,
u32
ssid
,
u32
tsid
,
static
int
aurule_avc_callback
(
u32
event
)
u16
class
,
u32
perms
,
u32
*
retained
)
{
{
int
err
=
0
;
int
err
=
0
;
...
@@ -3032,8 +3057,7 @@ static int __init aurule_init(void)
...
@@ -3032,8 +3057,7 @@ static int __init aurule_init(void)
{
{
int
err
;
int
err
;
err
=
avc_add_callback
(
aurule_avc_callback
,
AVC_CALLBACK_RESET
,
err
=
avc_add_callback
(
aurule_avc_callback
,
AVC_CALLBACK_RESET
);
SECSID_NULL
,
SECSID_NULL
,
SECCLASS_NULL
,
0
);
if
(
err
)
if
(
err
)
panic
(
"avc_add_callback() failed, error %d
\n
"
,
err
);
panic
(
"avc_add_callback() failed, error %d
\n
"
,
err
);
...
...
security/smack/smack.h
浏览文件 @
ff2bb047
...
@@ -304,7 +304,7 @@ void smack_log(char *subject_label, char *object_label,
...
@@ -304,7 +304,7 @@ void smack_log(char *subject_label, char *object_label,
static
inline
void
smk_ad_init
(
struct
smk_audit_info
*
a
,
const
char
*
func
,
static
inline
void
smk_ad_init
(
struct
smk_audit_info
*
a
,
const
char
*
func
,
char
type
)
char
type
)
{
{
memset
(
a
,
0
,
sizeof
(
*
a
));
memset
(
&
a
->
sad
,
0
,
sizeof
(
a
->
sad
));
a
->
a
.
type
=
type
;
a
->
a
.
type
=
type
;
a
->
a
.
smack_audit_data
=
&
a
->
sad
;
a
->
a
.
smack_audit_data
=
&
a
->
sad
;
a
->
a
.
smack_audit_data
->
function
=
func
;
a
->
a
.
smack_audit_data
->
function
=
func
;
...
...
security/smack/smack_lsm.c
浏览文件 @
ff2bb047
...
@@ -1359,7 +1359,7 @@ static int smack_file_receive(struct file *file)
...
@@ -1359,7 +1359,7 @@ static int smack_file_receive(struct file *file)
}
}
/**
/**
* smack_
dentry
_open - Smack dentry open processing
* smack_
file
_open - Smack dentry open processing
* @file: the object
* @file: the object
* @cred: unused
* @cred: unused
*
*
...
@@ -1367,7 +1367,7 @@ static int smack_file_receive(struct file *file)
...
@@ -1367,7 +1367,7 @@ static int smack_file_receive(struct file *file)
*
*
* Returns 0
* Returns 0
*/
*/
static
int
smack_
dentry
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
static
int
smack_
file
_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
{
struct
inode_smack
*
isp
=
file
->
f_path
.
dentry
->
d_inode
->
i_security
;
struct
inode_smack
*
isp
=
file
->
f_path
.
dentry
->
d_inode
->
i_security
;
...
@@ -3487,7 +3487,7 @@ struct security_operations smack_ops = {
...
@@ -3487,7 +3487,7 @@ struct security_operations smack_ops = {
.
file_send_sigiotask
=
smack_file_send_sigiotask
,
.
file_send_sigiotask
=
smack_file_send_sigiotask
,
.
file_receive
=
smack_file_receive
,
.
file_receive
=
smack_file_receive
,
.
dentry_open
=
smack_dentry
_open
,
.
file_open
=
smack_file
_open
,
.
cred_alloc_blank
=
smack_cred_alloc_blank
,
.
cred_alloc_blank
=
smack_cred_alloc_blank
,
.
cred_free
=
smack_cred_free
,
.
cred_free
=
smack_cred_free
,
...
...
security/tomoyo/tomoyo.c
浏览文件 @
ff2bb047
...
@@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
...
@@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
}
}
/**
/**
* tomoyo_
dentry_open - Target for security_dentry
_open().
* tomoyo_
file_open - Target for security_file
_open().
*
*
* @f: Pointer to "struct file".
* @f: Pointer to "struct file".
* @cred: Pointer to "struct cred".
* @cred: Pointer to "struct cred".
*
*
* Returns 0 on success, negative value otherwise.
* Returns 0 on success, negative value otherwise.
*/
*/
static
int
tomoyo_
dentry
_open
(
struct
file
*
f
,
const
struct
cred
*
cred
)
static
int
tomoyo_
file
_open
(
struct
file
*
f
,
const
struct
cred
*
cred
)
{
{
int
flags
=
f
->
f_flags
;
int
flags
=
f
->
f_flags
;
/* Don't check read permission here if called from do_execve(). */
/* Don't check read permission here if called from do_execve(). */
...
@@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = {
...
@@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = {
.
bprm_set_creds
=
tomoyo_bprm_set_creds
,
.
bprm_set_creds
=
tomoyo_bprm_set_creds
,
.
bprm_check_security
=
tomoyo_bprm_check_security
,
.
bprm_check_security
=
tomoyo_bprm_check_security
,
.
file_fcntl
=
tomoyo_file_fcntl
,
.
file_fcntl
=
tomoyo_file_fcntl
,
.
dentry_open
=
tomoyo_dentry
_open
,
.
file_open
=
tomoyo_file
_open
,
.
path_truncate
=
tomoyo_path_truncate
,
.
path_truncate
=
tomoyo_path_truncate
,
.
path_unlink
=
tomoyo_path_unlink
,
.
path_unlink
=
tomoyo_path_unlink
,
.
path_mkdir
=
tomoyo_path_mkdir
,
.
path_mkdir
=
tomoyo_path_mkdir
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录