Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
2fd4e669
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
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看板
提交
2fd4e669
编写于
5月 20, 2014
作者:
J
James Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'smack-for-3.16' of
git://git.gitorious.org/smack-next/kernel
into next
上级
fab71a90
ec554fa7
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
307 addition
and
73 deletion
+307
-73
Documentation/security/Smack.txt
Documentation/security/Smack.txt
+10
-0
security/smack/smack.h
security/smack/smack.h
+13
-3
security/smack/smack_access.c
security/smack/smack_access.c
+30
-8
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+179
-61
security/smack/smackfs.c
security/smack/smackfs.c
+75
-1
未找到文件。
Documentation/security/Smack.txt
浏览文件 @
2fd4e669
...
...
@@ -204,6 +204,16 @@ onlycap
these capabilities are effective at for processes with any
label. The value is set by writing the desired label to the
file or cleared by writing "-" to the file.
ptrace
This is used to define the current ptrace policy
0 - default: this is the policy that relies on smack access rules.
For the PTRACE_READ a subject needs to have a read access on
object. For the PTRACE_ATTACH a read-write access is required.
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
only allowed when subject's and object's labels are equal.
PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
2 - draconian: this policy behaves like the 'exact' above with an
exception that it can't be overriden with CAP_SYS_PTRACE.
revoke-subject
Writing a Smack label here sets the access to '-' for all access
rules with that subject label.
...
...
security/smack/smack.h
浏览文件 @
2fd4e669
...
...
@@ -80,8 +80,8 @@ struct superblock_smack {
struct
socket_smack
{
struct
smack_known
*
smk_out
;
/* outbound label */
char
*
smk_in
;
/* inbound label */
char
*
smk_packet
;
/* TCP peer label */
struct
smack_known
*
smk_in
;
/* inbound label */
struct
smack_known
*
smk_packet
;
/* TCP peer label */
};
/*
...
...
@@ -133,7 +133,7 @@ struct smk_port_label {
struct
list_head
list
;
struct
sock
*
smk_sock
;
/* socket initialized on */
unsigned
short
smk_port
;
/* the port number */
char
*
smk_in
;
/* incoming
label */
struct
smack_known
*
smk_in
;
/* inbound
label */
struct
smack_known
*
smk_out
;
/* outgoing label */
};
...
...
@@ -176,6 +176,14 @@ struct smk_port_label {
*/
#define SMACK_CIPSO_MAXCATNUM 184
/* 23 * 8 */
/*
* Ptrace rules
*/
#define SMACK_PTRACE_DEFAULT 0
#define SMACK_PTRACE_EXACT 1
#define SMACK_PTRACE_DRACONIAN 2
#define SMACK_PTRACE_MAX SMACK_PTRACE_DRACONIAN
/*
* Flags for untraditional access modes.
* It shouldn't be necessary to avoid conflicts with definitions
...
...
@@ -225,6 +233,7 @@ struct inode_smack *new_inode_smack(char *);
*/
int
smk_access_entry
(
char
*
,
char
*
,
struct
list_head
*
);
int
smk_access
(
struct
smack_known
*
,
char
*
,
int
,
struct
smk_audit_info
*
);
int
smk_tskacc
(
struct
task_smack
*
,
char
*
,
u32
,
struct
smk_audit_info
*
);
int
smk_curacc
(
char
*
,
u32
,
struct
smk_audit_info
*
);
struct
smack_known
*
smack_from_secid
(
const
u32
);
char
*
smk_parse_smack
(
const
char
*
string
,
int
len
);
...
...
@@ -244,6 +253,7 @@ extern struct smack_known *smack_net_ambient;
extern
struct
smack_known
*
smack_onlycap
;
extern
struct
smack_known
*
smack_syslog_label
;
extern
const
char
*
smack_cipso_option
;
extern
int
smack_ptrace_rule
;
extern
struct
smack_known
smack_known_floor
;
extern
struct
smack_known
smack_known_hat
;
...
...
security/smack/smack_access.c
浏览文件 @
2fd4e669
...
...
@@ -192,20 +192,21 @@ int smk_access(struct smack_known *subject_known, char *object_label,
}
/**
* smk_curacc - determine if current has a specific access to an object
* smk_tskacc - determine if a task has a specific access to an object
* @tsp: a pointer to the subject task
* @obj_label: a pointer to the object's Smack label
* @mode: the access requested, in "MAY" format
* @a : common audit data
*
* This function checks the
current subject
label/object label pair
* This function checks the
subject task's
label/object label pair
* in the access rule list and returns 0 if the access is permitted,
* non zero otherwise. It allows that
current
may have the capability
* non zero otherwise. It allows that
the task
may have the capability
* to override the rules.
*/
int
smk_curacc
(
char
*
obj_label
,
u32
mode
,
struct
smk_audit_info
*
a
)
int
smk_tskacc
(
struct
task_smack
*
subject
,
char
*
obj_label
,
u32
mode
,
struct
smk_audit_info
*
a
)
{
struct
task_smack
*
tsp
=
current_security
();
struct
smack_known
*
skp
=
smk_of_task
(
tsp
);
struct
smack_known
*
skp
=
smk_of_task
(
subject
);
int
may
;
int
rc
;
...
...
@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
* it can further restrict access.
*/
may
=
smk_access_entry
(
skp
->
smk_known
,
obj_label
,
&
tsp
->
smk_rules
);
&
subject
->
smk_rules
);
if
(
may
<
0
)
goto
out_audit
;
if
((
mode
&
may
)
==
mode
)
...
...
@@ -241,6 +242,24 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
return
rc
;
}
/**
* smk_curacc - determine if current has a specific access to an object
* @obj_label: a pointer to the object's Smack label
* @mode: the access requested, in "MAY" format
* @a : common audit data
*
* This function checks the current subject label/object label pair
* in the access rule list and returns 0 if the access is permitted,
* non zero otherwise. It allows that current may have the capability
* to override the rules.
*/
int
smk_curacc
(
char
*
obj_label
,
u32
mode
,
struct
smk_audit_info
*
a
)
{
struct
task_smack
*
tsp
=
current_security
();
return
smk_tskacc
(
tsp
,
obj_label
,
mode
,
a
);
}
#ifdef CONFIG_AUDIT
/**
* smack_str_from_perm : helper to transalate an int to a
...
...
@@ -285,7 +304,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
audit_log_untrustedstring
(
ab
,
sad
->
subject
);
audit_log_format
(
ab
,
" object="
);
audit_log_untrustedstring
(
ab
,
sad
->
object
);
audit_log_format
(
ab
,
" requested=%s"
,
sad
->
request
);
if
(
sad
->
request
[
0
]
==
'\0'
)
audit_log_format
(
ab
,
" labels_differ"
);
else
audit_log_format
(
ab
,
" requested=%s"
,
sad
->
request
);
}
/**
...
...
security/smack/smack_lsm.c
浏览文件 @
2fd4e669
...
...
@@ -157,6 +157,74 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
return
rc
;
}
/**
* smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
* @mode - input mode in form of PTRACE_MODE_*
*
* Returns a converted MAY_* mode usable by smack rules
*/
static
inline
unsigned
int
smk_ptrace_mode
(
unsigned
int
mode
)
{
switch
(
mode
)
{
case
PTRACE_MODE_READ
:
return
MAY_READ
;
case
PTRACE_MODE_ATTACH
:
return
MAY_READWRITE
;
}
return
0
;
}
/**
* smk_ptrace_rule_check - helper for ptrace access
* @tracer: tracer process
* @tracee_label: label of the process that's about to be traced,
* the pointer must originate from smack structures
* @mode: ptrace attachment mode (PTRACE_MODE_*)
* @func: name of the function that called us, used for audit
*
* Returns 0 on access granted, -error on error
*/
static
int
smk_ptrace_rule_check
(
struct
task_struct
*
tracer
,
char
*
tracee_label
,
unsigned
int
mode
,
const
char
*
func
)
{
int
rc
;
struct
smk_audit_info
ad
,
*
saip
=
NULL
;
struct
task_smack
*
tsp
;
struct
smack_known
*
skp
;
if
((
mode
&
PTRACE_MODE_NOAUDIT
)
==
0
)
{
smk_ad_init
(
&
ad
,
func
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
tracer
);
saip
=
&
ad
;
}
tsp
=
task_security
(
tracer
);
skp
=
smk_of_task
(
tsp
);
if
((
mode
&
PTRACE_MODE_ATTACH
)
&&
(
smack_ptrace_rule
==
SMACK_PTRACE_EXACT
||
smack_ptrace_rule
==
SMACK_PTRACE_DRACONIAN
))
{
if
(
skp
->
smk_known
==
tracee_label
)
rc
=
0
;
else
if
(
smack_ptrace_rule
==
SMACK_PTRACE_DRACONIAN
)
rc
=
-
EACCES
;
else
if
(
capable
(
CAP_SYS_PTRACE
))
rc
=
0
;
else
rc
=
-
EACCES
;
if
(
saip
)
smack_log
(
skp
->
smk_known
,
tracee_label
,
0
,
rc
,
saip
);
return
rc
;
}
/* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
rc
=
smk_tskacc
(
tsp
,
tracee_label
,
smk_ptrace_mode
(
mode
),
saip
);
return
rc
;
}
/*
* LSM hooks.
* We he, that is fun!
...
...
@@ -165,16 +233,15 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
/**
* smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
* @ctp: child task pointer
* @mode: ptrace attachment mode
* @mode: ptrace attachment mode
(PTRACE_MODE_*)
*
* Returns 0 if access is OK, an error code otherwise
*
* Do the capability checks
, and require read and write
.
* Do the capability checks.
*/
static
int
smack_ptrace_access_check
(
struct
task_struct
*
ctp
,
unsigned
int
mode
)
{
int
rc
;
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
;
rc
=
cap_ptrace_access_check
(
ctp
,
mode
);
...
...
@@ -182,10 +249,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
return
rc
;
skp
=
smk_of_task
(
task_security
(
ctp
));
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
ctp
);
rc
=
smk_
curacc
(
skp
->
smk_known
,
mode
,
&
ad
);
rc
=
smk_
ptrace_rule_check
(
current
,
skp
->
smk_known
,
mode
,
__func__
);
return
rc
;
}
...
...
@@ -195,23 +260,21 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
*
* Returns 0 if access is OK, an error code otherwise
*
* Do the capability checks, and require
read and write
.
* Do the capability checks, and require
PTRACE_MODE_ATTACH
.
*/
static
int
smack_ptrace_traceme
(
struct
task_struct
*
ptp
)
{
int
rc
;
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
;
rc
=
cap_ptrace_traceme
(
ptp
);
if
(
rc
!=
0
)
return
rc
;
skp
=
smk_of_task
(
task_security
(
ptp
));
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_TASK
);
smk_ad_setfield_u_tsk
(
&
ad
,
ptp
);
skp
=
smk_of_task
(
current_security
());
rc
=
smk_curacc
(
skp
->
smk_known
,
MAY_READWRITE
,
&
ad
);
rc
=
smk_ptrace_rule_check
(
ptp
,
skp
->
smk_known
,
PTRACE_MODE_ATTACH
,
__func__
);
return
rc
;
}
...
...
@@ -413,9 +476,11 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
* Initialize the root inode.
*/
isp
=
inode
->
i_security
;
if
(
inode
->
i_security
==
NULL
)
{
inode
->
i_security
=
new_inode_smack
(
sp
->
smk_root
);
isp
=
inode
->
i_security
;
if
(
isp
==
NULL
)
{
isp
=
new_inode_smack
(
sp
->
smk_root
);
if
(
isp
==
NULL
)
return
-
ENOMEM
;
inode
->
i_security
=
isp
;
}
else
isp
->
smk_inode
=
sp
->
smk_root
;
...
...
@@ -453,7 +518,7 @@ static int smack_sb_statfs(struct dentry *dentry)
* smack_bprm_set_creds - set creds for exec
* @bprm: the exec information
*
* Returns 0 if it gets a blob, -ENOMEM otherwise
* Returns 0 if it gets a blob, -E
PERM if exec forbidden and -E
NOMEM otherwise
*/
static
int
smack_bprm_set_creds
(
struct
linux_binprm
*
bprm
)
{
...
...
@@ -473,7 +538,22 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
if
(
isp
->
smk_task
==
NULL
||
isp
->
smk_task
==
bsp
->
smk_task
)
return
0
;
if
(
bprm
->
unsafe
)
if
(
bprm
->
unsafe
&
(
LSM_UNSAFE_PTRACE
|
LSM_UNSAFE_PTRACE_CAP
))
{
struct
task_struct
*
tracer
;
rc
=
0
;
rcu_read_lock
();
tracer
=
ptrace_parent
(
current
);
if
(
likely
(
tracer
!=
NULL
))
rc
=
smk_ptrace_rule_check
(
tracer
,
isp
->
smk_task
->
smk_known
,
PTRACE_MODE_ATTACH
,
__func__
);
rcu_read_unlock
();
if
(
rc
!=
0
)
return
rc
;
}
else
if
(
bprm
->
unsafe
)
return
-
EPERM
;
bsp
->
smk_task
=
isp
->
smk_task
;
...
...
@@ -880,18 +960,20 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
return
;
}
skp
=
smk_import_entry
(
value
,
size
);
if
(
strcmp
(
name
,
XATTR_NAME_SMACK
)
==
0
)
{
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
!=
NULL
)
isp
->
smk_inode
=
skp
->
smk_known
;
else
isp
->
smk_inode
=
smack_known_invalid
.
smk_known
;
}
else
if
(
strcmp
(
name
,
XATTR_NAME_SMACKEXEC
)
==
0
)
{
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
!=
NULL
)
isp
->
smk_task
=
skp
;
else
isp
->
smk_task
=
&
smack_known_invalid
;
}
else
if
(
strcmp
(
name
,
XATTR_NAME_SMACKMMAP
)
==
0
)
{
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
!=
NULL
)
isp
->
smk_mmap
=
skp
;
else
...
...
@@ -938,24 +1020,37 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
strcmp
(
name
,
XATTR_NAME_SMACKIPOUT
)
==
0
||
strcmp
(
name
,
XATTR_NAME_SMACKEXEC
)
==
0
||
strcmp
(
name
,
XATTR_NAME_SMACKTRANSMUTE
)
==
0
||
strcmp
(
name
,
XATTR_NAME_SMACKMMAP
))
{
strcmp
(
name
,
XATTR_NAME_SMACKMMAP
)
==
0
)
{
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
rc
=
-
EPERM
;
}
else
rc
=
cap_inode_removexattr
(
dentry
,
name
);
if
(
rc
!=
0
)
return
rc
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_DENTRY
);
smk_ad_setfield_u_fs_path_dentry
(
&
ad
,
dentry
);
if
(
rc
==
0
)
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
if
(
rc
==
0
)
{
isp
=
dentry
->
d_inode
->
i_security
;
rc
=
smk_curacc
(
smk_of_inode
(
dentry
->
d_inode
),
MAY_WRITE
,
&
ad
);
if
(
rc
!=
0
)
return
rc
;
isp
=
dentry
->
d_inode
->
i_security
;
/*
* Don't do anything special for these.
* XATTR_NAME_SMACKIPIN
* XATTR_NAME_SMACKIPOUT
* XATTR_NAME_SMACKEXEC
*/
if
(
strcmp
(
name
,
XATTR_NAME_SMACK
)
==
0
)
isp
->
smk_task
=
NULL
;
else
if
(
strcmp
(
name
,
XATTR_NAME_SMACKMMAP
)
==
0
)
isp
->
smk_mmap
=
NULL
;
}
else
if
(
strcmp
(
name
,
XATTR_NAME_SMACKTRANSMUTE
)
==
0
)
isp
->
smk_flags
&=
~
SMK_INODE_TRANSMUTE
;
return
rc
;
return
0
;
}
/**
...
...
@@ -1000,7 +1095,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
ssp
=
sock
->
sk
->
sk_security
;
if
(
strcmp
(
name
,
XATTR_SMACK_IPIN
)
==
0
)
isp
=
ssp
->
smk_in
;
isp
=
ssp
->
smk_in
->
smk_known
;
else
if
(
strcmp
(
name
,
XATTR_SMACK_IPOUT
)
==
0
)
isp
=
ssp
->
smk_out
->
smk_known
;
else
...
...
@@ -1367,19 +1462,32 @@ static int smack_file_receive(struct file *file)
/**
* smack_file_open - Smack dentry open processing
* @file: the object
* @cred:
unused
* @cred:
task credential
*
* Set the security blob in the file structure.
* Allow the open only if the task has read access. There are
* many read operations (e.g. fstat) that you can do with an
* fd even if you have the file open write-only.
*
* Returns 0
*/
static
int
smack_file_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
struct
task_smack
*
tsp
=
cred
->
security
;
struct
inode_smack
*
isp
=
file_inode
(
file
)
->
i_security
;
struct
smk_audit_info
ad
;
int
rc
;
file
->
f_security
=
isp
->
smk_inode
;
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
return
0
;
return
0
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_access
(
tsp
->
smk_task
,
isp
->
smk_inode
,
MAY_READ
,
&
ad
);
if
(
rc
==
0
)
file
->
f_security
=
isp
->
smk_inode
;
return
rc
;
}
/*
...
...
@@ -1764,7 +1872,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
if
(
ssp
==
NULL
)
return
-
ENOMEM
;
ssp
->
smk_in
=
skp
->
smk_known
;
ssp
->
smk_in
=
skp
;
ssp
->
smk_out
=
skp
;
ssp
->
smk_packet
=
NULL
;
...
...
@@ -2004,7 +2112,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
if
(
act
==
SMK_RECEIVING
)
{
skp
=
smack_net_ambient
;
object
=
ssp
->
smk_in
;
object
=
ssp
->
smk_in
->
smk_known
;
}
else
{
skp
=
ssp
->
smk_out
;
object
=
smack_net_ambient
->
smk_known
;
...
...
@@ -2034,9 +2142,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
list_for_each_entry
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
spp
->
smk_port
!=
port
)
continue
;
object
=
spp
->
smk_in
;
object
=
spp
->
smk_in
->
smk_known
;
if
(
act
==
SMK_CONNECTING
)
ssp
->
smk_packet
=
spp
->
smk_out
->
smk_known
;
ssp
->
smk_packet
=
spp
->
smk_out
;
break
;
}
...
...
@@ -2076,7 +2184,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
int
rc
=
0
;
if
(
value
==
NULL
||
size
>
SMK_LONGLABEL
||
size
==
0
)
return
-
E
ACCES
;
return
-
E
INVAL
;
skp
=
smk_import_entry
(
value
,
size
);
if
(
skp
==
NULL
)
...
...
@@ -2100,7 +2208,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
ssp
=
sock
->
sk
->
sk_security
;
if
(
strcmp
(
name
,
XATTR_SMACK_IPIN
)
==
0
)
ssp
->
smk_in
=
skp
->
smk_known
;
ssp
->
smk_in
=
skp
;
else
if
(
strcmp
(
name
,
XATTR_SMACK_IPOUT
)
==
0
)
{
ssp
->
smk_out
=
skp
;
if
(
sock
->
sk
->
sk_family
==
PF_INET
)
{
...
...
@@ -2713,6 +2821,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* of the superblock.
*/
if
(
opt_dentry
->
d_parent
==
opt_dentry
)
{
if
(
sbp
->
s_magic
==
CGROUP_SUPER_MAGIC
)
{
/*
* The cgroup filesystem is never mounted,
* so there's no opportunity to set the mount
* options.
*/
sbsp
->
smk_root
=
smack_known_star
.
smk_known
;
sbsp
->
smk_default
=
smack_known_star
.
smk_known
;
}
isp
->
smk_inode
=
sbsp
->
smk_root
;
isp
->
smk_flags
|=
SMK_INODE_INSTANT
;
goto
unlockandout
;
...
...
@@ -2726,16 +2843,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
switch
(
sbp
->
s_magic
)
{
case
SMACK_MAGIC
:
case
PIPEFS_MAGIC
:
case
SOCKFS_MAGIC
:
case
CGROUP_SUPER_MAGIC
:
/*
* Casey says that it's a little embarrassing
* that the smack file system doesn't do
* extended attributes.
*/
final
=
smack_known_star
.
smk_known
;
break
;
case
PIPEFS_MAGIC
:
/*
*
* Casey says pipes are easy (?)
*
* Socket access is controlled by the socket
* structures associated with the task involved.
*
* Cgroupfs is special
*/
final
=
smack_known_star
.
smk_known
;
break
;
...
...
@@ -2747,13 +2868,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
final
=
ckp
->
smk_known
;
break
;
case
SOCKFS_MAGIC
:
/*
* Socket access is controlled by the socket
* structures associated with the task involved.
*/
final
=
smack_known_star
.
smk_known
;
break
;
case
PROC_SUPER_MAGIC
:
/*
* Casey says procfs appears not to care.
...
...
@@ -2959,30 +3073,34 @@ static int smack_unix_stream_connect(struct sock *sock,
struct
sock
*
other
,
struct
sock
*
newsk
)
{
struct
smack_known
*
skp
;
struct
smack_known
*
okp
;
struct
socket_smack
*
ssp
=
sock
->
sk_security
;
struct
socket_smack
*
osp
=
other
->
sk_security
;
struct
socket_smack
*
nsp
=
newsk
->
sk_security
;
struct
smk_audit_info
ad
;
int
rc
=
0
;
#ifdef CONFIG_AUDIT
struct
lsm_network_audit
net
;
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
smk_ad_setfield_u_net_sk
(
&
ad
,
other
);
#endif
if
(
!
smack_privileged
(
CAP_MAC_OVERRIDE
))
{
skp
=
ssp
->
smk_out
;
rc
=
smk_access
(
skp
,
osp
->
smk_in
,
MAY_WRITE
,
&
ad
);
okp
=
osp
->
smk_out
;
#ifdef CONFIG_AUDIT
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
smk_ad_setfield_u_net_sk
(
&
ad
,
other
);
#endif
rc
=
smk_access
(
skp
,
okp
->
smk_known
,
MAY_WRITE
,
&
ad
);
if
(
rc
==
0
)
rc
=
smk_access
(
okp
,
okp
->
smk_known
,
MAY_WRITE
,
NULL
);
}
/*
* Cross reference the peer labels for SO_PEERSEC.
*/
if
(
rc
==
0
)
{
nsp
->
smk_packet
=
ssp
->
smk_out
->
smk_known
;
ssp
->
smk_packet
=
osp
->
smk_out
->
smk_known
;
nsp
->
smk_packet
=
ssp
->
smk_out
;
ssp
->
smk_packet
=
osp
->
smk_out
;
}
return
rc
;
...
...
@@ -3014,7 +3132,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
return
0
;
skp
=
ssp
->
smk_out
;
return
smk_access
(
skp
,
osp
->
smk_in
,
MAY_WRITE
,
&
ad
);
return
smk_access
(
skp
,
osp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
}
/**
...
...
@@ -3109,7 +3227,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
if
(
found
)
return
skp
;
if
(
ssp
!=
NULL
&&
ssp
->
smk_in
==
smack_known_star
.
smk_known
)
if
(
ssp
!=
NULL
&&
ssp
->
smk_in
==
&
smack_known_star
)
return
&
smack_known_web
;
return
&
smack_known_star
;
}
...
...
@@ -3228,7 +3346,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
* This is the simplist possible security model
* for networking.
*/
rc
=
smk_access
(
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
ssp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
if
(
rc
!=
0
)
netlbl_skbuff_err
(
skb
,
rc
,
0
);
break
;
...
...
@@ -3263,7 +3381,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
ssp
=
sock
->
sk
->
sk_security
;
if
(
ssp
->
smk_packet
!=
NULL
)
{
rcp
=
ssp
->
smk_packet
;
rcp
=
ssp
->
smk_packet
->
smk_known
;
slen
=
strlen
(
rcp
)
+
1
;
}
...
...
@@ -3348,7 +3466,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
return
;
ssp
=
sk
->
sk_security
;
ssp
->
smk_in
=
skp
->
smk_known
;
ssp
->
smk_in
=
skp
;
ssp
->
smk_out
=
skp
;
/* cssp->smk_packet is already set in smack_inet_csk_clone() */
}
...
...
@@ -3408,7 +3526,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
* Receiving a packet requires that the other end be able to write
* here. Read access is not required.
*/
rc
=
smk_access
(
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_access
(
skp
,
ssp
->
smk_in
->
smk_known
,
MAY_WRITE
,
&
ad
);
if
(
rc
!=
0
)
return
rc
;
...
...
@@ -3452,7 +3570,7 @@ static void smack_inet_csk_clone(struct sock *sk,
if
(
req
->
peer_secid
!=
0
)
{
skp
=
smack_from_secid
(
req
->
peer_secid
);
ssp
->
smk_packet
=
skp
->
smk_known
;
ssp
->
smk_packet
=
skp
;
}
else
ssp
->
smk_packet
=
NULL
;
}
...
...
security/smack/smackfs.c
浏览文件 @
2fd4e669
...
...
@@ -53,6 +53,7 @@ enum smk_inos {
SMK_REVOKE_SUBJ
=
18
,
/* set rules with subject label to '-' */
SMK_CHANGE_RULE
=
19
,
/* change or add rules (long labels) */
SMK_SYSLOG
=
20
,
/* change syslog label) */
SMK_PTRACE
=
21
,
/* set ptrace rule */
};
/*
...
...
@@ -100,6 +101,15 @@ struct smack_known *smack_onlycap;
*/
struct
smack_known
*
smack_syslog_label
;
/*
* Ptrace current rule
* SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based)
* SMACK_PTRACE_EXACT labels must match, but can be overriden with
* CAP_SYS_PTRACE
* SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect
*/
int
smack_ptrace_rule
=
SMACK_PTRACE_DEFAULT
;
/*
* Certain IP addresses may be designated as single label hosts.
* Packets are sent there unlabeled, but only from tasks that
...
...
@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
data
[
count
]
=
'\0'
;
rc
=
sscanf
(
data
,
"%hhd.%hhd.%hhd.%hhd/%
d
%s"
,
rc
=
sscanf
(
data
,
"%hhd.%hhd.%hhd.%hhd/%
u
%s"
,
&
host
[
0
],
&
host
[
1
],
&
host
[
2
],
&
host
[
3
],
&
m
,
smack
);
if
(
rc
!=
6
)
{
rc
=
sscanf
(
data
,
"%hhd.%hhd.%hhd.%hhd %s"
,
...
...
@@ -2243,6 +2253,68 @@ static const struct file_operations smk_syslog_ops = {
};
/**
* smk_read_ptrace - read() for /smack/ptrace
* @filp: file pointer, not actually used
* @buf: where to put the result
* @count: maximum to send along
* @ppos: where to start
*
* Returns number of bytes read or error code, as appropriate
*/
static
ssize_t
smk_read_ptrace
(
struct
file
*
filp
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
char
temp
[
32
];
ssize_t
rc
;
if
(
*
ppos
!=
0
)
return
0
;
sprintf
(
temp
,
"%d
\n
"
,
smack_ptrace_rule
);
rc
=
simple_read_from_buffer
(
buf
,
count
,
ppos
,
temp
,
strlen
(
temp
));
return
rc
;
}
/**
* smk_write_ptrace - write() for /smack/ptrace
* @file: file pointer
* @buf: data from user space
* @count: bytes sent
* @ppos: where to start - must be 0
*/
static
ssize_t
smk_write_ptrace
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
char
temp
[
32
];
int
i
;
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
))
return
-
EPERM
;
if
(
*
ppos
!=
0
||
count
>=
sizeof
(
temp
)
||
count
==
0
)
return
-
EINVAL
;
if
(
copy_from_user
(
temp
,
buf
,
count
)
!=
0
)
return
-
EFAULT
;
temp
[
count
]
=
'\0'
;
if
(
sscanf
(
temp
,
"%d"
,
&
i
)
!=
1
)
return
-
EINVAL
;
if
(
i
<
SMACK_PTRACE_DEFAULT
||
i
>
SMACK_PTRACE_MAX
)
return
-
EINVAL
;
smack_ptrace_rule
=
i
;
return
count
;
}
static
const
struct
file_operations
smk_ptrace_ops
=
{
.
write
=
smk_write_ptrace
,
.
read
=
smk_read_ptrace
,
.
llseek
=
default_llseek
,
};
/**
* smk_fill_super - fill the smackfs superblock
* @sb: the empty superblock
...
...
@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
"change-rule"
,
&
smk_change_rule_ops
,
S_IRUGO
|
S_IWUSR
},
[
SMK_SYSLOG
]
=
{
"syslog"
,
&
smk_syslog_ops
,
S_IRUGO
|
S_IWUSR
},
[
SMK_PTRACE
]
=
{
"ptrace"
,
&
smk_ptrace_ops
,
S_IRUGO
|
S_IWUSR
},
/* last one */
{
""
}
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录