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
nexedi
linux
Commits
37babe4e
Commit
37babe4e
authored
Dec 26, 2015
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream' of
git://git.infradead.org/users/pcmoore/selinux
into next
parents
3cb92fe4
76319946
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
302 additions
and
88 deletions
+302
-88
fs/gfs2/glops.c
fs/gfs2/glops.c
+2
-0
include/linux/audit.h
include/linux/audit.h
+4
-4
include/linux/lsm_hooks.h
include/linux/lsm_hooks.h
+8
-2
include/linux/security.h
include/linux/security.h
+9
-4
kernel/audit.c
kernel/audit.c
+1
-1
kernel/audit.h
kernel/audit.h
+1
-1
kernel/auditsc.c
kernel/auditsc.c
+3
-3
security/security.c
security/security.c
+10
-2
security/selinux/hooks.c
security/selinux/hooks.c
+145
-61
security/selinux/include/classmap.h
security/selinux/include/classmap.h
+1
-1
security/selinux/include/objsec.h
security/selinux/include/objsec.h
+6
-0
security/selinux/include/security.h
security/selinux/include/security.h
+3
-0
security/selinux/selinuxfs.c
security/selinux/selinuxfs.c
+80
-0
security/selinux/ss/services.c
security/selinux/ss/services.c
+27
-7
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+2
-2
No files found.
fs/gfs2/glops.c
View file @
37babe4e
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
#include <linux/gfs2_ondisk.h>
#include <linux/gfs2_ondisk.h>
#include <linux/bio.h>
#include <linux/bio.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl.h>
#include <linux/security.h>
#include "gfs2.h"
#include "gfs2.h"
#include "incore.h"
#include "incore.h"
...
@@ -262,6 +263,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
...
@@ -262,6 +263,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
if
(
ip
)
{
if
(
ip
)
{
set_bit
(
GIF_INVALID
,
&
ip
->
i_flags
);
set_bit
(
GIF_INVALID
,
&
ip
->
i_flags
);
forget_all_cached_acls
(
&
ip
->
i_inode
);
forget_all_cached_acls
(
&
ip
->
i_inode
);
security_inode_invalidate_secctx
(
&
ip
->
i_inode
);
gfs2_dir_hash_inval
(
ip
);
gfs2_dir_hash_inval
(
ip
);
}
}
}
}
...
...
include/linux/audit.h
View file @
37babe4e
...
@@ -137,7 +137,7 @@ extern void __audit_getname(struct filename *name);
...
@@ -137,7 +137,7 @@ extern void __audit_getname(struct filename *name);
extern
void
__audit_inode
(
struct
filename
*
name
,
const
struct
dentry
*
dentry
,
extern
void
__audit_inode
(
struct
filename
*
name
,
const
struct
dentry
*
dentry
,
unsigned
int
flags
);
unsigned
int
flags
);
extern
void
__audit_file
(
const
struct
file
*
);
extern
void
__audit_file
(
const
struct
file
*
);
extern
void
__audit_inode_child
(
const
struct
inode
*
parent
,
extern
void
__audit_inode_child
(
struct
inode
*
parent
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
unsigned
char
type
);
const
unsigned
char
type
);
extern
void
__audit_seccomp
(
unsigned
long
syscall
,
long
signr
,
int
code
);
extern
void
__audit_seccomp
(
unsigned
long
syscall
,
long
signr
,
int
code
);
...
@@ -202,7 +202,7 @@ static inline void audit_inode_parent_hidden(struct filename *name,
...
@@ -202,7 +202,7 @@ static inline void audit_inode_parent_hidden(struct filename *name,
__audit_inode
(
name
,
dentry
,
__audit_inode
(
name
,
dentry
,
AUDIT_INODE_PARENT
|
AUDIT_INODE_HIDDEN
);
AUDIT_INODE_PARENT
|
AUDIT_INODE_HIDDEN
);
}
}
static
inline
void
audit_inode_child
(
const
struct
inode
*
parent
,
static
inline
void
audit_inode_child
(
struct
inode
*
parent
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
unsigned
char
type
)
{
const
unsigned
char
type
)
{
if
(
unlikely
(
!
audit_dummy_context
()))
if
(
unlikely
(
!
audit_dummy_context
()))
...
@@ -359,7 +359,7 @@ static inline void __audit_inode(struct filename *name,
...
@@ -359,7 +359,7 @@ static inline void __audit_inode(struct filename *name,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
unsigned
int
flags
)
unsigned
int
flags
)
{
}
{
}
static
inline
void
__audit_inode_child
(
const
struct
inode
*
parent
,
static
inline
void
__audit_inode_child
(
struct
inode
*
parent
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
unsigned
char
type
)
const
unsigned
char
type
)
{
}
{
}
...
@@ -373,7 +373,7 @@ static inline void audit_file(struct file *file)
...
@@ -373,7 +373,7 @@ static inline void audit_file(struct file *file)
static
inline
void
audit_inode_parent_hidden
(
struct
filename
*
name
,
static
inline
void
audit_inode_parent_hidden
(
struct
filename
*
name
,
const
struct
dentry
*
dentry
)
const
struct
dentry
*
dentry
)
{
}
{
}
static
inline
void
audit_inode_child
(
const
struct
inode
*
parent
,
static
inline
void
audit_inode_child
(
struct
inode
*
parent
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
unsigned
char
type
)
const
unsigned
char
type
)
{
}
{
}
...
...
include/linux/lsm_hooks.h
View file @
37babe4e
...
@@ -1261,6 +1261,10 @@
...
@@ -1261,6 +1261,10 @@
* audit_rule_init.
* audit_rule_init.
* @rule contains the allocated rule
* @rule contains the allocated rule
*
*
* @inode_invalidate_secctx:
* Notify the security module that it must revalidate the security context
* of an inode.
*
* @inode_notifysecctx:
* @inode_notifysecctx:
* Notify the security module of what the security context of an inode
* Notify the security module of what the security context of an inode
* should be. Initializes the incore security context managed by the
* should be. Initializes the incore security context managed by the
...
@@ -1413,14 +1417,14 @@ union security_list_options {
...
@@ -1413,14 +1417,14 @@ union security_list_options {
int
(
*
inode_removexattr
)(
struct
dentry
*
dentry
,
const
char
*
name
);
int
(
*
inode_removexattr
)(
struct
dentry
*
dentry
,
const
char
*
name
);
int
(
*
inode_need_killpriv
)(
struct
dentry
*
dentry
);
int
(
*
inode_need_killpriv
)(
struct
dentry
*
dentry
);
int
(
*
inode_killpriv
)(
struct
dentry
*
dentry
);
int
(
*
inode_killpriv
)(
struct
dentry
*
dentry
);
int
(
*
inode_getsecurity
)(
const
struct
inode
*
inode
,
const
char
*
name
,
int
(
*
inode_getsecurity
)(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
);
void
**
buffer
,
bool
alloc
);
int
(
*
inode_setsecurity
)(
struct
inode
*
inode
,
const
char
*
name
,
int
(
*
inode_setsecurity
)(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
const
void
*
value
,
size_t
size
,
int
flags
);
int
flags
);
int
(
*
inode_listsecurity
)(
struct
inode
*
inode
,
char
*
buffer
,
int
(
*
inode_listsecurity
)(
struct
inode
*
inode
,
char
*
buffer
,
size_t
buffer_size
);
size_t
buffer_size
);
void
(
*
inode_getsecid
)(
const
struct
inode
*
inode
,
u32
*
secid
);
void
(
*
inode_getsecid
)(
struct
inode
*
inode
,
u32
*
secid
);
int
(
*
file_permission
)(
struct
file
*
file
,
int
mask
);
int
(
*
file_permission
)(
struct
file
*
file
,
int
mask
);
int
(
*
file_alloc_security
)(
struct
file
*
file
);
int
(
*
file_alloc_security
)(
struct
file
*
file
);
...
@@ -1516,6 +1520,7 @@ union security_list_options {
...
@@ -1516,6 +1520,7 @@ union security_list_options {
int
(
*
secctx_to_secid
)(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
);
int
(
*
secctx_to_secid
)(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
);
void
(
*
release_secctx
)(
char
*
secdata
,
u32
seclen
);
void
(
*
release_secctx
)(
char
*
secdata
,
u32
seclen
);
void
(
*
inode_invalidate_secctx
)(
struct
inode
*
inode
);
int
(
*
inode_notifysecctx
)(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
);
int
(
*
inode_notifysecctx
)(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
);
int
(
*
inode_setsecctx
)(
struct
dentry
*
dentry
,
void
*
ctx
,
u32
ctxlen
);
int
(
*
inode_setsecctx
)(
struct
dentry
*
dentry
,
void
*
ctx
,
u32
ctxlen
);
int
(
*
inode_getsecctx
)(
struct
inode
*
inode
,
void
**
ctx
,
u32
*
ctxlen
);
int
(
*
inode_getsecctx
)(
struct
inode
*
inode
,
void
**
ctx
,
u32
*
ctxlen
);
...
@@ -1757,6 +1762,7 @@ struct security_hook_heads {
...
@@ -1757,6 +1762,7 @@ struct security_hook_heads {
struct
list_head
secid_to_secctx
;
struct
list_head
secid_to_secctx
;
struct
list_head
secctx_to_secid
;
struct
list_head
secctx_to_secid
;
struct
list_head
release_secctx
;
struct
list_head
release_secctx
;
struct
list_head
inode_invalidate_secctx
;
struct
list_head
inode_notifysecctx
;
struct
list_head
inode_notifysecctx
;
struct
list_head
inode_setsecctx
;
struct
list_head
inode_setsecctx
;
struct
list_head
inode_getsecctx
;
struct
list_head
inode_getsecctx
;
...
...
include/linux/security.h
View file @
37babe4e
...
@@ -270,10 +270,10 @@ int security_inode_listxattr(struct dentry *dentry);
...
@@ -270,10 +270,10 @@ int security_inode_listxattr(struct dentry *dentry);
int
security_inode_removexattr
(
struct
dentry
*
dentry
,
const
char
*
name
);
int
security_inode_removexattr
(
struct
dentry
*
dentry
,
const
char
*
name
);
int
security_inode_need_killpriv
(
struct
dentry
*
dentry
);
int
security_inode_need_killpriv
(
struct
dentry
*
dentry
);
int
security_inode_killpriv
(
struct
dentry
*
dentry
);
int
security_inode_killpriv
(
struct
dentry
*
dentry
);
int
security_inode_getsecurity
(
const
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
);
int
security_inode_getsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
);
int
security_inode_setsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
);
int
security_inode_setsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
);
int
security_inode_listsecurity
(
struct
inode
*
inode
,
char
*
buffer
,
size_t
buffer_size
);
int
security_inode_listsecurity
(
struct
inode
*
inode
,
char
*
buffer
,
size_t
buffer_size
);
void
security_inode_getsecid
(
const
struct
inode
*
inode
,
u32
*
secid
);
void
security_inode_getsecid
(
struct
inode
*
inode
,
u32
*
secid
);
int
security_file_permission
(
struct
file
*
file
,
int
mask
);
int
security_file_permission
(
struct
file
*
file
,
int
mask
);
int
security_file_alloc
(
struct
file
*
file
);
int
security_file_alloc
(
struct
file
*
file
);
void
security_file_free
(
struct
file
*
file
);
void
security_file_free
(
struct
file
*
file
);
...
@@ -353,6 +353,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
...
@@ -353,6 +353,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
int
security_secctx_to_secid
(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
);
int
security_secctx_to_secid
(
const
char
*
secdata
,
u32
seclen
,
u32
*
secid
);
void
security_release_secctx
(
char
*
secdata
,
u32
seclen
);
void
security_release_secctx
(
char
*
secdata
,
u32
seclen
);
void
security_inode_invalidate_secctx
(
struct
inode
*
inode
);
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
);
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
);
int
security_inode_setsecctx
(
struct
dentry
*
dentry
,
void
*
ctx
,
u32
ctxlen
);
int
security_inode_setsecctx
(
struct
dentry
*
dentry
,
void
*
ctx
,
u32
ctxlen
);
int
security_inode_getsecctx
(
struct
inode
*
inode
,
void
**
ctx
,
u32
*
ctxlen
);
int
security_inode_getsecctx
(
struct
inode
*
inode
,
void
**
ctx
,
u32
*
ctxlen
);
...
@@ -719,7 +720,7 @@ static inline int security_inode_killpriv(struct dentry *dentry)
...
@@ -719,7 +720,7 @@ static inline int security_inode_killpriv(struct dentry *dentry)
return
cap_inode_killpriv
(
dentry
);
return
cap_inode_killpriv
(
dentry
);
}
}
static
inline
int
security_inode_getsecurity
(
const
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
static
inline
int
security_inode_getsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
{
{
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
...
@@ -734,7 +735,7 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer,
...
@@ -734,7 +735,7 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer,
return
0
;
return
0
;
}
}
static
inline
void
security_inode_getsecid
(
const
struct
inode
*
inode
,
u32
*
secid
)
static
inline
void
security_inode_getsecid
(
struct
inode
*
inode
,
u32
*
secid
)
{
{
*
secid
=
0
;
*
secid
=
0
;
}
}
...
@@ -1093,6 +1094,10 @@ static inline void security_release_secctx(char *secdata, u32 seclen)
...
@@ -1093,6 +1094,10 @@ static inline void security_release_secctx(char *secdata, u32 seclen)
{
{
}
}
static
inline
void
security_inode_invalidate_secctx
(
struct
inode
*
inode
)
{
}
static
inline
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
)
static
inline
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
)
{
{
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
...
...
kernel/audit.c
View file @
37babe4e
...
@@ -1722,7 +1722,7 @@ static inline int audit_copy_fcaps(struct audit_names *name,
...
@@ -1722,7 +1722,7 @@ static inline int audit_copy_fcaps(struct audit_names *name,
/* Copy inode data into an audit_names. */
/* Copy inode data into an audit_names. */
void
audit_copy_inode
(
struct
audit_names
*
name
,
const
struct
dentry
*
dentry
,
void
audit_copy_inode
(
struct
audit_names
*
name
,
const
struct
dentry
*
dentry
,
const
struct
inode
*
inode
)
struct
inode
*
inode
)
{
{
name
->
ino
=
inode
->
i_ino
;
name
->
ino
=
inode
->
i_ino
;
name
->
dev
=
inode
->
i_sb
->
s_dev
;
name
->
dev
=
inode
->
i_sb
->
s_dev
;
...
...
kernel/audit.h
View file @
37babe4e
...
@@ -207,7 +207,7 @@ extern u32 audit_ever_enabled;
...
@@ -207,7 +207,7 @@ extern u32 audit_ever_enabled;
extern
void
audit_copy_inode
(
struct
audit_names
*
name
,
extern
void
audit_copy_inode
(
struct
audit_names
*
name
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
struct
inode
*
inode
);
struct
inode
*
inode
);
extern
void
audit_log_cap
(
struct
audit_buffer
*
ab
,
char
*
prefix
,
extern
void
audit_log_cap
(
struct
audit_buffer
*
ab
,
char
*
prefix
,
kernel_cap_t
*
cap
);
kernel_cap_t
*
cap
);
extern
void
audit_log_name
(
struct
audit_context
*
context
,
extern
void
audit_log_name
(
struct
audit_context
*
context
,
...
...
kernel/auditsc.c
View file @
37babe4e
...
@@ -1754,7 +1754,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
...
@@ -1754,7 +1754,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned
int
flags
)
unsigned
int
flags
)
{
{
struct
audit_context
*
context
=
current
->
audit_context
;
struct
audit_context
*
context
=
current
->
audit_context
;
const
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
audit_names
*
n
;
struct
audit_names
*
n
;
bool
parent
=
flags
&
AUDIT_INODE_PARENT
;
bool
parent
=
flags
&
AUDIT_INODE_PARENT
;
...
@@ -1848,12 +1848,12 @@ void __audit_file(const struct file *file)
...
@@ -1848,12 +1848,12 @@ void __audit_file(const struct file *file)
* must be hooked prior, in order to capture the target inode during
* must be hooked prior, in order to capture the target inode during
* unsuccessful attempts.
* unsuccessful attempts.
*/
*/
void
__audit_inode_child
(
const
struct
inode
*
parent
,
void
__audit_inode_child
(
struct
inode
*
parent
,
const
struct
dentry
*
dentry
,
const
struct
dentry
*
dentry
,
const
unsigned
char
type
)
const
unsigned
char
type
)
{
{
struct
audit_context
*
context
=
current
->
audit_context
;
struct
audit_context
*
context
=
current
->
audit_context
;
const
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
const
char
*
dname
=
dentry
->
d_name
.
name
;
const
char
*
dname
=
dentry
->
d_name
.
name
;
struct
audit_names
*
n
,
*
found_parent
=
NULL
,
*
found_child
=
NULL
;
struct
audit_names
*
n
,
*
found_parent
=
NULL
,
*
found_child
=
NULL
;
...
...
security/security.c
View file @
37babe4e
...
@@ -697,7 +697,7 @@ int security_inode_killpriv(struct dentry *dentry)
...
@@ -697,7 +697,7 @@ int security_inode_killpriv(struct dentry *dentry)
return
call_int_hook
(
inode_killpriv
,
0
,
dentry
);
return
call_int_hook
(
inode_killpriv
,
0
,
dentry
);
}
}
int
security_inode_getsecurity
(
const
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
int
security_inode_getsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
{
{
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
...
@@ -721,7 +721,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
...
@@ -721,7 +721,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
}
}
EXPORT_SYMBOL
(
security_inode_listsecurity
);
EXPORT_SYMBOL
(
security_inode_listsecurity
);
void
security_inode_getsecid
(
const
struct
inode
*
inode
,
u32
*
secid
)
void
security_inode_getsecid
(
struct
inode
*
inode
,
u32
*
secid
)
{
{
call_void_hook
(
inode_getsecid
,
inode
,
secid
);
call_void_hook
(
inode_getsecid
,
inode
,
secid
);
}
}
...
@@ -1161,6 +1161,12 @@ void security_release_secctx(char *secdata, u32 seclen)
...
@@ -1161,6 +1161,12 @@ void security_release_secctx(char *secdata, u32 seclen)
}
}
EXPORT_SYMBOL
(
security_release_secctx
);
EXPORT_SYMBOL
(
security_release_secctx
);
void
security_inode_invalidate_secctx
(
struct
inode
*
inode
)
{
call_void_hook
(
inode_invalidate_secctx
,
inode
);
}
EXPORT_SYMBOL
(
security_inode_invalidate_secctx
);
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
)
int
security_inode_notifysecctx
(
struct
inode
*
inode
,
void
*
ctx
,
u32
ctxlen
)
{
{
return
call_int_hook
(
inode_notifysecctx
,
0
,
inode
,
ctx
,
ctxlen
);
return
call_int_hook
(
inode_notifysecctx
,
0
,
inode
,
ctx
,
ctxlen
);
...
@@ -1763,6 +1769,8 @@ struct security_hook_heads security_hook_heads = {
...
@@ -1763,6 +1769,8 @@ struct security_hook_heads security_hook_heads = {
LIST_HEAD_INIT
(
security_hook_heads
.
secctx_to_secid
),
LIST_HEAD_INIT
(
security_hook_heads
.
secctx_to_secid
),
.
release_secctx
=
.
release_secctx
=
LIST_HEAD_INIT
(
security_hook_heads
.
release_secctx
),
LIST_HEAD_INIT
(
security_hook_heads
.
release_secctx
),
.
inode_invalidate_secctx
=
LIST_HEAD_INIT
(
security_hook_heads
.
inode_invalidate_secctx
),
.
inode_notifysecctx
=
.
inode_notifysecctx
=
LIST_HEAD_INIT
(
security_hook_heads
.
inode_notifysecctx
),
LIST_HEAD_INIT
(
security_hook_heads
.
inode_notifysecctx
),
.
inode_setsecctx
=
.
inode_setsecctx
=
...
...
security/selinux/hooks.c
View file @
37babe4e
...
@@ -242,6 +242,77 @@ static int inode_alloc_security(struct inode *inode)
...
@@ -242,6 +242,77 @@ static int inode_alloc_security(struct inode *inode)
return
0
;
return
0
;
}
}
static
int
inode_doinit_with_dentry
(
struct
inode
*
inode
,
struct
dentry
*
opt_dentry
);
/*
* Try reloading inode security labels that have been marked as invalid. The
* @may_sleep parameter indicates when sleeping and thus reloading labels is
* allowed; when set to false, returns ERR_PTR(-ECHILD) when the label is
* invalid. The @opt_dentry parameter should be set to a dentry of the inode;
* when no dentry is available, set it to NULL instead.
*/
static
int
__inode_security_revalidate
(
struct
inode
*
inode
,
struct
dentry
*
opt_dentry
,
bool
may_sleep
)
{
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
might_sleep_if
(
may_sleep
);
if
(
isec
->
initialized
==
LABEL_INVALID
)
{
if
(
!
may_sleep
)
return
-
ECHILD
;
/*
* Try reloading the inode security label. This will fail if
* @opt_dentry is NULL and no dentry for this inode can be
* found; in that case, continue using the old label.
*/
inode_doinit_with_dentry
(
inode
,
opt_dentry
);
}
return
0
;
}
static
void
inode_security_revalidate
(
struct
inode
*
inode
)
{
__inode_security_revalidate
(
inode
,
NULL
,
true
);
}
static
struct
inode_security_struct
*
inode_security_novalidate
(
struct
inode
*
inode
)
{
return
inode
->
i_security
;
}
static
struct
inode_security_struct
*
inode_security_rcu
(
struct
inode
*
inode
,
bool
rcu
)
{
int
error
;
error
=
__inode_security_revalidate
(
inode
,
NULL
,
!
rcu
);
if
(
error
)
return
ERR_PTR
(
error
);
return
inode
->
i_security
;
}
/*
* Get the security label of an inode.
*/
static
struct
inode_security_struct
*
inode_security
(
struct
inode
*
inode
)
{
__inode_security_revalidate
(
inode
,
NULL
,
true
);
return
inode
->
i_security
;
}
/*
* Get the security label of a dentry's backing inode.
*/
static
struct
inode_security_struct
*
backing_inode_security
(
struct
dentry
*
dentry
)
{
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
__inode_security_revalidate
(
inode
,
dentry
,
true
);
return
inode
->
i_security
;
}
static
void
inode_free_rcu
(
struct
rcu_head
*
head
)
static
void
inode_free_rcu
(
struct
rcu_head
*
head
)
{
{
struct
inode_security_struct
*
isec
;
struct
inode_security_struct
*
isec
;
...
@@ -345,8 +416,6 @@ static const char *labeling_behaviors[7] = {
...
@@ -345,8 +416,6 @@ static const char *labeling_behaviors[7] = {
"uses native labeling"
,
"uses native labeling"
,
};
};
static
int
inode_doinit_with_dentry
(
struct
inode
*
inode
,
struct
dentry
*
opt_dentry
);
static
inline
int
inode_doinit
(
struct
inode
*
inode
)
static
inline
int
inode_doinit
(
struct
inode
*
inode
)
{
{
return
inode_doinit_with_dentry
(
inode
,
NULL
);
return
inode_doinit_with_dentry
(
inode
,
NULL
);
...
@@ -565,8 +634,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
...
@@ -565,8 +634,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
opts
->
mnt_opts_flags
[
i
++
]
=
DEFCONTEXT_MNT
;
opts
->
mnt_opts_flags
[
i
++
]
=
DEFCONTEXT_MNT
;
}
}
if
(
sbsec
->
flags
&
ROOTCONTEXT_MNT
)
{
if
(
sbsec
->
flags
&
ROOTCONTEXT_MNT
)
{
struct
inode
*
root
=
d_backing_inode
(
sbsec
->
sb
->
s_root
)
;
struct
dentry
*
root
=
sbsec
->
sb
->
s_root
;
struct
inode_security_struct
*
isec
=
root
->
i_security
;
struct
inode_security_struct
*
isec
=
backing_inode_security
(
root
)
;
rc
=
security_sid_to_context
(
isec
->
sid
,
&
context
,
&
len
);
rc
=
security_sid_to_context
(
isec
->
sid
,
&
context
,
&
len
);
if
(
rc
)
if
(
rc
)
...
@@ -621,8 +690,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
...
@@ -621,8 +690,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
int
rc
=
0
,
i
;
int
rc
=
0
,
i
;
struct
superblock_security_struct
*
sbsec
=
sb
->
s_security
;
struct
superblock_security_struct
*
sbsec
=
sb
->
s_security
;
const
char
*
name
=
sb
->
s_type
->
name
;
const
char
*
name
=
sb
->
s_type
->
name
;
struct
inode
*
inode
=
d_backing_inode
(
sbsec
->
sb
->
s_root
)
;
struct
dentry
*
root
=
sbsec
->
sb
->
s_root
;
struct
inode_security_struct
*
root_isec
=
inode
->
i_security
;
struct
inode_security_struct
*
root_isec
=
backing_inode_security
(
root
)
;
u32
fscontext_sid
=
0
,
context_sid
=
0
,
rootcontext_sid
=
0
;
u32
fscontext_sid
=
0
,
context_sid
=
0
,
rootcontext_sid
=
0
;
u32
defcontext_sid
=
0
;
u32
defcontext_sid
=
0
;
char
**
mount_options
=
opts
->
mnt_opts
;
char
**
mount_options
=
opts
->
mnt_opts
;
...
@@ -802,7 +871,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
...
@@ -802,7 +871,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
goto
out
;
goto
out
;
root_isec
->
sid
=
rootcontext_sid
;
root_isec
->
sid
=
rootcontext_sid
;
root_isec
->
initialized
=
1
;
root_isec
->
initialized
=
LABEL_INITIALIZED
;
}
}
if
(
defcontext_sid
)
{
if
(
defcontext_sid
)
{
...
@@ -852,8 +921,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb,
...
@@ -852,8 +921,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb,
if
((
oldflags
&
DEFCONTEXT_MNT
)
&&
old
->
def_sid
!=
new
->
def_sid
)
if
((
oldflags
&
DEFCONTEXT_MNT
)
&&
old
->
def_sid
!=
new
->
def_sid
)
goto
mismatch
;
goto
mismatch
;
if
(
oldflags
&
ROOTCONTEXT_MNT
)
{
if
(
oldflags
&
ROOTCONTEXT_MNT
)
{
struct
inode_security_struct
*
oldroot
=
d_backing_inode
(
oldsb
->
s_root
)
->
i_security
;
struct
inode_security_struct
*
oldroot
=
backing_inode_security
(
oldsb
->
s_root
)
;
struct
inode_security_struct
*
newroot
=
d_backing_inode
(
newsb
->
s_root
)
->
i_security
;
struct
inode_security_struct
*
newroot
=
backing_inode_security
(
newsb
->
s_root
)
;
if
(
oldroot
->
sid
!=
newroot
->
sid
)
if
(
oldroot
->
sid
!=
newroot
->
sid
)
goto
mismatch
;
goto
mismatch
;
}
}
...
@@ -903,17 +972,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
...
@@ -903,17 +972,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
if
(
!
set_fscontext
)
if
(
!
set_fscontext
)
newsbsec
->
sid
=
sid
;
newsbsec
->
sid
=
sid
;
if
(
!
set_rootcontext
)
{
if
(
!
set_rootcontext
)
{
struct
inode
*
newinode
=
d_backing_inode
(
newsb
->
s_root
);
struct
inode_security_struct
*
newisec
=
backing_inode_security
(
newsb
->
s_root
);
struct
inode_security_struct
*
newisec
=
newinode
->
i_security
;
newisec
->
sid
=
sid
;
newisec
->
sid
=
sid
;
}
}
newsbsec
->
mntpoint_sid
=
sid
;
newsbsec
->
mntpoint_sid
=
sid
;
}
}
if
(
set_rootcontext
)
{
if
(
set_rootcontext
)
{
const
struct
inode
*
oldinode
=
d_backing_inode
(
oldsb
->
s_root
);
const
struct
inode_security_struct
*
oldisec
=
backing_inode_security
(
oldsb
->
s_root
);
const
struct
inode_security_struct
*
oldisec
=
oldinode
->
i_security
;
struct
inode_security_struct
*
newisec
=
backing_inode_security
(
newsb
->
s_root
);
struct
inode
*
newinode
=
d_backing_inode
(
newsb
->
s_root
);
struct
inode_security_struct
*
newisec
=
newinode
->
i_security
;
newisec
->
sid
=
oldisec
->
sid
;
newisec
->
sid
=
oldisec
->
sid
;
}
}
...
@@ -1293,11 +1359,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
...
@@ -1293,11 +1359,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
unsigned
len
=
0
;
unsigned
len
=
0
;
int
rc
=
0
;
int
rc
=
0
;
if
(
isec
->
initialized
)
if
(
isec
->
initialized
==
LABEL_INITIALIZED
)
goto
out
;
goto
out
;
mutex_lock
(
&
isec
->
lock
);
mutex_lock
(
&
isec
->
lock
);
if
(
isec
->
initialized
)
if
(
isec
->
initialized
==
LABEL_INITIALIZED
)
goto
out_unlock
;
goto
out_unlock
;
sbsec
=
inode
->
i_sb
->
s_security
;
sbsec
=
inode
->
i_sb
->
s_security
;
...
@@ -1469,7 +1535,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
...
@@ -1469,7 +1535,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
break
;
break
;
}
}
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
out_unlock:
out_unlock:
mutex_unlock
(
&
isec
->
lock
);
mutex_unlock
(
&
isec
->
lock
);
...
@@ -1640,6 +1706,7 @@ static inline int dentry_has_perm(const struct cred *cred,
...
@@ -1640,6 +1706,7 @@ static inline int dentry_has_perm(const struct cred *cred,
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
u
.
dentry
=
dentry
;
ad
.
u
.
dentry
=
dentry
;
__inode_security_revalidate
(
inode
,
dentry
,
true
);
return
inode_has_perm
(
cred
,
inode
,
av
,
&
ad
);
return
inode_has_perm
(
cred
,
inode
,
av
,
&
ad
);
}
}
...
@@ -1655,6 +1722,7 @@ static inline int path_has_perm(const struct cred *cred,
...
@@ -1655,6 +1722,7 @@ static inline int path_has_perm(const struct cred *cred,
ad
.
type
=
LSM_AUDIT_DATA_PATH
;
ad
.
type
=
LSM_AUDIT_DATA_PATH
;
ad
.
u
.
path
=
*
path
;
ad
.
u
.
path
=
*
path
;
__inode_security_revalidate
(
inode
,
path
->
dentry
,
true
);
return
inode_has_perm
(
cred
,
inode
,
av
,
&
ad
);
return
inode_has_perm
(
cred
,
inode
,
av
,
&
ad
);
}
}
...
@@ -1712,13 +1780,13 @@ static int file_has_perm(const struct cred *cred,
...
@@ -1712,13 +1780,13 @@ static int file_has_perm(const struct cred *cred,
/*
/*
* Determine the label for an inode that might be unioned.
* Determine the label for an inode that might be unioned.
*/
*/
static
int
selinux_determine_inode_label
(
const
struct
inode
*
dir
,
static
int
selinux_determine_inode_label
(
struct
inode
*
dir
,
const
struct
qstr
*
name
,
const
struct
qstr
*
name
,
u16
tclass
,
u16
tclass
,
u32
*
_new_isid
)
u32
*
_new_isid
)
{
{
const
struct
superblock_security_struct
*
sbsec
=
dir
->
i_sb
->
s_security
;
const
struct
superblock_security_struct
*
sbsec
=
dir
->
i_sb
->
s_security
;
const
struct
inode_security_struct
*
dsec
=
dir
->
i_security
;
const
struct
inode_security_struct
*
dsec
=
inode_security
(
dir
)
;
const
struct
task_security_struct
*
tsec
=
current_security
();
const
struct
task_security_struct
*
tsec
=
current_security
();
if
((
sbsec
->
flags
&
SE_SBINITIALIZED
)
&&
if
((
sbsec
->
flags
&
SE_SBINITIALIZED
)
&&
...
@@ -1747,7 +1815,7 @@ static int may_create(struct inode *dir,
...
@@ -1747,7 +1815,7 @@ static int may_create(struct inode *dir,
struct
common_audit_data
ad
;
struct
common_audit_data
ad
;
int
rc
;
int
rc
;
dsec
=
dir
->
i_security
;
dsec
=
inode_security
(
dir
)
;
sbsec
=
dir
->
i_sb
->
s_security
;
sbsec
=
dir
->
i_sb
->
s_security
;
sid
=
tsec
->
sid
;
sid
=
tsec
->
sid
;
...
@@ -1800,8 +1868,8 @@ static int may_link(struct inode *dir,
...
@@ -1800,8 +1868,8 @@ static int may_link(struct inode *dir,
u32
av
;
u32
av
;
int
rc
;
int
rc
;
dsec
=
dir
->
i_security
;
dsec
=
inode_security
(
dir
)
;
isec
=
d_backing_inode
(
dentry
)
->
i_security
;
isec
=
backing_inode_security
(
dentry
)
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
u
.
dentry
=
dentry
;
ad
.
u
.
dentry
=
dentry
;
...
@@ -1844,10 +1912,10 @@ static inline int may_rename(struct inode *old_dir,
...
@@ -1844,10 +1912,10 @@ static inline int may_rename(struct inode *old_dir,
int
old_is_dir
,
new_is_dir
;
int
old_is_dir
,
new_is_dir
;
int
rc
;
int
rc
;
old_dsec
=
old_dir
->
i_security
;
old_dsec
=
inode_security
(
old_dir
)
;
old_isec
=
d_backing_inode
(
old_dentry
)
->
i_security
;
old_isec
=
backing_inode_security
(
old_dentry
)
;
old_is_dir
=
d_is_dir
(
old_dentry
);
old_is_dir
=
d_is_dir
(
old_dentry
);
new_dsec
=
new_dir
->
i_security
;
new_dsec
=
inode_security
(
new_dir
)
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
...
@@ -1875,7 +1943,7 @@ static inline int may_rename(struct inode *old_dir,
...
@@ -1875,7 +1943,7 @@ static inline int may_rename(struct inode *old_dir,
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
if
(
d_is_positive
(
new_dentry
))
{
if
(
d_is_positive
(
new_dentry
))
{
new_isec
=
d_backing_inode
(
new_dentry
)
->
i_security
;
new_isec
=
backing_inode_security
(
new_dentry
)
;
new_is_dir
=
d_is_dir
(
new_dentry
);
new_is_dir
=
d_is_dir
(
new_dentry
);
rc
=
avc_has_perm
(
sid
,
new_isec
->
sid
,
rc
=
avc_has_perm
(
sid
,
new_isec
->
sid
,
new_isec
->
sclass
,
new_isec
->
sclass
,
...
@@ -2011,8 +2079,8 @@ static int selinux_binder_transfer_file(struct task_struct *from,
...
@@ -2011,8 +2079,8 @@ static int selinux_binder_transfer_file(struct task_struct *from,
{
{
u32
sid
=
task_sid
(
to
);
u32
sid
=
task_sid
(
to
);
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
inode
*
inode
=
d_backing_inode
(
file
->
f_path
.
dentry
)
;
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
backing_inode_security
(
dentry
)
;
struct
common_audit_data
ad
;
struct
common_audit_data
ad
;
int
rc
;
int
rc
;
...
@@ -2028,7 +2096,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
...
@@ -2028,7 +2096,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
return
rc
;
return
rc
;
}
}
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
if
(
unlikely
(
IS_PRIVATE
(
d_backing_inode
(
dentry
)
)))
return
0
;
return
0
;
return
avc_has_perm
(
sid
,
isec
->
sid
,
isec
->
sclass
,
file_to_av
(
file
),
return
avc_has_perm
(
sid
,
isec
->
sid
,
isec
->
sclass
,
file_to_av
(
file
),
...
@@ -2217,7 +2285,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
...
@@ -2217,7 +2285,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
old_tsec
=
current_security
();
old_tsec
=
current_security
();
new_tsec
=
bprm
->
cred
->
security
;
new_tsec
=
bprm
->
cred
->
security
;
isec
=
inode
->
i_security
;
isec
=
inode
_security
(
inode
)
;
/* Default to the current task SID. */
/* Default to the current task SID. */
new_tsec
->
sid
=
old_tsec
->
sid
;
new_tsec
->
sid
=
old_tsec
->
sid
;
...
@@ -2639,7 +2707,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
...
@@ -2639,7 +2707,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
break
;
break
;
case
ROOTCONTEXT_MNT
:
{
case
ROOTCONTEXT_MNT
:
{
struct
inode_security_struct
*
root_isec
;
struct
inode_security_struct
*
root_isec
;
root_isec
=
d_backing_inode
(
sb
->
s_root
)
->
i_security
;
root_isec
=
backing_inode_security
(
sb
->
s_root
)
;
if
(
bad_option
(
sbsec
,
ROOTCONTEXT_MNT
,
root_isec
->
sid
,
sid
))
if
(
bad_option
(
sbsec
,
ROOTCONTEXT_MNT
,
root_isec
->
sid
,
sid
))
goto
out_bad_option
;
goto
out_bad_option
;
...
@@ -2753,13 +2821,11 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
...
@@ -2753,13 +2821,11 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
void
**
value
,
size_t
*
len
)
void
**
value
,
size_t
*
len
)
{
{
const
struct
task_security_struct
*
tsec
=
current_security
();
const
struct
task_security_struct
*
tsec
=
current_security
();
struct
inode_security_struct
*
dsec
;
struct
superblock_security_struct
*
sbsec
;
struct
superblock_security_struct
*
sbsec
;
u32
sid
,
newsid
,
clen
;
u32
sid
,
newsid
,
clen
;
int
rc
;
int
rc
;
char
*
context
;
char
*
context
;
dsec
=
dir
->
i_security
;
sbsec
=
dir
->
i_sb
->
s_security
;
sbsec
=
dir
->
i_sb
->
s_security
;
sid
=
tsec
->
sid
;
sid
=
tsec
->
sid
;
...
@@ -2777,7 +2843,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
...
@@ -2777,7 +2843,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sid
=
newsid
;
isec
->
sid
=
newsid
;
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
}
}
if
(
!
ss_initialized
||
!
(
sbsec
->
flags
&
SBLABEL_MNT
))
if
(
!
ss_initialized
||
!
(
sbsec
->
flags
&
SBLABEL_MNT
))
...
@@ -2858,7 +2924,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
...
@@ -2858,7 +2924,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
type
=
LSM_AUDIT_DATA_DENTRY
;
ad
.
u
.
dentry
=
dentry
;
ad
.
u
.
dentry
=
dentry
;
sid
=
cred_sid
(
cred
);
sid
=
cred_sid
(
cred
);
isec
=
inode
->
i_security
;
isec
=
inode_security_rcu
(
inode
,
rcu
);
if
(
IS_ERR
(
isec
))
return
PTR_ERR
(
isec
);
return
avc_has_perm_flags
(
sid
,
isec
->
sid
,
isec
->
sclass
,
FILE__READ
,
&
ad
,
return
avc_has_perm_flags
(
sid
,
isec
->
sid
,
isec
->
sclass
,
FILE__READ
,
&
ad
,
rcu
?
MAY_NOT_BLOCK
:
0
);
rcu
?
MAY_NOT_BLOCK
:
0
);
...
@@ -2910,7 +2978,9 @@ static int selinux_inode_permission(struct inode *inode, int mask)
...
@@ -2910,7 +2978,9 @@ static int selinux_inode_permission(struct inode *inode, int mask)
perms
=
file_mask_to_av
(
inode
->
i_mode
,
mask
);
perms
=
file_mask_to_av
(
inode
->
i_mode
,
mask
);
sid
=
cred_sid
(
cred
);
sid
=
cred_sid
(
cred
);
isec
=
inode
->
i_security
;
isec
=
inode_security_rcu
(
inode
,
flags
&
MAY_NOT_BLOCK
);
if
(
IS_ERR
(
isec
))
return
PTR_ERR
(
isec
);
rc
=
avc_has_perm_noaudit
(
sid
,
isec
->
sid
,
isec
->
sclass
,
perms
,
0
,
&
avd
);
rc
=
avc_has_perm_noaudit
(
sid
,
isec
->
sid
,
isec
->
sclass
,
perms
,
0
,
&
avd
);
audited
=
avc_audit_required
(
perms
,
&
avd
,
rc
,
audited
=
avc_audit_required
(
perms
,
&
avd
,
rc
,
...
@@ -2980,7 +3050,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
...
@@ -2980,7 +3050,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
const
void
*
value
,
size_t
size
,
int
flags
)
const
void
*
value
,
size_t
size
,
int
flags
)
{
{
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
backing_inode_security
(
dentry
)
;
struct
superblock_security_struct
*
sbsec
;
struct
superblock_security_struct
*
sbsec
;
struct
common_audit_data
ad
;
struct
common_audit_data
ad
;
u32
newsid
,
sid
=
current_sid
();
u32
newsid
,
sid
=
current_sid
();
...
@@ -3057,7 +3127,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
...
@@ -3057,7 +3127,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
int
flags
)
int
flags
)
{
{
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
backing_inode_security
(
dentry
)
;
u32
newsid
;
u32
newsid
;
int
rc
;
int
rc
;
...
@@ -3076,7 +3146,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
...
@@ -3076,7 +3146,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sid
=
newsid
;
isec
->
sid
=
newsid
;
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
return
;
return
;
}
}
...
@@ -3110,12 +3180,12 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
...
@@ -3110,12 +3180,12 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
*
*
* Permission check is handled by selinux_inode_getxattr hook.
* Permission check is handled by selinux_inode_getxattr hook.
*/
*/
static
int
selinux_inode_getsecurity
(
const
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
static
int
selinux_inode_getsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
{
{
u32
size
;
u32
size
;
int
error
;
int
error
;
char
*
context
=
NULL
;
char
*
context
=
NULL
;
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
if
(
strcmp
(
name
,
XATTR_SELINUX_SUFFIX
))
if
(
strcmp
(
name
,
XATTR_SELINUX_SUFFIX
))
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
...
@@ -3154,7 +3224,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
...
@@ -3154,7 +3224,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
static
int
selinux_inode_setsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
static
int
selinux_inode_setsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
const
void
*
value
,
size_t
size
,
int
flags
)
{
{
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
u32
newsid
;
u32
newsid
;
int
rc
;
int
rc
;
...
@@ -3170,7 +3240,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
...
@@ -3170,7 +3240,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sclass
=
inode_mode_to_security_class
(
inode
->
i_mode
);
isec
->
sid
=
newsid
;
isec
->
sid
=
newsid
;
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
return
0
;
return
0
;
}
}
...
@@ -3182,9 +3252,9 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
...
@@ -3182,9 +3252,9 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
return
len
;
return
len
;
}
}
static
void
selinux_inode_getsecid
(
const
struct
inode
*
inode
,
u32
*
secid
)
static
void
selinux_inode_getsecid
(
struct
inode
*
inode
,
u32
*
secid
)
{
{
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
*
secid
=
isec
->
sid
;
*
secid
=
isec
->
sid
;
}
}
...
@@ -3207,7 +3277,7 @@ static int selinux_file_permission(struct file *file, int mask)
...
@@ -3207,7 +3277,7 @@ static int selinux_file_permission(struct file *file, int mask)
{
{
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode
*
inode
=
file_inode
(
file
);
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
u32
sid
=
current_sid
();
u32
sid
=
current_sid
();
if
(
!
mask
)
if
(
!
mask
)
...
@@ -3219,6 +3289,7 @@ static int selinux_file_permission(struct file *file, int mask)
...
@@ -3219,6 +3289,7 @@ static int selinux_file_permission(struct file *file, int mask)
/* No change since file_open check. */
/* No change since file_open check. */
return
0
;
return
0
;
inode_security_revalidate
(
inode
);
return
selinux_revalidate_file_permission
(
file
,
mask
);
return
selinux_revalidate_file_permission
(
file
,
mask
);
}
}
...
@@ -3242,7 +3313,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
...
@@ -3242,7 +3313,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
struct
common_audit_data
ad
;
struct
common_audit_data
ad
;
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
file_security_struct
*
fsec
=
file
->
f_security
;
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
struct
lsm_ioctlop_audit
ioctl
;
struct
lsm_ioctlop_audit
ioctl
;
u32
ssid
=
cred_sid
(
cred
);
u32
ssid
=
cred_sid
(
cred
);
int
rc
;
int
rc
;
...
@@ -3506,7 +3577,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
...
@@ -3506,7 +3577,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
struct
inode_security_struct
*
isec
;
struct
inode_security_struct
*
isec
;
fsec
=
file
->
f_security
;
fsec
=
file
->
f_security
;
isec
=
file_inode
(
file
)
->
i_security
;
isec
=
inode_security
(
file_inode
(
file
))
;
/*
/*
* Save inode label and policy sequence number
* Save inode label and policy sequence number
* at open-time so that selinux_file_permission
* at open-time so that selinux_file_permission
...
@@ -3524,6 +3595,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
...
@@ -3524,6 +3595,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
* new inode label or new policy.
* new inode label or new policy.
* This check is not redundant - do not remove.
* This check is not redundant - do not remove.
*/
*/
inode_security_revalidate
(
file_inode
(
file
));
return
file_path_has_perm
(
cred
,
file
,
open_file_to_av
(
file
));
return
file_path_has_perm
(
cred
,
file
,
open_file_to_av
(
file
));
}
}
...
@@ -3624,7 +3696,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
...
@@ -3624,7 +3696,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
*/
*/
static
int
selinux_kernel_create_files_as
(
struct
cred
*
new
,
struct
inode
*
inode
)
static
int
selinux_kernel_create_files_as
(
struct
cred
*
new
,
struct
inode
*
inode
)
{
{
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
struct
inode_security_struct
*
isec
=
inode
_security
(
inode
)
;
struct
task_security_struct
*
tsec
=
new
->
security
;
struct
task_security_struct
*
tsec
=
new
->
security
;
u32
sid
=
current_sid
();
u32
sid
=
current_sid
();
int
ret
;
int
ret
;
...
@@ -3748,7 +3820,7 @@ static void selinux_task_to_inode(struct task_struct *p,
...
@@ -3748,7 +3820,7 @@ static void selinux_task_to_inode(struct task_struct *p,
u32
sid
=
task_sid
(
p
);
u32
sid
=
task_sid
(
p
);
isec
->
sid
=
sid
;
isec
->
sid
=
sid
;
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
}
}
/* Returns error only if unable to parse addresses */
/* Returns error only if unable to parse addresses */
...
@@ -4065,7 +4137,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
...
@@ -4065,7 +4137,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
int
type
,
int
protocol
,
int
kern
)
int
type
,
int
protocol
,
int
kern
)
{
{
const
struct
task_security_struct
*
tsec
=
current_security
();
const
struct
task_security_struct
*
tsec
=
current_security
();
struct
inode_security_struct
*
isec
=
SOCK_INODE
(
sock
)
->
i_security
;
struct
inode_security_struct
*
isec
=
inode_security_novalidate
(
SOCK_INODE
(
sock
))
;
struct
sk_security_struct
*
sksec
;
struct
sk_security_struct
*
sksec
;
int
err
=
0
;
int
err
=
0
;
...
@@ -4079,7 +4151,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
...
@@ -4079,7 +4151,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
return
err
;
return
err
;
}
}
isec
->
initialized
=
1
;
isec
->
initialized
=
LABEL_INITIALIZED
;
if
(
sock
->
sk
)
{
if
(
sock
->
sk
)
{
sksec
=
sock
->
sk
->
sk_security
;
sksec
=
sock
->
sk
->
sk_security
;
...
@@ -4265,12 +4337,12 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
...
@@ -4265,12 +4337,12 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
if
(
err
)
if
(
err
)
return
err
;
return
err
;
newisec
=
SOCK_INODE
(
newsock
)
->
i_security
;
newisec
=
inode_security_novalidate
(
SOCK_INODE
(
newsock
))
;
isec
=
SOCK_INODE
(
sock
)
->
i_security
;
isec
=
inode_security_novalidate
(
SOCK_INODE
(
sock
))
;
newisec
->
sclass
=
isec
->
sclass
;
newisec
->
sclass
=
isec
->
sclass
;
newisec
->
sid
=
isec
->
sid
;
newisec
->
sid
=
isec
->
sid
;
newisec
->
initialized
=
1
;
newisec
->
initialized
=
LABEL_INITIALIZED
;
return
0
;
return
0
;
}
}
...
@@ -4605,7 +4677,8 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
...
@@ -4605,7 +4677,8 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
static
void
selinux_sock_graft
(
struct
sock
*
sk
,
struct
socket
*
parent
)
static
void
selinux_sock_graft
(
struct
sock
*
sk
,
struct
socket
*
parent
)
{
{
struct
inode_security_struct
*
isec
=
SOCK_INODE
(
parent
)
->
i_security
;
struct
inode_security_struct
*
isec
=
inode_security_novalidate
(
SOCK_INODE
(
parent
));
struct
sk_security_struct
*
sksec
=
sk
->
sk_security
;
struct
sk_security_struct
*
sksec
=
sk
->
sk_security
;
if
(
sk
->
sk_family
==
PF_INET
||
sk
->
sk_family
==
PF_INET6
||
if
(
sk
->
sk_family
==
PF_INET
||
sk
->
sk_family
==
PF_INET6
||
...
@@ -4785,11 +4858,12 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
...
@@ -4785,11 +4858,12 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
err
=
selinux_nlmsg_lookup
(
sksec
->
sclass
,
nlh
->
nlmsg_type
,
&
perm
);
err
=
selinux_nlmsg_lookup
(
sksec
->
sclass
,
nlh
->
nlmsg_type
,
&
perm
);
if
(
err
)
{
if
(
err
)
{
if
(
err
==
-
EINVAL
)
{
if
(
err
==
-
EINVAL
)
{
pr
intk
(
KERN_WARNING
pr
_warn_ratelimited
(
"SELinux: unrecognized netlink"
"
SELinux: unrecognized netlink message:
"
"
message: protocol=%hu nlmsg_type=%hu sclass=%s
"
" p
rotocol=%hu nlmsg_type=%hu sclass
=%s
\n
"
,
" p
ig=%d comm
=%s
\n
"
,
sk
->
sk_protocol
,
nlh
->
nlmsg_type
,
sk
->
sk_protocol
,
nlh
->
nlmsg_type
,
secclass_map
[
sksec
->
sclass
-
1
].
name
);
secclass_map
[
sksec
->
sclass
-
1
].
name
,
task_pid_nr
(
current
),
current
->
comm
);
if
(
!
selinux_enforcing
||
security_get_allow_unknown
())
if
(
!
selinux_enforcing
||
security_get_allow_unknown
())
err
=
0
;
err
=
0
;
}
}
...
@@ -5762,6 +5836,15 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
...
@@ -5762,6 +5836,15 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
kfree
(
secdata
);
kfree
(
secdata
);
}
}
static
void
selinux_inode_invalidate_secctx
(
struct
inode
*
inode
)
{
struct
inode_security_struct
*
isec
=
inode
->
i_security
;
mutex_lock
(
&
isec
->
lock
);
isec
->
initialized
=
LABEL_INVALID
;
mutex_unlock
(
&
isec
->
lock
);
}
/*
/*
* called with inode->i_mutex locked
* called with inode->i_mutex locked
*/
*/
...
@@ -5993,6 +6076,7 @@ static struct security_hook_list selinux_hooks[] = {
...
@@ -5993,6 +6076,7 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT
(
secid_to_secctx
,
selinux_secid_to_secctx
),
LSM_HOOK_INIT
(
secid_to_secctx
,
selinux_secid_to_secctx
),
LSM_HOOK_INIT
(
secctx_to_secid
,
selinux_secctx_to_secid
),
LSM_HOOK_INIT
(
secctx_to_secid
,
selinux_secctx_to_secid
),
LSM_HOOK_INIT
(
release_secctx
,
selinux_release_secctx
),
LSM_HOOK_INIT
(
release_secctx
,
selinux_release_secctx
),
LSM_HOOK_INIT
(
inode_invalidate_secctx
,
selinux_inode_invalidate_secctx
),
LSM_HOOK_INIT
(
inode_notifysecctx
,
selinux_inode_notifysecctx
),
LSM_HOOK_INIT
(
inode_notifysecctx
,
selinux_inode_notifysecctx
),
LSM_HOOK_INIT
(
inode_setsecctx
,
selinux_inode_setsecctx
),
LSM_HOOK_INIT
(
inode_setsecctx
,
selinux_inode_setsecctx
),
LSM_HOOK_INIT
(
inode_getsecctx
,
selinux_inode_getsecctx
),
LSM_HOOK_INIT
(
inode_getsecctx
,
selinux_inode_getsecctx
),
...
...
security/selinux/include/classmap.h
View file @
37babe4e
...
@@ -21,7 +21,7 @@ struct security_class_mapping secclass_map[] = {
...
@@ -21,7 +21,7 @@ struct security_class_mapping secclass_map[] = {
{
"compute_av"
,
"compute_create"
,
"compute_member"
,
{
"compute_av"
,
"compute_create"
,
"compute_member"
,
"check_context"
,
"load_policy"
,
"compute_relabel"
,
"check_context"
,
"load_policy"
,
"compute_relabel"
,
"compute_user"
,
"setenforce"
,
"setbool"
,
"setsecparam"
,
"compute_user"
,
"setenforce"
,
"setbool"
,
"setsecparam"
,
"setcheckreqprot"
,
"read_policy"
,
NULL
}
},
"setcheckreqprot"
,
"read_policy"
,
"validate_trans"
,
NULL
}
},
{
"process"
,
{
"process"
,
{
"fork"
,
"transition"
,
"sigchld"
,
"sigkill"
,
{
"fork"
,
"transition"
,
"sigchld"
,
"sigkill"
,
"sigstop"
,
"signull"
,
"signal"
,
"ptrace"
,
"getsched"
,
"setsched"
,
"sigstop"
,
"signull"
,
"signal"
,
"ptrace"
,
"getsched"
,
"setsched"
,
...
...
security/selinux/include/objsec.h
View file @
37babe4e
...
@@ -37,6 +37,12 @@ struct task_security_struct {
...
@@ -37,6 +37,12 @@ struct task_security_struct {
u32
sockcreate_sid
;
/* fscreate SID */
u32
sockcreate_sid
;
/* fscreate SID */
};
};
enum
label_initialized
{
LABEL_MISSING
,
/* not initialized */
LABEL_INITIALIZED
,
/* inizialized */
LABEL_INVALID
/* invalid */
};
struct
inode_security_struct
{
struct
inode_security_struct
{
struct
inode
*
inode
;
/* back pointer to inode object */
struct
inode
*
inode
;
/* back pointer to inode object */
union
{
union
{
...
...
security/selinux/include/security.h
View file @
37babe4e
...
@@ -187,6 +187,9 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
...
@@ -187,6 +187,9 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
int
security_validate_transition
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
int
security_validate_transition
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
u16
tclass
);
u16
tclass
);
int
security_validate_transition_user
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
u16
tclass
);
int
security_bounded_transition
(
u32
oldsid
,
u32
newsid
);
int
security_bounded_transition
(
u32
oldsid
,
u32
newsid
);
int
security_sid_mls_copy
(
u32
sid
,
u32
mls_sid
,
u32
*
new_sid
);
int
security_sid_mls_copy
(
u32
sid
,
u32
mls_sid
,
u32
*
new_sid
);
...
...
security/selinux/selinuxfs.c
View file @
37babe4e
...
@@ -116,6 +116,7 @@ enum sel_inos {
...
@@ -116,6 +116,7 @@ enum sel_inos {
SEL_DENY_UNKNOWN
,
/* export unknown deny handling to userspace */
SEL_DENY_UNKNOWN
,
/* export unknown deny handling to userspace */
SEL_STATUS
,
/* export current status using mmap() */
SEL_STATUS
,
/* export current status using mmap() */
SEL_POLICY
,
/* allow userspace to read the in kernel policy */
SEL_POLICY
,
/* allow userspace to read the in kernel policy */
SEL_VALIDATE_TRANS
,
/* compute validatetrans decision */
SEL_INO_NEXT
,
/* The next inode number to use */
SEL_INO_NEXT
,
/* The next inode number to use */
};
};
...
@@ -653,6 +654,83 @@ static const struct file_operations sel_checkreqprot_ops = {
...
@@ -653,6 +654,83 @@ static const struct file_operations sel_checkreqprot_ops = {
.
llseek
=
generic_file_llseek
,
.
llseek
=
generic_file_llseek
,
};
};
static
ssize_t
sel_write_validatetrans
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
char
*
oldcon
=
NULL
,
*
newcon
=
NULL
,
*
taskcon
=
NULL
;
char
*
req
=
NULL
;
u32
osid
,
nsid
,
tsid
;
u16
tclass
;
int
rc
;
rc
=
task_has_security
(
current
,
SECURITY__VALIDATE_TRANS
);
if
(
rc
)
goto
out
;
rc
=
-
ENOMEM
;
if
(
count
>=
PAGE_SIZE
)
goto
out
;
/* No partial writes. */
rc
=
-
EINVAL
;
if
(
*
ppos
!=
0
)
goto
out
;
rc
=
-
ENOMEM
;
req
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
req
)
goto
out
;
rc
=
-
EFAULT
;
if
(
copy_from_user
(
req
,
buf
,
count
))
goto
out
;
rc
=
-
ENOMEM
;
oldcon
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
oldcon
)
goto
out
;
newcon
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
newcon
)
goto
out
;
taskcon
=
kzalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
taskcon
)
goto
out
;
rc
=
-
EINVAL
;
if
(
sscanf
(
req
,
"%s %s %hu %s"
,
oldcon
,
newcon
,
&
tclass
,
taskcon
)
!=
4
)
goto
out
;
rc
=
security_context_str_to_sid
(
oldcon
,
&
osid
,
GFP_KERNEL
);
if
(
rc
)
goto
out
;
rc
=
security_context_str_to_sid
(
newcon
,
&
nsid
,
GFP_KERNEL
);
if
(
rc
)
goto
out
;
rc
=
security_context_str_to_sid
(
taskcon
,
&
tsid
,
GFP_KERNEL
);
if
(
rc
)
goto
out
;
rc
=
security_validate_transition_user
(
osid
,
nsid
,
tsid
,
tclass
);
if
(
!
rc
)
rc
=
count
;
out:
kfree
(
req
);
kfree
(
oldcon
);
kfree
(
newcon
);
kfree
(
taskcon
);
return
rc
;
}
static
const
struct
file_operations
sel_transition_ops
=
{
.
write
=
sel_write_validatetrans
,
.
llseek
=
generic_file_llseek
,
};
/*
/*
* Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
* Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
*/
*/
...
@@ -1759,6 +1837,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
...
@@ -1759,6 +1837,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
[
SEL_DENY_UNKNOWN
]
=
{
"deny_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_DENY_UNKNOWN
]
=
{
"deny_unknown"
,
&
sel_handle_unknown_ops
,
S_IRUGO
},
[
SEL_STATUS
]
=
{
"status"
,
&
sel_handle_status_ops
,
S_IRUGO
},
[
SEL_STATUS
]
=
{
"status"
,
&
sel_handle_status_ops
,
S_IRUGO
},
[
SEL_POLICY
]
=
{
"policy"
,
&
sel_policy_ops
,
S_IRUGO
},
[
SEL_POLICY
]
=
{
"policy"
,
&
sel_policy_ops
,
S_IRUGO
},
[
SEL_VALIDATE_TRANS
]
=
{
"validatetrans"
,
&
sel_transition_ops
,
S_IWUGO
},
/* last one */
{
""
}
/* last one */
{
""
}
};
};
ret
=
simple_fill_super
(
sb
,
SELINUX_MAGIC
,
selinux_files
);
ret
=
simple_fill_super
(
sb
,
SELINUX_MAGIC
,
selinux_files
);
...
...
security/selinux/ss/services.c
View file @
37babe4e
...
@@ -778,8 +778,8 @@ static int security_validtrans_handle_fail(struct context *ocontext,
...
@@ -778,8 +778,8 @@ static int security_validtrans_handle_fail(struct context *ocontext,
return
-
EPERM
;
return
-
EPERM
;
}
}
int
security_validate_transition
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
static
int
security_compute_validatetrans
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
u16
orig_tclass
)
u16
orig_tclass
,
bool
user
)
{
{
struct
context
*
ocontext
;
struct
context
*
ocontext
;
struct
context
*
ncontext
;
struct
context
*
ncontext
;
...
@@ -794,11 +794,12 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
...
@@ -794,11 +794,12 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
read_lock
(
&
policy_rwlock
);
read_lock
(
&
policy_rwlock
);
if
(
!
user
)
tclass
=
unmap_class
(
orig_tclass
);
tclass
=
unmap_class
(
orig_tclass
);
else
tclass
=
orig_tclass
;
if
(
!
tclass
||
tclass
>
policydb
.
p_classes
.
nprim
)
{
if
(
!
tclass
||
tclass
>
policydb
.
p_classes
.
nprim
)
{
printk
(
KERN_ERR
"SELinux: %s: unrecognized class %d
\n
"
,
__func__
,
tclass
);
rc
=
-
EINVAL
;
rc
=
-
EINVAL
;
goto
out
;
goto
out
;
}
}
...
@@ -832,8 +833,13 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
...
@@ -832,8 +833,13 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
while
(
constraint
)
{
while
(
constraint
)
{
if
(
!
constraint_expr_eval
(
ocontext
,
ncontext
,
tcontext
,
if
(
!
constraint_expr_eval
(
ocontext
,
ncontext
,
tcontext
,
constraint
->
expr
))
{
constraint
->
expr
))
{
rc
=
security_validtrans_handle_fail
(
ocontext
,
ncontext
,
if
(
user
)
tcontext
,
tclass
);
rc
=
-
EPERM
;
else
rc
=
security_validtrans_handle_fail
(
ocontext
,
ncontext
,
tcontext
,
tclass
);
goto
out
;
goto
out
;
}
}
constraint
=
constraint
->
next
;
constraint
=
constraint
->
next
;
...
@@ -844,6 +850,20 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
...
@@ -844,6 +850,20 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
return
rc
;
return
rc
;
}
}
int
security_validate_transition_user
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
u16
tclass
)
{
return
security_compute_validatetrans
(
oldsid
,
newsid
,
tasksid
,
tclass
,
true
);
}
int
security_validate_transition
(
u32
oldsid
,
u32
newsid
,
u32
tasksid
,
u16
orig_tclass
)
{
return
security_compute_validatetrans
(
oldsid
,
newsid
,
tasksid
,
orig_tclass
,
false
);
}
/*
/*
* security_bounded_transition - check whether the given
* security_bounded_transition - check whether the given
* transition is directed to bounded, or not.
* transition is directed to bounded, or not.
...
...
security/smack/smack_lsm.c
View file @
37babe4e
...
@@ -1465,7 +1465,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
...
@@ -1465,7 +1465,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
*
*
* Returns the size of the attribute or an error code
* Returns the size of the attribute or an error code
*/
*/
static
int
smack_inode_getsecurity
(
const
struct
inode
*
inode
,
static
int
smack_inode_getsecurity
(
struct
inode
*
inode
,
const
char
*
name
,
void
**
buffer
,
const
char
*
name
,
void
**
buffer
,
bool
alloc
)
bool
alloc
)
{
{
...
@@ -1538,7 +1538,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
...
@@ -1538,7 +1538,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
* @inode: inode to extract the info from
* @inode: inode to extract the info from
* @secid: where result will be saved
* @secid: where result will be saved
*/
*/
static
void
smack_inode_getsecid
(
const
struct
inode
*
inode
,
u32
*
secid
)
static
void
smack_inode_getsecid
(
struct
inode
*
inode
,
u32
*
secid
)
{
{
struct
inode_smack
*
isp
=
inode
->
i_security
;
struct
inode_smack
*
isp
=
inode
->
i_security
;
...
...
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