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
710584b9
Commit
710584b9
authored
Jan 27, 2017
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'smack-for-4.11' of
git://github.com/cschaufler/smack-next
into next
parents
c659af78
83a1e53f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
27 deletions
+95
-27
security/smack/smack.h
security/smack/smack.h
+3
-0
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+87
-27
security/smack/smackfs.c
security/smack/smackfs.c
+5
-0
No files found.
security/smack/smack.h
View file @
710584b9
...
@@ -114,6 +114,7 @@ struct inode_smack {
...
@@ -114,6 +114,7 @@ struct inode_smack {
struct
smack_known
*
smk_mmap
;
/* label of the mmap domain */
struct
smack_known
*
smk_mmap
;
/* label of the mmap domain */
struct
mutex
smk_lock
;
/* initialization lock */
struct
mutex
smk_lock
;
/* initialization lock */
int
smk_flags
;
/* smack inode flags */
int
smk_flags
;
/* smack inode flags */
struct
rcu_head
smk_rcu
;
/* for freeing inode_smack */
};
};
struct
task_smack
{
struct
task_smack
{
...
@@ -173,6 +174,8 @@ struct smk_port_label {
...
@@ -173,6 +174,8 @@ struct smk_port_label {
unsigned
short
smk_port
;
/* the port number */
unsigned
short
smk_port
;
/* the port number */
struct
smack_known
*
smk_in
;
/* inbound label */
struct
smack_known
*
smk_in
;
/* inbound label */
struct
smack_known
*
smk_out
;
/* outgoing label */
struct
smack_known
*
smk_out
;
/* outgoing label */
short
smk_sock_type
;
/* Socket type */
short
smk_can_reuse
;
};
};
#endif
/* SMACK_IPV6_PORT_LABELING */
#endif
/* SMACK_IPV6_PORT_LABELING */
...
...
security/smack/smack_lsm.c
View file @
710584b9
...
@@ -52,6 +52,7 @@
...
@@ -52,6 +52,7 @@
#define SMK_SENDING 2
#define SMK_SENDING 2
#ifdef SMACK_IPV6_PORT_LABELING
#ifdef SMACK_IPV6_PORT_LABELING
DEFINE_MUTEX
(
smack_ipv6_lock
);
static
LIST_HEAD
(
smk_ipv6_port_list
);
static
LIST_HEAD
(
smk_ipv6_port_list
);
#endif
#endif
static
struct
kmem_cache
*
smack_inode_cache
;
static
struct
kmem_cache
*
smack_inode_cache
;
...
@@ -347,8 +348,6 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
...
@@ -347,8 +348,6 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
struct
smack_rule
*
orp
;
struct
smack_rule
*
orp
;
int
rc
=
0
;
int
rc
=
0
;
INIT_LIST_HEAD
(
nhead
);
list_for_each_entry_rcu
(
orp
,
ohead
,
list
)
{
list_for_each_entry_rcu
(
orp
,
ohead
,
list
)
{
nrp
=
kzalloc
(
sizeof
(
struct
smack_rule
),
gfp
);
nrp
=
kzalloc
(
sizeof
(
struct
smack_rule
),
gfp
);
if
(
nrp
==
NULL
)
{
if
(
nrp
==
NULL
)
{
...
@@ -375,8 +374,6 @@ static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
...
@@ -375,8 +374,6 @@ static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
struct
smack_known_list_elem
*
nklep
;
struct
smack_known_list_elem
*
nklep
;
struct
smack_known_list_elem
*
oklep
;
struct
smack_known_list_elem
*
oklep
;
INIT_LIST_HEAD
(
nhead
);
list_for_each_entry
(
oklep
,
ohead
,
list
)
{
list_for_each_entry
(
oklep
,
ohead
,
list
)
{
nklep
=
kzalloc
(
sizeof
(
struct
smack_known_list_elem
),
gfp
);
nklep
=
kzalloc
(
sizeof
(
struct
smack_known_list_elem
),
gfp
);
if
(
nklep
==
NULL
)
{
if
(
nklep
==
NULL
)
{
...
@@ -1009,15 +1006,39 @@ static int smack_inode_alloc_security(struct inode *inode)
...
@@ -1009,15 +1006,39 @@ static int smack_inode_alloc_security(struct inode *inode)
}
}
/**
/**
* smack_inode_free_security - free an inode blob
* smack_inode_free_rcu - Free inode_smack blob from cache
* @head: the rcu_head for getting inode_smack pointer
*
* Call back function called from call_rcu() to free
* the i_security blob pointer in inode
*/
static
void
smack_inode_free_rcu
(
struct
rcu_head
*
head
)
{
struct
inode_smack
*
issp
;
issp
=
container_of
(
head
,
struct
inode_smack
,
smk_rcu
);
kmem_cache_free
(
smack_inode_cache
,
issp
);
}
/**
* smack_inode_free_security - free an inode blob using call_rcu()
* @inode: the inode with a blob
* @inode: the inode with a blob
*
*
* Clears the blob pointer in inode
* Clears the blob pointer in inode
using RCU
*/
*/
static
void
smack_inode_free_security
(
struct
inode
*
inode
)
static
void
smack_inode_free_security
(
struct
inode
*
inode
)
{
{
kmem_cache_free
(
smack_inode_cache
,
inode
->
i_security
);
struct
inode_smack
*
issp
=
inode
->
i_security
;
inode
->
i_security
=
NULL
;
/*
* The inode may still be referenced in a path walk and
* a call to smack_inode_permission() can be made
* after smack_inode_free_security() is called.
* To avoid race condition free the i_security via RCU
* and leave the current inode->i_security pointer intact.
* The inode will be freed after the RCU grace period too.
*/
call_rcu
(
&
issp
->
smk_rcu
,
smack_inode_free_rcu
);
}
}
/**
/**
...
@@ -1626,6 +1647,9 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
...
@@ -1626,6 +1647,9 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
struct
smk_audit_info
ad
;
struct
smk_audit_info
ad
;
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode
*
inode
=
file_inode
(
file
);
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
return
0
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
...
@@ -1655,6 +1679,9 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
...
@@ -1655,6 +1679,9 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
int
rc
;
int
rc
;
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode
*
inode
=
file_inode
(
file
);
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
return
0
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
),
MAY_LOCK
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
),
MAY_LOCK
,
&
ad
);
...
@@ -1681,6 +1708,9 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
...
@@ -1681,6 +1708,9 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
int
rc
=
0
;
int
rc
=
0
;
struct
inode
*
inode
=
file_inode
(
file
);
struct
inode
*
inode
=
file_inode
(
file
);
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
return
0
;
switch
(
cmd
)
{
switch
(
cmd
)
{
case
F_GETLK
:
case
F_GETLK
:
break
;
break
;
...
@@ -1734,6 +1764,9 @@ static int smack_mmap_file(struct file *file,
...
@@ -1734,6 +1764,9 @@ static int smack_mmap_file(struct file *file,
if
(
file
==
NULL
)
if
(
file
==
NULL
)
return
0
;
return
0
;
if
(
unlikely
(
IS_PRIVATE
(
file_inode
(
file
))))
return
0
;
isp
=
file_inode
(
file
)
->
i_security
;
isp
=
file_inode
(
file
)
->
i_security
;
if
(
isp
->
smk_mmap
==
NULL
)
if
(
isp
->
smk_mmap
==
NULL
)
return
0
;
return
0
;
...
@@ -1934,12 +1967,9 @@ static int smack_file_open(struct file *file, const struct cred *cred)
...
@@ -1934,12 +1967,9 @@ static int smack_file_open(struct file *file, const struct cred *cred)
struct
smk_audit_info
ad
;
struct
smk_audit_info
ad
;
int
rc
;
int
rc
;
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
return
0
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_
access
(
tsp
->
smk_task
,
smk_of_inode
(
inode
),
MAY_READ
,
&
ad
);
rc
=
smk_
tskacc
(
tsp
,
smk_of_inode
(
inode
),
MAY_READ
,
&
ad
);
rc
=
smk_bu_credfile
(
cred
,
file
,
MAY_READ
,
rc
);
rc
=
smk_bu_credfile
(
cred
,
file
,
MAY_READ
,
rc
);
return
rc
;
return
rc
;
...
@@ -2353,6 +2383,20 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
...
@@ -2353,6 +2383,20 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
*/
*/
static
void
smack_sk_free_security
(
struct
sock
*
sk
)
static
void
smack_sk_free_security
(
struct
sock
*
sk
)
{
{
#ifdef SMACK_IPV6_PORT_LABELING
struct
smk_port_label
*
spp
;
if
(
sk
->
sk_family
==
PF_INET6
)
{
rcu_read_lock
();
list_for_each_entry_rcu
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
spp
->
smk_sock
!=
sk
)
continue
;
spp
->
smk_can_reuse
=
1
;
break
;
}
rcu_read_unlock
();
}
#endif
kfree
(
sk
->
sk_security
);
kfree
(
sk
->
sk_security
);
}
}
...
@@ -2603,17 +2647,20 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
...
@@ -2603,17 +2647,20 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
* on the bound socket. Take the changes to the port
* on the bound socket. Take the changes to the port
* as well.
* as well.
*/
*/
list_for_each_entry
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
rcu_read_lock
();
list_for_each_entry_rcu
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
sk
!=
spp
->
smk_sock
)
if
(
sk
!=
spp
->
smk_sock
)
continue
;
continue
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_out
=
ssp
->
smk_out
;
spp
->
smk_out
=
ssp
->
smk_out
;
rcu_read_unlock
();
return
;
return
;
}
}
/*
/*
* A NULL address is only used for updating existing
* A NULL address is only used for updating existing
* bound entries. If there isn't one, it's OK.
* bound entries. If there isn't one, it's OK.
*/
*/
rcu_read_unlock
();
return
;
return
;
}
}
...
@@ -2629,16 +2676,23 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
...
@@ -2629,16 +2676,23 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
* Look for an existing port list entry.
* Look for an existing port list entry.
* This is an indication that a port is getting reused.
* This is an indication that a port is getting reused.
*/
*/
list_for_each_entry
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
rcu_read_lock
();
if
(
spp
->
smk_port
!=
port
)
list_for_each_entry_rcu
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
spp
->
smk_port
!=
port
||
spp
->
smk_sock_type
!=
sock
->
type
)
continue
;
continue
;
if
(
spp
->
smk_can_reuse
!=
1
)
{
rcu_read_unlock
();
return
;
}
spp
->
smk_port
=
port
;
spp
->
smk_port
=
port
;
spp
->
smk_sock
=
sk
;
spp
->
smk_sock
=
sk
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_out
=
ssp
->
smk_out
;
spp
->
smk_out
=
ssp
->
smk_out
;
spp
->
smk_can_reuse
=
0
;
rcu_read_unlock
();
return
;
return
;
}
}
rcu_read_unlock
();
/*
/*
* A new port entry is required.
* A new port entry is required.
*/
*/
...
@@ -2650,8 +2704,12 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
...
@@ -2650,8 +2704,12 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
spp
->
smk_sock
=
sk
;
spp
->
smk_sock
=
sk
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_in
=
ssp
->
smk_in
;
spp
->
smk_out
=
ssp
->
smk_out
;
spp
->
smk_out
=
ssp
->
smk_out
;
spp
->
smk_sock_type
=
sock
->
type
;
spp
->
smk_can_reuse
=
0
;
list_add
(
&
spp
->
list
,
&
smk_ipv6_port_list
);
mutex_lock
(
&
smack_ipv6_lock
);
list_add_rcu
(
&
spp
->
list
,
&
smk_ipv6_port_list
);
mutex_unlock
(
&
smack_ipv6_lock
);
return
;
return
;
}
}
...
@@ -2702,14 +2760,16 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
...
@@ -2702,14 +2760,16 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
return
0
;
return
0
;
port
=
ntohs
(
address
->
sin6_port
);
port
=
ntohs
(
address
->
sin6_port
);
list_for_each_entry
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
rcu_read_lock
();
if
(
spp
->
smk_port
!=
port
)
list_for_each_entry_rcu
(
spp
,
&
smk_ipv6_port_list
,
list
)
{
if
(
spp
->
smk_port
!=
port
||
spp
->
smk_sock_type
!=
sk
->
sk_type
)
continue
;
continue
;
object
=
spp
->
smk_in
;
object
=
spp
->
smk_in
;
if
(
act
==
SMK_CONNECTING
)
if
(
act
==
SMK_CONNECTING
)
ssp
->
smk_packet
=
spp
->
smk_out
;
ssp
->
smk_packet
=
spp
->
smk_out
;
break
;
break
;
}
}
rcu_read_unlock
();
return
smk_ipv6_check
(
skp
,
object
,
address
,
act
);
return
smk_ipv6_check
(
skp
,
object
,
address
,
act
);
}
}
...
@@ -3438,6 +3498,13 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
...
@@ -3438,6 +3498,13 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
case
PIPEFS_MAGIC
:
case
PIPEFS_MAGIC
:
isp
->
smk_inode
=
smk_of_current
();
isp
->
smk_inode
=
smk_of_current
();
break
;
break
;
case
SOCKFS_MAGIC
:
/*
* Socket access is controlled by the socket
* structures associated with the task involved.
*/
isp
->
smk_inode
=
&
smack_known_star
;
break
;
default:
default:
isp
->
smk_inode
=
sbsp
->
smk_root
;
isp
->
smk_inode
=
sbsp
->
smk_root
;
break
;
break
;
...
@@ -3454,19 +3521,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
...
@@ -3454,19 +3521,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
*/
switch
(
sbp
->
s_magic
)
{
switch
(
sbp
->
s_magic
)
{
case
SMACK_MAGIC
:
case
SMACK_MAGIC
:
case
PIPEFS_MAGIC
:
case
SOCKFS_MAGIC
:
case
CGROUP_SUPER_MAGIC
:
case
CGROUP_SUPER_MAGIC
:
/*
/*
* Casey says that it's a little embarrassing
* Casey says that it's a little embarrassing
* that the smack file system doesn't do
* that the smack file system doesn't do
* extended attributes.
* extended attributes.
*
*
* Casey says pipes are easy (?)
*
* Socket access is controlled by the socket
* structures associated with the task involved.
*
* Cgroupfs is special
* Cgroupfs is special
*/
*/
final
=
&
smack_known_star
;
final
=
&
smack_known_star
;
...
@@ -3849,7 +3909,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
...
@@ -3849,7 +3909,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
* ambient value.
* ambient value.
*/
*/
rcu_read_lock
();
rcu_read_lock
();
list_for_each_entry
(
skp
,
&
smack_known_list
,
list
)
{
list_for_each_entry
_rcu
(
skp
,
&
smack_known_list
,
list
)
{
if
(
sap
->
attr
.
mls
.
lvl
!=
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
)
if
(
sap
->
attr
.
mls
.
lvl
!=
skp
->
smk_netlabel
.
attr
.
mls
.
lvl
)
continue
;
continue
;
/*
/*
...
...
security/smack/smackfs.c
View file @
710584b9
...
@@ -67,6 +67,7 @@ enum smk_inos {
...
@@ -67,6 +67,7 @@ enum smk_inos {
/*
/*
* List locks
* List locks
*/
*/
static
DEFINE_MUTEX
(
smack_master_list_lock
);
static
DEFINE_MUTEX
(
smack_cipso_lock
);
static
DEFINE_MUTEX
(
smack_cipso_lock
);
static
DEFINE_MUTEX
(
smack_ambient_lock
);
static
DEFINE_MUTEX
(
smack_ambient_lock
);
static
DEFINE_MUTEX
(
smk_net4addr_lock
);
static
DEFINE_MUTEX
(
smk_net4addr_lock
);
...
@@ -262,12 +263,16 @@ static int smk_set_access(struct smack_parsed_rule *srp,
...
@@ -262,12 +263,16 @@ static int smk_set_access(struct smack_parsed_rule *srp,
* it needs to get added for reporting.
* it needs to get added for reporting.
*/
*/
if
(
global
)
{
if
(
global
)
{
mutex_unlock
(
rule_lock
);
smlp
=
kzalloc
(
sizeof
(
*
smlp
),
GFP_KERNEL
);
smlp
=
kzalloc
(
sizeof
(
*
smlp
),
GFP_KERNEL
);
if
(
smlp
!=
NULL
)
{
if
(
smlp
!=
NULL
)
{
smlp
->
smk_rule
=
sp
;
smlp
->
smk_rule
=
sp
;
mutex_lock
(
&
smack_master_list_lock
);
list_add_rcu
(
&
smlp
->
list
,
&
smack_rule_list
);
list_add_rcu
(
&
smlp
->
list
,
&
smack_rule_list
);
mutex_unlock
(
&
smack_master_list_lock
);
}
else
}
else
rc
=
-
ENOMEM
;
rc
=
-
ENOMEM
;
return
rc
;
}
}
}
}
...
...
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