Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
2fd4e669
Commit
2fd4e669
authored
May 20, 2014
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'smack-for-3.16' of
git://git.gitorious.org/smack-next/kernel
into next
parents
fab71a90
ec554fa7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
307 additions
and
73 deletions
+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
No files found.
Documentation/security/Smack.txt
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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 */
{
""
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment