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
a2a15479
Commit
a2a15479
authored
Feb 10, 2017
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'stable-4.11' of
git://git.infradead.org/users/pcmoore/selinux
into next
parents
e2241be6
1ea0ce40
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
341 additions
and
314 deletions
+341
-314
fs/proc/base.c
fs/proc/base.c
+9
-4
include/linux/lsm_hooks.h
include/linux/lsm_hooks.h
+1
-9
include/linux/security.h
include/linux/security.h
+2
-8
kernel/exit.c
kernel/exit.c
+2
-17
security/apparmor/lsm.c
security/apparmor/lsm.c
+2
-5
security/security.c
security/security.c
+2
-8
security/selinux/hooks.c
security/selinux/hooks.c
+188
-191
security/selinux/include/classmap.h
security/selinux/include/classmap.h
+62
-0
security/selinux/include/objsec.h
security/selinux/include/objsec.h
+10
-0
security/selinux/include/security.h
security/selinux/include/security.h
+2
-1
security/selinux/selinuxfs.c
security/selinux/selinuxfs.c
+57
-41
security/selinux/ss/services.c
security/selinux/ss/services.c
+3
-0
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+1
-30
No files found.
fs/proc/base.c
View file @
a2a15479
...
...
@@ -2488,6 +2488,12 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
length
=
-
ESRCH
;
if
(
!
task
)
goto
out_no_task
;
/* A task may only write its own attributes. */
length
=
-
EACCES
;
if
(
current
!=
task
)
goto
out
;
if
(
count
>
PAGE_SIZE
)
count
=
PAGE_SIZE
;
...
...
@@ -2503,14 +2509,13 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
}
/* Guard against adverse ptrace interaction */
length
=
mutex_lock_interruptible
(
&
task
->
signal
->
cred_guard_mutex
);
length
=
mutex_lock_interruptible
(
&
current
->
signal
->
cred_guard_mutex
);
if
(
length
<
0
)
goto
out_free
;
length
=
security_setprocattr
(
task
,
(
char
*
)
file
->
f_path
.
dentry
->
d_name
.
name
,
length
=
security_setprocattr
(
file
->
f_path
.
dentry
->
d_name
.
name
,
page
,
count
);
mutex_unlock
(
&
task
->
signal
->
cred_guard_mutex
);
mutex_unlock
(
&
current
->
signal
->
cred_guard_mutex
);
out_free:
kfree
(
page
);
out:
...
...
include/linux/lsm_hooks.h
View file @
a2a15479
...
...
@@ -665,11 +665,6 @@
* @sig contains the signal value.
* @secid contains the sid of the process where the signal originated
* Return 0 if permission is granted.
* @task_wait:
* Check permission before allowing a process to reap a child process @p
* and collect its status information.
* @p contains the task_struct for process.
* Return 0 if permission is granted.
* @task_prctl:
* Check permission before performing a process control operation on the
* current process.
...
...
@@ -1506,7 +1501,6 @@ union security_list_options {
int
(
*
task_movememory
)(
struct
task_struct
*
p
);
int
(
*
task_kill
)(
struct
task_struct
*
p
,
struct
siginfo
*
info
,
int
sig
,
u32
secid
);
int
(
*
task_wait
)(
struct
task_struct
*
p
);
int
(
*
task_prctl
)(
int
option
,
unsigned
long
arg2
,
unsigned
long
arg3
,
unsigned
long
arg4
,
unsigned
long
arg5
);
void
(
*
task_to_inode
)(
struct
task_struct
*
p
,
struct
inode
*
inode
);
...
...
@@ -1546,8 +1540,7 @@ union security_list_options {
void
(
*
d_instantiate
)(
struct
dentry
*
dentry
,
struct
inode
*
inode
);
int
(
*
getprocattr
)(
struct
task_struct
*
p
,
char
*
name
,
char
**
value
);
int
(
*
setprocattr
)(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
);
int
(
*
setprocattr
)(
const
char
*
name
,
void
*
value
,
size_t
size
);
int
(
*
ismaclabel
)(
const
char
*
name
);
int
(
*
secid_to_secctx
)(
u32
secid
,
char
**
secdata
,
u32
*
seclen
);
int
(
*
secctx_to_secid
)(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
);
...
...
@@ -1767,7 +1760,6 @@ struct security_hook_heads {
struct
list_head
task_getscheduler
;
struct
list_head
task_movememory
;
struct
list_head
task_kill
;
struct
list_head
task_wait
;
struct
list_head
task_prctl
;
struct
list_head
task_to_inode
;
struct
list_head
ipc_permission
;
...
...
include/linux/security.h
View file @
a2a15479
...
...
@@ -332,7 +332,6 @@ int security_task_getscheduler(struct task_struct *p);
int
security_task_movememory
(
struct
task_struct
*
p
);
int
security_task_kill
(
struct
task_struct
*
p
,
struct
siginfo
*
info
,
int
sig
,
u32
secid
);
int
security_task_wait
(
struct
task_struct
*
p
);
int
security_task_prctl
(
int
option
,
unsigned
long
arg2
,
unsigned
long
arg3
,
unsigned
long
arg4
,
unsigned
long
arg5
);
void
security_task_to_inode
(
struct
task_struct
*
p
,
struct
inode
*
inode
);
...
...
@@ -361,7 +360,7 @@ int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
unsigned
nsops
,
int
alter
);
void
security_d_instantiate
(
struct
dentry
*
dentry
,
struct
inode
*
inode
);
int
security_getprocattr
(
struct
task_struct
*
p
,
char
*
name
,
char
**
value
);
int
security_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
);
int
security_setprocattr
(
const
char
*
name
,
void
*
value
,
size_t
size
);
int
security_netlink_send
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
security_ismaclabel
(
const
char
*
name
);
int
security_secid_to_secctx
(
u32
secid
,
char
**
secdata
,
u32
*
seclen
);
...
...
@@ -980,11 +979,6 @@ static inline int security_task_kill(struct task_struct *p,
return
0
;
}
static
inline
int
security_task_wait
(
struct
task_struct
*
p
)
{
return
0
;
}
static
inline
int
security_task_prctl
(
int
option
,
unsigned
long
arg2
,
unsigned
long
arg3
,
unsigned
long
arg4
,
...
...
@@ -1106,7 +1100,7 @@ static inline int security_getprocattr(struct task_struct *p, char *name, char *
return
-
EINVAL
;
}
static
inline
int
security_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
)
static
inline
int
security_setprocattr
(
char
*
name
,
void
*
value
,
size_t
size
)
{
return
-
EINVAL
;
}
...
...
kernel/exit.c
View file @
a2a15479
...
...
@@ -14,7 +14,6 @@
#include <linux/tty.h>
#include <linux/iocontext.h>
#include <linux/key.h>
#include <linux/security.h>
#include <linux/cpu.h>
#include <linux/acct.h>
#include <linux/tsacct_kern.h>
...
...
@@ -1360,7 +1359,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
* Returns nonzero for a final return, when we have unlocked tasklist_lock.
* Returns zero if the search for a child should continue;
* then ->notask_error is 0 if @p is an eligible child,
* or
another error from security_task_wait(), or
still -ECHILD.
* or still -ECHILD.
*/
static
int
wait_consider_task
(
struct
wait_opts
*
wo
,
int
ptrace
,
struct
task_struct
*
p
)
...
...
@@ -1380,20 +1379,6 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
if
(
!
ret
)
return
ret
;
ret
=
security_task_wait
(
p
);
if
(
unlikely
(
ret
<
0
))
{
/*
* If we have not yet seen any eligible child,
* then let this error code replace -ECHILD.
* A permission error will give the user a clue
* to look for security policy problems, rather
* than for mysterious wait bugs.
*/
if
(
wo
->
notask_error
)
wo
->
notask_error
=
ret
;
return
0
;
}
if
(
unlikely
(
exit_state
==
EXIT_TRACE
))
{
/*
* ptrace == 0 means we are the natural parent. In this case
...
...
@@ -1486,7 +1471,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
* Returns nonzero for a final return, when we have unlocked tasklist_lock.
* Returns zero if the search for a child should continue; then
* ->notask_error is 0 if there were any eligible children,
* or
another error from security_task_wait(), or
still -ECHILD.
* or still -ECHILD.
*/
static
int
do_wait_thread
(
struct
wait_opts
*
wo
,
struct
task_struct
*
tsk
)
{
...
...
security/apparmor/lsm.c
View file @
a2a15479
...
...
@@ -505,8 +505,8 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
return
error
;
}
static
int
apparmor_setprocattr
(
struct
task_struct
*
task
,
char
*
nam
e
,
void
*
value
,
size_t
size
)
static
int
apparmor_setprocattr
(
const
char
*
name
,
void
*
valu
e
,
size_t
size
)
{
char
*
command
,
*
largs
=
NULL
,
*
args
=
value
;
size_t
arg_size
;
...
...
@@ -515,9 +515,6 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
if
(
size
==
0
)
return
-
EINVAL
;
/* task can only write its own attributes */
if
(
current
!=
task
)
return
-
EACCES
;
/* AppArmor requires that the buffer must be null terminated atm */
if
(
args
[
size
-
1
]
!=
'\0'
)
{
...
...
security/security.c
View file @
a2a15479
...
...
@@ -1063,11 +1063,6 @@ int security_task_kill(struct task_struct *p, struct siginfo *info,
return
call_int_hook
(
task_kill
,
0
,
p
,
info
,
sig
,
secid
);
}
int
security_task_wait
(
struct
task_struct
*
p
)
{
return
call_int_hook
(
task_wait
,
0
,
p
);
}
int
security_task_prctl
(
int
option
,
unsigned
long
arg2
,
unsigned
long
arg3
,
unsigned
long
arg4
,
unsigned
long
arg5
)
{
...
...
@@ -1208,9 +1203,9 @@ int security_getprocattr(struct task_struct *p, char *name, char **value)
return
call_int_hook
(
getprocattr
,
-
EINVAL
,
p
,
name
,
value
);
}
int
security_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
)
int
security_setprocattr
(
const
char
*
name
,
void
*
value
,
size_t
size
)
{
return
call_int_hook
(
setprocattr
,
-
EINVAL
,
p
,
name
,
value
,
size
);
return
call_int_hook
(
setprocattr
,
-
EINVAL
,
name
,
value
,
size
);
}
int
security_netlink_send
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
...
...
@@ -1807,7 +1802,6 @@ struct security_hook_heads security_hook_heads = {
.
task_movememory
=
LIST_HEAD_INIT
(
security_hook_heads
.
task_movememory
),
.
task_kill
=
LIST_HEAD_INIT
(
security_hook_heads
.
task_kill
),
.
task_wait
=
LIST_HEAD_INIT
(
security_hook_heads
.
task_wait
),
.
task_prctl
=
LIST_HEAD_INIT
(
security_hook_heads
.
task_prctl
),
.
task_to_inode
=
LIST_HEAD_INIT
(
security_hook_heads
.
task_to_inode
),
...
...
security/selinux/hooks.c
View file @
a2a15479
...
...
@@ -210,16 +210,6 @@ static inline u32 task_sid(const struct task_struct *task)
return
sid
;
}
/*
* get the subjective security ID of the current task
*/
static
inline
u32
current_sid
(
void
)
{
const
struct
task_security_struct
*
tsec
=
current_security
();
return
tsec
->
sid
;
}
/* Allocate and free functions for each kind of security blob. */
static
int
inode_alloc_security
(
struct
inode
*
inode
)
...
...
@@ -490,8 +480,11 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
sbsec
->
behavior
==
SECURITY_FS_USE_NATIVE
||
/* Special handling. Genfs but also in-core setxattr handler */
!
strcmp
(
sb
->
s_type
->
name
,
"sysfs"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"cgroup"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"cgroup2"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"pstore"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"debugfs"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"tracefs"
)
||
!
strcmp
(
sb
->
s_type
->
name
,
"rootfs"
);
}
...
...
@@ -833,10 +826,14 @@ static int selinux_set_mnt_opts(struct super_block *sb,
}
/*
* If this is a user namespace mount, no contexts are allowed
* on the command line and security labels must be ignored.
* If this is a user namespace mount and the filesystem type is not
* explicitly whitelisted, then no contexts are allowed on the command
* line and security labels must be ignored.
*/
if
(
sb
->
s_user_ns
!=
&
init_user_ns
)
{
if
(
sb
->
s_user_ns
!=
&
init_user_ns
&&
strcmp
(
sb
->
s_type
->
name
,
"tmpfs"
)
&&
strcmp
(
sb
->
s_type
->
name
,
"ramfs"
)
&&
strcmp
(
sb
->
s_type
->
name
,
"devpts"
))
{
if
(
context_sid
||
fscontext_sid
||
rootcontext_sid
||
defcontext_sid
)
{
rc
=
-
EACCES
;
...
...
@@ -1268,6 +1265,8 @@ static inline int default_protocol_dgram(int protocol)
static
inline
u16
socket_type_to_security_class
(
int
family
,
int
type
,
int
protocol
)
{
int
extsockclass
=
selinux_policycap_extsockclass
;
switch
(
family
)
{
case
PF_UNIX
:
switch
(
type
)
{
...
...
@@ -1282,13 +1281,19 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
case
PF_INET6
:
switch
(
type
)
{
case
SOCK_STREAM
:
case
SOCK_SEQPACKET
:
if
(
default_protocol_stream
(
protocol
))
return
SECCLASS_TCP_SOCKET
;
else
if
(
extsockclass
&&
protocol
==
IPPROTO_SCTP
)
return
SECCLASS_SCTP_SOCKET
;
else
return
SECCLASS_RAWIP_SOCKET
;
case
SOCK_DGRAM
:
if
(
default_protocol_dgram
(
protocol
))
return
SECCLASS_UDP_SOCKET
;
else
if
(
extsockclass
&&
(
protocol
==
IPPROTO_ICMP
||
protocol
==
IPPROTO_ICMPV6
))
return
SECCLASS_ICMP_SOCKET
;
else
return
SECCLASS_RAWIP_SOCKET
;
case
SOCK_DCCP
:
...
...
@@ -1342,6 +1347,66 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
return
SECCLASS_APPLETALK_SOCKET
;
}
if
(
extsockclass
)
{
switch
(
family
)
{
case
PF_AX25
:
return
SECCLASS_AX25_SOCKET
;
case
PF_IPX
:
return
SECCLASS_IPX_SOCKET
;
case
PF_NETROM
:
return
SECCLASS_NETROM_SOCKET
;
case
PF_ATMPVC
:
return
SECCLASS_ATMPVC_SOCKET
;
case
PF_X25
:
return
SECCLASS_X25_SOCKET
;
case
PF_ROSE
:
return
SECCLASS_ROSE_SOCKET
;
case
PF_DECnet
:
return
SECCLASS_DECNET_SOCKET
;
case
PF_ATMSVC
:
return
SECCLASS_ATMSVC_SOCKET
;
case
PF_RDS
:
return
SECCLASS_RDS_SOCKET
;
case
PF_IRDA
:
return
SECCLASS_IRDA_SOCKET
;
case
PF_PPPOX
:
return
SECCLASS_PPPOX_SOCKET
;
case
PF_LLC
:
return
SECCLASS_LLC_SOCKET
;
case
PF_CAN
:
return
SECCLASS_CAN_SOCKET
;
case
PF_TIPC
:
return
SECCLASS_TIPC_SOCKET
;
case
PF_BLUETOOTH
:
return
SECCLASS_BLUETOOTH_SOCKET
;
case
PF_IUCV
:
return
SECCLASS_IUCV_SOCKET
;
case
PF_RXRPC
:
return
SECCLASS_RXRPC_SOCKET
;
case
PF_ISDN
:
return
SECCLASS_ISDN_SOCKET
;
case
PF_PHONET
:
return
SECCLASS_PHONET_SOCKET
;
case
PF_IEEE802154
:
return
SECCLASS_IEEE802154_SOCKET
;
case
PF_CAIF
:
return
SECCLASS_CAIF_SOCKET
;
case
PF_ALG
:
return
SECCLASS_ALG_SOCKET
;
case
PF_NFC
:
return
SECCLASS_NFC_SOCKET
;
case
PF_VSOCK
:
return
SECCLASS_VSOCK_SOCKET
;
case
PF_KCM
:
return
SECCLASS_KCM_SOCKET
;
case
PF_QIPCRTR
:
return
SECCLASS_QIPCRTR_SOCKET
;
#if PF_MAX > 43
#error New address family defined, please update this function.
#endif
}
}
return
SECCLASS_SOCKET
;
}
...
...
@@ -1608,55 +1673,6 @@ static inline u32 signal_to_av(int sig)
return
perm
;
}
/*
* Check permission between a pair of credentials
* fork check, ptrace check, etc.
*/
static
int
cred_has_perm
(
const
struct
cred
*
actor
,
const
struct
cred
*
target
,
u32
perms
)
{
u32
asid
=
cred_sid
(
actor
),
tsid
=
cred_sid
(
target
);
return
avc_has_perm
(
asid
,
tsid
,
SECCLASS_PROCESS
,
perms
,
NULL
);
}
/*
* Check permission between a pair of tasks, e.g. signal checks,
* fork check, ptrace check, etc.
* tsk1 is the actor and tsk2 is the target
* - this uses the default subjective creds of tsk1
*/
static
int
task_has_perm
(
const
struct
task_struct
*
tsk1
,
const
struct
task_struct
*
tsk2
,
u32
perms
)
{
const
struct
task_security_struct
*
__tsec1
,
*
__tsec2
;
u32
sid1
,
sid2
;
rcu_read_lock
();
__tsec1
=
__task_cred
(
tsk1
)
->
security
;
sid1
=
__tsec1
->
sid
;
__tsec2
=
__task_cred
(
tsk2
)
->
security
;
sid2
=
__tsec2
->
sid
;
rcu_read_unlock
();
return
avc_has_perm
(
sid1
,
sid2
,
SECCLASS_PROCESS
,
perms
,
NULL
);
}
/*
* Check permission between current and another task, e.g. signal checks,
* fork check, ptrace check, etc.
* current is the actor and tsk2 is the target
* - this uses current's subjective creds
*/
static
int
current_has_perm
(
const
struct
task_struct
*
tsk
,
u32
perms
)
{
u32
sid
,
tsid
;
sid
=
current_sid
();
tsid
=
task_sid
(
tsk
);
return
avc_has_perm
(
sid
,
tsid
,
SECCLASS_PROCESS
,
perms
,
NULL
);
}
#if CAP_LAST_CAP > 63
#error Fix SELinux to handle capabilities > 63.
#endif
...
...
@@ -1698,16 +1714,6 @@ static int cred_has_capability(const struct cred *cred,
return
rc
;
}
/* Check whether a task is allowed to use a system operation. */
static
int
task_has_system
(
struct
task_struct
*
tsk
,
u32
perms
)
{
u32
sid
=
task_sid
(
tsk
);
return
avc_has_perm
(
sid
,
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
perms
,
NULL
);
}
/* Check whether a task has a particular permission to an inode.
The 'adp' parameter is optional and allows other audit
data to be passed (e.g. the dentry). */
...
...
@@ -1879,15 +1885,6 @@ static int may_create(struct inode *dir,
FILESYSTEM__ASSOCIATE
,
&
ad
);
}
/* Check whether a task can create a key. */
static
int
may_create_key
(
u32
ksid
,
struct
task_struct
*
ctx
)
{
u32
sid
=
task_sid
(
ctx
);
return
avc_has_perm
(
sid
,
ksid
,
SECCLASS_KEY
,
KEY__CREATE
,
NULL
);
}
#define MAY_LINK 0
#define MAY_UNLINK 1
#define MAY_RMDIR 2
...
...
@@ -2143,24 +2140,26 @@ static int selinux_binder_transfer_file(struct task_struct *from,
static
int
selinux_ptrace_access_check
(
struct
task_struct
*
child
,
unsigned
int
mode
)
{
if
(
mode
&
PTRACE_MODE_READ
)
{
u32
sid
=
current_sid
();
u32
csid
=
task_sid
(
child
);
if
(
mode
&
PTRACE_MODE_READ
)
return
avc_has_perm
(
sid
,
csid
,
SECCLASS_FILE
,
FILE__READ
,
NULL
);
}
return
current_has_perm
(
child
,
PROCESS__PTRACE
);
return
avc_has_perm
(
sid
,
csid
,
SECCLASS_PROCESS
,
PROCESS__PTRACE
,
NULL
);
}
static
int
selinux_ptrace_traceme
(
struct
task_struct
*
parent
)
{
return
task_has_perm
(
parent
,
current
,
PROCESS__PTRACE
);
return
avc_has_perm
(
task_sid
(
parent
),
current_sid
(),
SECCLASS_PROCESS
,
PROCESS__PTRACE
,
NULL
);
}
static
int
selinux_capget
(
struct
task_struct
*
target
,
kernel_cap_t
*
effective
,
kernel_cap_t
*
inheritable
,
kernel_cap_t
*
permitted
)
{
return
current_has_perm
(
target
,
PROCESS__GETCAP
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
target
),
SECCLASS_PROCESS
,
PROCESS__GETCAP
,
NULL
);
}
static
int
selinux_capset
(
struct
cred
*
new
,
const
struct
cred
*
old
,
...
...
@@ -2168,7 +2167,8 @@ static int selinux_capset(struct cred *new, const struct cred *old,
const
kernel_cap_t
*
inheritable
,
const
kernel_cap_t
*
permitted
)
{
return
cred_has_perm
(
old
,
new
,
PROCESS__SETCAP
);
return
avc_has_perm
(
cred_sid
(
old
),
cred_sid
(
new
),
SECCLASS_PROCESS
,
PROCESS__SETCAP
,
NULL
);
}
/*
...
...
@@ -2224,29 +2224,22 @@ static int selinux_quota_on(struct dentry *dentry)
static
int
selinux_syslog
(
int
type
)
{
int
rc
;
switch
(
type
)
{
case
SYSLOG_ACTION_READ_ALL
:
/* Read last kernel messages */
case
SYSLOG_ACTION_SIZE_BUFFER
:
/* Return size of the log buffer */
r
c
=
task_has_system
(
current
,
SYSTEM__SYSLOG_READ
);
break
;
r
eturn
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__SYSLOG_READ
,
NULL
)
;
case
SYSLOG_ACTION_CONSOLE_OFF
:
/* Disable logging to console */
case
SYSLOG_ACTION_CONSOLE_ON
:
/* Enable logging to console */
/* Set level of messages printed to console */
case
SYSLOG_ACTION_CONSOLE_LEVEL
:
rc
=
task_has_system
(
current
,
SYSTEM__SYSLOG_CONSOLE
);
break
;
case
SYSLOG_ACTION_CLOSE
:
/* Close log */
case
SYSLOG_ACTION_OPEN
:
/* Open log */
case
SYSLOG_ACTION_READ
:
/* Read from log */
case
SYSLOG_ACTION_READ_CLEAR
:
/* Read/clear last kernel messages */
case
SYSLOG_ACTION_CLEAR
:
/* Clear ring buffer */
default:
rc
=
task_has_system
(
current
,
SYSTEM__SYSLOG_MOD
);
break
;
return
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__SYSLOG_CONSOLE
,
NULL
);
}
return
rc
;
/* All other syslog types */
return
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__SYSLOG_MOD
,
NULL
);
}
/*
...
...
@@ -2271,13 +2264,13 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
/* binprm security operations */
static
u32
ptrace_parent_sid
(
struct
task_struct
*
task
)
static
u32
ptrace_parent_sid
(
void
)
{
u32
sid
=
0
;
struct
task_struct
*
tracer
;
rcu_read_lock
();
tracer
=
ptrace_parent
(
task
);
tracer
=
ptrace_parent
(
current
);
if
(
tracer
)
sid
=
task_sid
(
tracer
);
rcu_read_unlock
();
...
...
@@ -2406,7 +2399,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
* changes its SID has the appropriate permit */
if
(
bprm
->
unsafe
&
(
LSM_UNSAFE_PTRACE
|
LSM_UNSAFE_PTRACE_CAP
))
{
u32
ptsid
=
ptrace_parent_sid
(
current
);
u32
ptsid
=
ptrace_parent_sid
();
if
(
ptsid
!=
0
)
{
rc
=
avc_has_perm
(
ptsid
,
new_tsec
->
sid
,
SECCLASS_PROCESS
,
...
...
@@ -3503,6 +3496,7 @@ static int default_noexec;
static
int
file_map_prot_check
(
struct
file
*
file
,
unsigned
long
prot
,
int
shared
)
{
const
struct
cred
*
cred
=
current_cred
();
u32
sid
=
cred_sid
(
cred
);
int
rc
=
0
;
if
(
default_noexec
&&
...
...
@@ -3513,7 +3507,8 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
* private file mapping that will also be writable.
* This has an additional check.
*/
rc
=
cred_has_perm
(
cred
,
cred
,
PROCESS__EXECMEM
);
rc
=
avc_has_perm
(
sid
,
sid
,
SECCLASS_PROCESS
,
PROCESS__EXECMEM
,
NULL
);
if
(
rc
)
goto
error
;
}
...
...
@@ -3564,6 +3559,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
unsigned
long
prot
)
{
const
struct
cred
*
cred
=
current_cred
();
u32
sid
=
cred_sid
(
cred
);
if
(
selinux_checkreqprot
)
prot
=
reqprot
;
...
...
@@ -3573,12 +3569,14 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
int
rc
=
0
;
if
(
vma
->
vm_start
>=
vma
->
vm_mm
->
start_brk
&&
vma
->
vm_end
<=
vma
->
vm_mm
->
brk
)
{
rc
=
cred_has_perm
(
cred
,
cred
,
PROCESS__EXECHEAP
);
rc
=
avc_has_perm
(
sid
,
sid
,
SECCLASS_PROCESS
,
PROCESS__EXECHEAP
,
NULL
);
}
else
if
(
!
vma
->
vm_file
&&
((
vma
->
vm_start
<=
vma
->
vm_mm
->
start_stack
&&
vma
->
vm_end
>=
vma
->
vm_mm
->
start_stack
)
||
vma_is_stack_for_current
(
vma
)))
{
rc
=
current_has_perm
(
current
,
PROCESS__EXECSTACK
);
rc
=
avc_has_perm
(
sid
,
sid
,
SECCLASS_PROCESS
,
PROCESS__EXECSTACK
,
NULL
);
}
else
if
(
vma
->
vm_file
&&
vma
->
anon_vma
)
{
/*
* We are making executable a file mapping that has
...
...
@@ -3711,7 +3709,9 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
static
int
selinux_task_create
(
unsigned
long
clone_flags
)
{
return
current_has_perm
(
current
,
PROCESS__FORK
);
u32
sid
=
current_sid
();
return
avc_has_perm
(
sid
,
sid
,
SECCLASS_PROCESS
,
PROCESS__FORK
,
NULL
);
}
/*
...
...
@@ -3821,15 +3821,12 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
static
int
selinux_kernel_module_request
(
char
*
kmod_name
)
{
u32
sid
;
struct
common_audit_data
ad
;
sid
=
task_sid
(
current
);
ad
.
type
=
LSM_AUDIT_DATA_KMOD
;
ad
.
u
.
kmod_name
=
kmod_name
;
return
avc_has_perm
(
sid
,
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
return
avc_has_perm
(
current_sid
()
,
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__MODULE_REQUEST
,
&
ad
);
}
...
...
@@ -3881,17 +3878,20 @@ static int selinux_kernel_read_file(struct file *file,
static
int
selinux_task_setpgid
(
struct
task_struct
*
p
,
pid_t
pgid
)
{
return
current_has_perm
(
p
,
PROCESS__SETPGID
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETPGID
,
NULL
);
}
static
int
selinux_task_getpgid
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__GETPGID
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__GETPGID
,
NULL
);
}
static
int
selinux_task_getsid
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__GETSESSION
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__GETSESSION
,
NULL
);
}
static
void
selinux_task_getsecid
(
struct
task_struct
*
p
,
u32
*
secid
)
...
...
@@ -3901,17 +3901,20 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
static
int
selinux_task_setnice
(
struct
task_struct
*
p
,
int
nice
)
{
return
current_has_perm
(
p
,
PROCESS__SETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETSCHED
,
NULL
);
}
static
int
selinux_task_setioprio
(
struct
task_struct
*
p
,
int
ioprio
)
{
return
current_has_perm
(
p
,
PROCESS__SETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETSCHED
,
NULL
);
}
static
int
selinux_task_getioprio
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__GETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__GETSCHED
,
NULL
);
}
static
int
selinux_task_setrlimit
(
struct
task_struct
*
p
,
unsigned
int
resource
,
...
...
@@ -3924,47 +3927,42 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
later be used as a safe reset point for the soft limit
upon context transitions. See selinux_bprm_committing_creds. */
if
(
old_rlim
->
rlim_max
!=
new_rlim
->
rlim_max
)
return
current_has_perm
(
p
,
PROCESS__SETRLIMIT
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETRLIMIT
,
NULL
);
return
0
;
}
static
int
selinux_task_setscheduler
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__SETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETSCHED
,
NULL
);
}
static
int
selinux_task_getscheduler
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__GETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__GETSCHED
,
NULL
);
}
static
int
selinux_task_movememory
(
struct
task_struct
*
p
)
{
return
current_has_perm
(
p
,
PROCESS__SETSCHED
);
return
avc_has_perm
(
current_sid
(),
task_sid
(
p
),
SECCLASS_PROCESS
,
PROCESS__SETSCHED
,
NULL
);
}
static
int
selinux_task_kill
(
struct
task_struct
*
p
,
struct
siginfo
*
info
,
int
sig
,
u32
secid
)
{
u32
perm
;
int
rc
;
if
(
!
sig
)
perm
=
PROCESS__SIGNULL
;
/* null signal; existence test */
else
perm
=
signal_to_av
(
sig
);
if
(
secid
)
rc
=
avc_has_perm
(
secid
,
task_sid
(
p
),
SECCLASS_PROCESS
,
perm
,
NULL
);
else
rc
=
current_has_perm
(
p
,
perm
);
return
rc
;
}
static
int
selinux_task_wait
(
struct
task_struct
*
p
)
{
return
task_has_perm
(
p
,
current
,
PROCESS__SIGCHLD
);
if
(
!
secid
)
secid
=
current_sid
();
return
avc_has_perm
(
secid
,
task_sid
(
p
),
SECCLASS_PROCESS
,
perm
,
NULL
);
}
static
void
selinux_task_to_inode
(
struct
task_struct
*
p
,
...
...
@@ -4254,12 +4252,11 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec,
socksid
);
}
static
int
sock_has_perm
(
struct
task_struct
*
task
,
struct
sock
*
sk
,
u32
perms
)
static
int
sock_has_perm
(
struct
sock
*
sk
,
u32
perms
)
{
struct
sk_security_struct
*
sksec
=
sk
->
sk_security
;
struct
common_audit_data
ad
;
struct
lsm_network_audit
net
=
{
0
,};
u32
tsid
=
task_sid
(
task
);
if
(
sksec
->
sid
==
SECINITSID_KERNEL
)
return
0
;
...
...
@@ -4268,7 +4265,8 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
ad
.
u
.
net
=
&
net
;
ad
.
u
.
net
->
sk
=
sk
;
return
avc_has_perm
(
tsid
,
sksec
->
sid
,
sksec
->
sclass
,
perms
,
&
ad
);
return
avc_has_perm
(
current_sid
(),
sksec
->
sid
,
sksec
->
sclass
,
perms
,
&
ad
);
}
static
int
selinux_socket_create
(
int
family
,
int
type
,
...
...
@@ -4330,7 +4328,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
u16
family
;
int
err
;
err
=
sock_has_perm
(
current
,
sk
,
SOCKET__BIND
);
err
=
sock_has_perm
(
sk
,
SOCKET__BIND
);
if
(
err
)
goto
out
;
...
...
@@ -4429,7 +4427,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
struct
sk_security_struct
*
sksec
=
sk
->
sk_security
;
int
err
;
err
=
sock_has_perm
(
current
,
sk
,
SOCKET__CONNECT
);
err
=
sock_has_perm
(
sk
,
SOCKET__CONNECT
);
if
(
err
)
return
err
;
...
...
@@ -4481,7 +4479,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
static
int
selinux_socket_listen
(
struct
socket
*
sock
,
int
backlog
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__LISTEN
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__LISTEN
);
}
static
int
selinux_socket_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
)
...
...
@@ -4492,7 +4490,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
u16
sclass
;
u32
sid
;
err
=
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__ACCEPT
);
err
=
sock_has_perm
(
sock
->
sk
,
SOCKET__ACCEPT
);
if
(
err
)
return
err
;
...
...
@@ -4513,30 +4511,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
static
int
selinux_socket_sendmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__WRITE
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__WRITE
);
}
static
int
selinux_socket_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__READ
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__READ
);
}
static
int
selinux_socket_getsockname
(
struct
socket
*
sock
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__GETATTR
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__GETATTR
);
}
static
int
selinux_socket_getpeername
(
struct
socket
*
sock
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__GETATTR
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__GETATTR
);
}
static
int
selinux_socket_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
)
{
int
err
;
err
=
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__SETOPT
);
err
=
sock_has_perm
(
sock
->
sk
,
SOCKET__SETOPT
);
if
(
err
)
return
err
;
...
...
@@ -4546,12 +4544,12 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname
static
int
selinux_socket_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__GETOPT
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__GETOPT
);
}
static
int
selinux_socket_shutdown
(
struct
socket
*
sock
,
int
how
)
{
return
sock_has_perm
(
current
,
sock
->
sk
,
SOCKET__SHUTDOWN
);
return
sock_has_perm
(
sock
->
sk
,
SOCKET__SHUTDOWN
);
}
static
int
selinux_socket_unix_stream_connect
(
struct
sock
*
sock
,
...
...
@@ -5039,7 +5037,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
goto
out
;
}
err
=
sock_has_perm
(
current
,
sk
,
perm
);
err
=
sock_has_perm
(
sk
,
perm
);
out:
return
err
;
}
...
...
@@ -5370,20 +5368,17 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
return
selinux_nlmsg_perm
(
sk
,
skb
);
}
static
int
ipc_alloc_security
(
struct
task_struct
*
task
,
struct
kern_ipc_perm
*
perm
,
static
int
ipc_alloc_security
(
struct
kern_ipc_perm
*
perm
,
u16
sclass
)
{
struct
ipc_security_struct
*
isec
;
u32
sid
;
isec
=
kzalloc
(
sizeof
(
struct
ipc_security_struct
),
GFP_KERNEL
);
if
(
!
isec
)
return
-
ENOMEM
;
sid
=
task_sid
(
task
);
isec
->
sclass
=
sclass
;
isec
->
sid
=
sid
;
isec
->
sid
=
current_sid
()
;
perm
->
security
=
isec
;
return
0
;
...
...
@@ -5451,7 +5446,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
u32
sid
=
current_sid
();
int
rc
;
rc
=
ipc_alloc_security
(
current
,
&
msq
->
q_perm
,
SECCLASS_MSGQ
);
rc
=
ipc_alloc_security
(
&
msq
->
q_perm
,
SECCLASS_MSGQ
);
if
(
rc
)
return
rc
;
...
...
@@ -5498,7 +5493,8 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
case
IPC_INFO
:
case
MSG_INFO
:
/* No specific object, just general system-wide information. */
return
task_has_system
(
current
,
SYSTEM__IPC_INFO
);
return
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__IPC_INFO
,
NULL
);
case
IPC_STAT
:
case
MSG_STAT
:
perms
=
MSGQ__GETATTR
|
MSGQ__ASSOCIATE
;
...
...
@@ -5592,7 +5588,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
u32
sid
=
current_sid
();
int
rc
;
rc
=
ipc_alloc_security
(
current
,
&
shp
->
shm_perm
,
SECCLASS_SHM
);
rc
=
ipc_alloc_security
(
&
shp
->
shm_perm
,
SECCLASS_SHM
);
if
(
rc
)
return
rc
;
...
...
@@ -5640,7 +5636,8 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
case
IPC_INFO
:
case
SHM_INFO
:
/* No specific object, just general system-wide information. */
return
task_has_system
(
current
,
SYSTEM__IPC_INFO
);
return
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__IPC_INFO
,
NULL
);
case
IPC_STAT
:
case
SHM_STAT
:
perms
=
SHM__GETATTR
|
SHM__ASSOCIATE
;
...
...
@@ -5684,7 +5681,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
u32
sid
=
current_sid
();
int
rc
;
rc
=
ipc_alloc_security
(
current
,
&
sma
->
sem_perm
,
SECCLASS_SEM
);
rc
=
ipc_alloc_security
(
&
sma
->
sem_perm
,
SECCLASS_SEM
);
if
(
rc
)
return
rc
;
...
...
@@ -5732,7 +5729,8 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd)
case
IPC_INFO
:
case
SEM_INFO
:
/* No specific object, just general system-wide information. */
return
task_has_system
(
current
,
SYSTEM__IPC_INFO
);
return
avc_has_perm
(
current_sid
(),
SECINITSID_KERNEL
,
SECCLASS_SYSTEM
,
SYSTEM__IPC_INFO
,
NULL
);
case
GETPID
:
case
GETNCNT
:
case
GETZCNT
:
...
...
@@ -5813,15 +5811,16 @@ static int selinux_getprocattr(struct task_struct *p,
int
error
;
unsigned
len
;
rcu_read_lock
();
__tsec
=
__task_cred
(
p
)
->
security
;
if
(
current
!=
p
)
{
error
=
current_has_perm
(
p
,
PROCESS__GETATTR
);
error
=
avc_has_perm
(
current_sid
(),
__tsec
->
sid
,
SECCLASS_PROCESS
,
PROCESS__GETATTR
,
NULL
);
if
(
error
)
return
error
;
goto
bad
;
}
rcu_read_lock
();
__tsec
=
__task_cred
(
p
)
->
security
;
if
(
!
strcmp
(
name
,
"current"
))
sid
=
__tsec
->
sid
;
else
if
(
!
strcmp
(
name
,
"prev"
))
...
...
@@ -5834,8 +5833,10 @@ static int selinux_getprocattr(struct task_struct *p,
sid
=
__tsec
->
keycreate_sid
;
else
if
(
!
strcmp
(
name
,
"sockcreate"
))
sid
=
__tsec
->
sockcreate_sid
;
else
goto
invalid
;
else
{
error
=
-
EINVAL
;
goto
bad
;
}
rcu_read_unlock
();
if
(
!
sid
)
...
...
@@ -5846,41 +5847,37 @@ static int selinux_getprocattr(struct task_struct *p,
return
error
;
return
len
;
invali
d:
ba
d:
rcu_read_unlock
();
return
-
EINVAL
;
return
error
;
}
static
int
selinux_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
)
static
int
selinux_setprocattr
(
const
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
task_security_struct
*
tsec
;
struct
cred
*
new
;
u32
sid
=
0
,
ptsid
;
u32
mysid
=
current_sid
(),
sid
=
0
,
ptsid
;
int
error
;
char
*
str
=
value
;
if
(
current
!=
p
)
{
/* SELinux only allows a process to change its own
security attributes. */
return
-
EACCES
;
}
/*
* Basic control over ability to set these attributes at all.
* current == p, but we'll pass them separately in case the
* above restriction is ever removed.
*/
if
(
!
strcmp
(
name
,
"exec"
))
error
=
current_has_perm
(
p
,
PROCESS__SETEXEC
);
error
=
avc_has_perm
(
mysid
,
mysid
,
SECCLASS_PROCESS
,
PROCESS__SETEXEC
,
NULL
);
else
if
(
!
strcmp
(
name
,
"fscreate"
))
error
=
current_has_perm
(
p
,
PROCESS__SETFSCREATE
);
error
=
avc_has_perm
(
mysid
,
mysid
,
SECCLASS_PROCESS
,
PROCESS__SETFSCREATE
,
NULL
);
else
if
(
!
strcmp
(
name
,
"keycreate"
))
error
=
current_has_perm
(
p
,
PROCESS__SETKEYCREATE
);
error
=
avc_has_perm
(
mysid
,
mysid
,
SECCLASS_PROCESS
,
PROCESS__SETKEYCREATE
,
NULL
);
else
if
(
!
strcmp
(
name
,
"sockcreate"
))
error
=
current_has_perm
(
p
,
PROCESS__SETSOCKCREATE
);
error
=
avc_has_perm
(
mysid
,
mysid
,
SECCLASS_PROCESS
,
PROCESS__SETSOCKCREATE
,
NULL
);
else
if
(
!
strcmp
(
name
,
"current"
))
error
=
current_has_perm
(
p
,
PROCESS__SETCURRENT
);
error
=
avc_has_perm
(
mysid
,
mysid
,
SECCLASS_PROCESS
,
PROCESS__SETCURRENT
,
NULL
);
else
error
=
-
EINVAL
;
if
(
error
)
...
...
@@ -5934,7 +5931,8 @@ static int selinux_setprocattr(struct task_struct *p,
}
else
if
(
!
strcmp
(
name
,
"fscreate"
))
{
tsec
->
create_sid
=
sid
;
}
else
if
(
!
strcmp
(
name
,
"keycreate"
))
{
error
=
may_create_key
(
sid
,
p
);
error
=
avc_has_perm
(
mysid
,
sid
,
SECCLASS_KEY
,
KEY__CREATE
,
NULL
);
if
(
error
)
goto
abort_change
;
tsec
->
keycreate_sid
=
sid
;
...
...
@@ -5961,7 +5959,7 @@ static int selinux_setprocattr(struct task_struct *p,
/* Check for ptracing, and update the task SID if ok.
Otherwise, leave SID unchanged and fail. */
ptsid
=
ptrace_parent_sid
(
p
);
ptsid
=
ptrace_parent_sid
();
if
(
ptsid
!=
0
)
{
error
=
avc_has_perm
(
ptsid
,
sid
,
SECCLASS_PROCESS
,
PROCESS__PTRACE
,
NULL
);
...
...
@@ -6209,7 +6207,6 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT
(
task_getscheduler
,
selinux_task_getscheduler
),
LSM_HOOK_INIT
(
task_movememory
,
selinux_task_movememory
),
LSM_HOOK_INIT
(
task_kill
,
selinux_task_kill
),
LSM_HOOK_INIT
(
task_wait
,
selinux_task_wait
),
LSM_HOOK_INIT
(
task_to_inode
,
selinux_task_to_inode
),
LSM_HOOK_INIT
(
ipc_permission
,
selinux_ipc_permission
),
...
...
security/selinux/include/classmap.h
View file @
a2a15479
...
...
@@ -171,5 +171,67 @@ struct security_class_mapping secclass_map[] = {
{
COMMON_CAP_PERMS
,
NULL
}
},
{
"cap2_userns"
,
{
COMMON_CAP2_PERMS
,
NULL
}
},
{
"sctp_socket"
,
{
COMMON_SOCK_PERMS
,
"node_bind"
,
NULL
}
},
{
"icmp_socket"
,
{
COMMON_SOCK_PERMS
,
"node_bind"
,
NULL
}
},
{
"ax25_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"ipx_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"netrom_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"atmpvc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"x25_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"rose_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"decnet_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"atmsvc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"rds_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"irda_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"pppox_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"llc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"can_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"tipc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"bluetooth_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"iucv_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"rxrpc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"isdn_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"phonet_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"ieee802154_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"caif_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"alg_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"nfc_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"vsock_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"kcm_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
"qipcrtr_socket"
,
{
COMMON_SOCK_PERMS
,
NULL
}
},
{
NULL
}
};
#if PF_MAX > 43
#error New address family defined, please update secclass_map.
#endif
security/selinux/include/objsec.h
View file @
a2a15479
...
...
@@ -37,6 +37,16 @@ struct task_security_struct {
u32
sockcreate_sid
;
/* fscreate SID */
};
/*
* get the subjective security ID of the current task
*/
static
inline
u32
current_sid
(
void
)
{
const
struct
task_security_struct
*
tsec
=
current_security
();
return
tsec
->
sid
;
}
enum
label_initialized
{
LABEL_INVALID
,
/* invalid or not initialized */
LABEL_INITIALIZED
,
/* initialized */
...
...
security/selinux/include/security.h
View file @
a2a15479
...
...
@@ -69,7 +69,7 @@ extern int selinux_enabled;
enum
{
POLICYDB_CAPABILITY_NETPEER
,
POLICYDB_CAPABILITY_OPENPERM
,
POLICYDB_CAPABILITY_
REDHAT1
,
POLICYDB_CAPABILITY_
EXTSOCKCLASS
,
POLICYDB_CAPABILITY_ALWAYSNETWORK
,
__POLICYDB_CAPABILITY_MAX
};
...
...
@@ -77,6 +77,7 @@ enum {
extern
int
selinux_policycap_netpeer
;
extern
int
selinux_policycap_openperm
;
extern
int
selinux_policycap_extsockclass
;
extern
int
selinux_policycap_alwaysnetwork
;
/*
...
...
security/selinux/selinuxfs.c
View file @
a2a15479
...
...
@@ -45,7 +45,7 @@
static
char
*
policycap_names
[]
=
{
"network_peer_controls"
,
"open_perms"
,
"
redhat1
"
,
"
extended_socket_class
"
,
"always_check_network"
};
...
...
@@ -77,25 +77,6 @@ static char policy_opened;
/* global data for policy capabilities */
static
struct
dentry
*
policycap_dir
;
/* Check whether a task is allowed to use a security operation. */
static
int
task_has_security
(
struct
task_struct
*
tsk
,
u32
perms
)
{
const
struct
task_security_struct
*
tsec
;
u32
sid
=
0
;
rcu_read_lock
();
tsec
=
__task_cred
(
tsk
)
->
security
;
if
(
tsec
)
sid
=
tsec
->
sid
;
rcu_read_unlock
();
if
(
!
tsec
)
return
-
EACCES
;
return
avc_has_perm
(
sid
,
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
perms
,
NULL
);
}
enum
sel_inos
{
SEL_ROOT_INO
=
2
,
SEL_LOAD
,
/* load policy */
...
...
@@ -166,7 +147,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
new_value
=
!!
new_value
;
if
(
new_value
!=
selinux_enforcing
)
{
length
=
task_has_security
(
current
,
SECURITY__SETENFORCE
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__SETENFORCE
,
NULL
);
if
(
length
)
goto
out
;
audit_log
(
current
->
audit_context
,
GFP_KERNEL
,
AUDIT_MAC_STATUS
,
...
...
@@ -368,7 +351,8 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
mutex_lock
(
&
sel_mutex
);
rc
=
task_has_security
(
current
,
SECURITY__READ_POLICY
);
rc
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__READ_POLICY
,
NULL
);
if
(
rc
)
goto
err
;
...
...
@@ -429,7 +413,8 @@ static ssize_t sel_read_policy(struct file *filp, char __user *buf,
mutex_lock
(
&
sel_mutex
);
ret
=
task_has_security
(
current
,
SECURITY__READ_POLICY
);
ret
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__READ_POLICY
,
NULL
);
if
(
ret
)
goto
out
;
...
...
@@ -499,7 +484,8 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
mutex_lock
(
&
sel_mutex
);
length
=
task_has_security
(
current
,
SECURITY__LOAD_POLICY
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__LOAD_POLICY
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -522,20 +508,28 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
goto
out
;
length
=
security_load_policy
(
data
,
count
);
if
(
length
)
if
(
length
)
{
pr_warn_ratelimited
(
"SELinux: failed to load policy
\n
"
);
goto
out
;
}
length
=
sel_make_bools
();
if
(
length
)
if
(
length
)
{
pr_err
(
"SELinux: failed to load policy booleans
\n
"
);
goto
out1
;
}
length
=
sel_make_classes
();
if
(
length
)
if
(
length
)
{
pr_err
(
"SELinux: failed to load policy classes
\n
"
);
goto
out1
;
}
length
=
sel_make_policycap
();
if
(
length
)
if
(
length
)
{
pr_err
(
"SELinux: failed to load policy capabilities
\n
"
);
goto
out1
;
}
length
=
count
;
...
...
@@ -561,7 +555,8 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
u32
sid
,
len
;
ssize_t
length
;
length
=
task_has_security
(
current
,
SECURITY__CHECK_CONTEXT
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__CHECK_CONTEXT
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -604,7 +599,9 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
ssize_t
length
;
unsigned
int
new_value
;
length
=
task_has_security
(
current
,
SECURITY__SETCHECKREQPROT
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__SETCHECKREQPROT
,
NULL
);
if
(
length
)
return
length
;
...
...
@@ -645,7 +642,8 @@ static ssize_t sel_write_validatetrans(struct file *file,
u16
tclass
;
int
rc
;
rc
=
task_has_security
(
current
,
SECURITY__VALIDATE_TRANS
);
rc
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__VALIDATE_TRANS
,
NULL
);
if
(
rc
)
goto
out
;
...
...
@@ -772,7 +770,8 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
struct
av_decision
avd
;
ssize_t
length
;
length
=
task_has_security
(
current
,
SECURITY__COMPUTE_AV
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__COMPUTE_AV
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -822,7 +821,9 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
u32
len
;
int
nargs
;
length
=
task_has_security
(
current
,
SECURITY__COMPUTE_CREATE
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__COMPUTE_CREATE
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -919,7 +920,9 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
char
*
newcon
=
NULL
;
u32
len
;
length
=
task_has_security
(
current
,
SECURITY__COMPUTE_RELABEL
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__COMPUTE_RELABEL
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -975,7 +978,9 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
int
i
,
rc
;
u32
len
,
nsids
;
length
=
task_has_security
(
current
,
SECURITY__COMPUTE_USER
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__COMPUTE_USER
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -1035,7 +1040,9 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
char
*
newcon
=
NULL
;
u32
len
;
length
=
task_has_security
(
current
,
SECURITY__COMPUTE_MEMBER
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__COMPUTE_MEMBER
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -1142,7 +1149,9 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
mutex_lock
(
&
sel_mutex
);
length
=
task_has_security
(
current
,
SECURITY__SETBOOL
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__SETBOOL
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -1198,7 +1207,9 @@ static ssize_t sel_commit_bools_write(struct file *filep,
mutex_lock
(
&
sel_mutex
);
length
=
task_has_security
(
current
,
SECURITY__SETBOOL
);
length
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__SETBOOL
,
NULL
);
if
(
length
)
goto
out
;
...
...
@@ -1299,8 +1310,11 @@ static int sel_make_bools(void)
isec
=
(
struct
inode_security_struct
*
)
inode
->
i_security
;
ret
=
security_genfs_sid
(
"selinuxfs"
,
page
,
SECCLASS_FILE
,
&
sid
);
if
(
ret
)
goto
out
;
if
(
ret
)
{
pr_warn_ratelimited
(
"SELinux: no sid found, defaulting to security isid for %s
\n
"
,
page
);
sid
=
SECINITSID_SECURITY
;
}
isec
->
sid
=
sid
;
isec
->
initialized
=
LABEL_INITIALIZED
;
...
...
@@ -1351,7 +1365,9 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
ssize_t
ret
;
unsigned
int
new_value
;
ret
=
task_has_security
(
current
,
SECURITY__SETSECPARAM
);
ret
=
avc_has_perm
(
current_sid
(),
SECINITSID_SECURITY
,
SECCLASS_SECURITY
,
SECURITY__SETSECPARAM
,
NULL
);
if
(
ret
)
return
ret
;
...
...
security/selinux/ss/services.c
View file @
a2a15479
...
...
@@ -72,6 +72,7 @@
int
selinux_policycap_netpeer
;
int
selinux_policycap_openperm
;
int
selinux_policycap_extsockclass
;
int
selinux_policycap_alwaysnetwork
;
static
DEFINE_RWLOCK
(
policy_rwlock
);
...
...
@@ -1988,6 +1989,8 @@ static void security_load_policycaps(void)
POLICYDB_CAPABILITY_NETPEER
);
selinux_policycap_openperm
=
ebitmap_get_bit
(
&
policydb
.
policycaps
,
POLICYDB_CAPABILITY_OPENPERM
);
selinux_policycap_extsockclass
=
ebitmap_get_bit
(
&
policydb
.
policycaps
,
POLICYDB_CAPABILITY_EXTSOCKCLASS
);
selinux_policycap_alwaysnetwork
=
ebitmap_get_bit
(
&
policydb
.
policycaps
,
POLICYDB_CAPABILITY_ALWAYSNETWORK
);
}
...
...
security/smack/smack_lsm.c
View file @
a2a15479
...
...
@@ -2301,25 +2301,6 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
return
rc
;
}
/**
* smack_task_wait - Smack access check for waiting
* @p: task to wait for
*
* Returns 0
*/
static
int
smack_task_wait
(
struct
task_struct
*
p
)
{
/*
* Allow the operation to succeed.
* Zombies are bad.
* In userless environments (e.g. phones) programs
* get marked with SMACK64EXEC and even if the parent
* and child shouldn't be talking the parent still
* may expect to know when the child exits.
*/
return
0
;
}
/**
* smack_task_to_inode - copy task smack into the inode blob
* @p: task to copy from
...
...
@@ -3680,7 +3661,6 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
/**
* smack_setprocattr - Smack process attribute setting
* @p: the object task
* @name: the name of the attribute in /proc/.../attr
* @value: the value to set
* @size: the size of the value
...
...
@@ -3690,8 +3670,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
*
* Returns the length of the smack label or an error code
*/
static
int
smack_setprocattr
(
struct
task_struct
*
p
,
char
*
name
,
void
*
value
,
size_t
size
)
static
int
smack_setprocattr
(
const
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
task_smack
*
tsp
=
current_security
();
struct
cred
*
new
;
...
...
@@ -3699,13 +3678,6 @@ static int smack_setprocattr(struct task_struct *p, char *name,
struct
smack_known_list_elem
*
sklep
;
int
rc
;
/*
* Changing another process' Smack value is too dangerous
* and supports no sane use case.
*/
if
(
p
!=
current
)
return
-
EPERM
;
if
(
!
smack_privileged
(
CAP_MAC_ADMIN
)
&&
list_empty
(
&
tsp
->
smk_relabel
))
return
-
EPERM
;
...
...
@@ -4727,7 +4699,6 @@ static struct security_hook_list smack_hooks[] = {
LSM_HOOK_INIT
(
task_getscheduler
,
smack_task_getscheduler
),
LSM_HOOK_INIT
(
task_movememory
,
smack_task_movememory
),
LSM_HOOK_INIT
(
task_kill
,
smack_task_kill
),
LSM_HOOK_INIT
(
task_wait
,
smack_task_wait
),
LSM_HOOK_INIT
(
task_to_inode
,
smack_task_to_inode
),
LSM_HOOK_INIT
(
ipc_permission
,
smack_ipc_permission
),
...
...
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