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
9d5a5f65
Commit
9d5a5f65
authored
Jan 22, 2015
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'smack-for-3.20-rebased' of
git://git.gitorious.org/smack-next/kernel
into next
parents
743410a0
6d1cff2a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
267 additions
and
52 deletions
+267
-52
security/smack/Kconfig
security/smack/Kconfig
+12
-0
security/smack/Makefile
security/smack/Makefile
+1
-0
security/smack/smack.h
security/smack/smack.h
+11
-0
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+147
-52
security/smack/smack_netfilter.c
security/smack/smack_netfilter.c
+96
-0
No files found.
security/smack/Kconfig
View file @
9d5a5f65
...
...
@@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP
access rule set once the behavior is well understood.
This is a superior mechanism to the oft abused
"permissive" mode of other systems.
If you are unsure how to answer this question, answer N.
config SECURITY_SMACK_NETFILTER
bool "Packet marking using secmarks for netfilter"
depends on SECURITY_SMACK
depends on NETWORK_SECMARK
depends on NETFILTER
default n
help
This enables security marking of network packets using
Smack labels.
If you are unsure how to answer this question, answer N.
security/smack/Makefile
View file @
9d5a5f65
...
...
@@ -5,3 +5,4 @@
obj-$(CONFIG_SECURITY_SMACK)
:=
smack.o
smack-y
:=
smack_lsm.o smack_access.o smackfs.o
smack-$(CONFIG_NETFILTER)
+=
smack_netfilter.o
security/smack/smack.h
View file @
9d5a5f65
...
...
@@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *);
/*
* Shared data.
*/
extern
int
smack_enabled
;
extern
int
smack_cipso_direct
;
extern
int
smack_cipso_mapped
;
extern
struct
smack_known
*
smack_net_ambient
;
...
...
@@ -298,6 +299,16 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
return
tsp
->
smk_task
;
}
static
inline
struct
smack_known
*
smk_of_task_struct
(
const
struct
task_struct
*
t
)
{
struct
smack_known
*
skp
;
rcu_read_lock
();
skp
=
smk_of_task
(
__task_cred
(
t
)
->
security
);
rcu_read_unlock
();
return
skp
;
}
/*
* Present a pointer to the forked smack label entry in an task blob.
*/
...
...
security/smack/smack_lsm.c
View file @
9d5a5f65
...
...
@@ -43,8 +43,6 @@
#include <linux/binfmts.h>
#include "smack.h"
#define task_security(task) (task_cred_xxx((task), security))
#define TRANS_TRUE "TRUE"
#define TRANS_TRUE_SIZE 4
...
...
@@ -52,8 +50,11 @@
#define SMK_RECEIVING 1
#define SMK_SENDING 2
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
LIST_HEAD
(
smk_ipv6_port_list
);
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
static
struct
kmem_cache
*
smack_inode_cache
;
int
smack_enabled
;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static
void
smk_bu_mode
(
int
mode
,
char
*
s
)
...
...
@@ -120,7 +121,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
static
int
smk_bu_task
(
struct
task_struct
*
otp
,
int
mode
,
int
rc
)
{
struct
task_smack
*
tsp
=
current_security
();
struct
task_smack
*
otsp
=
task_security
(
otp
);
struct
smack_known
*
smk_task
=
smk_of_task_struct
(
otp
);
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
...
...
@@ -128,7 +129,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) %s to %s
\n
"
,
tsp
->
smk_task
->
smk_known
,
otsp
->
smk_task
->
smk_known
,
acc
,
tsp
->
smk_task
->
smk_known
,
smk_task
->
smk_known
,
acc
,
current
->
comm
,
otp
->
comm
);
return
0
;
}
...
...
@@ -160,7 +161,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
{
struct
task_smack
*
tsp
=
current_security
();
struct
smack_known
*
sskp
=
tsp
->
smk_task
;
struct
inode
*
inode
=
file
->
f_inode
;
struct
inode
*
inode
=
file
_inode
(
file
)
;
char
acc
[
SMK_NUM_ACCESS_TYPE
+
1
];
if
(
rc
<=
0
)
...
...
@@ -168,7 +169,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
smk_bu_mode
(
mode
,
acc
);
pr_info
(
"Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s
\n
"
,
sskp
->
smk_known
,
(
char
*
)
file
->
f_security
,
acc
,
sskp
->
smk_known
,
smk_of_inode
(
inode
)
->
smk_known
,
acc
,
inode
->
i_sb
->
s_id
,
inode
->
i_ino
,
file
,
current
->
comm
);
return
0
;
...
...
@@ -202,6 +203,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
/**
* smk_fetch - Fetch the smack label from a file.
* @name: type of the label (attribute)
* @ip: a pointer to the inode
* @dp: a pointer to the dentry
*
...
...
@@ -254,7 +256,9 @@ struct inode_smack *new_inode_smack(struct smack_known *skp)
/**
* new_task_smack - allocate a task security blob
* @smack: a pointer to the Smack label to use in the blob
* @task: a pointer to the Smack label for the running task
* @forked: a pointer to the Smack label for the forked task
* @gfp: type of the memory for the allocation
*
* Returns the new blob or NULL if there's no memory available
*/
...
...
@@ -277,8 +281,9 @@ static struct task_smack *new_task_smack(struct smack_known *task,
/**
* smk_copy_rules - copy a rule set
* @nhead - new rules header pointer
* @ohead - old rules header pointer
* @nhead: new rules header pointer
* @ohead: old rules header pointer
* @gfp: type of the memory for the allocation
*
* Returns 0 on success, -ENOMEM on error
*/
...
...
@@ -345,7 +350,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
saip
=
&
ad
;
}
tsp
=
task_security
(
tracer
);
rcu_read_lock
();
tsp
=
__task_cred
(
tracer
)
->
security
;
tracer_known
=
smk_of_task
(
tsp
);
if
((
mode
&
PTRACE_MODE_ATTACH
)
&&
...
...
@@ -365,11 +371,14 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
tracee_known
->
smk_known
,
0
,
rc
,
saip
);
rcu_read_unlock
();
return
rc
;
}
/* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
rc
=
smk_tskacc
(
tsp
,
tracee_known
,
smk_ptrace_mode
(
mode
),
saip
);
rcu_read_unlock
();
return
rc
;
}
...
...
@@ -396,7 +405,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
if
(
rc
!=
0
)
return
rc
;
skp
=
smk_of_task
(
task_security
(
ctp
)
);
skp
=
smk_of_task
_struct
(
ctp
);
rc
=
smk_ptrace_rule_check
(
current
,
skp
,
mode
,
__func__
);
return
rc
;
...
...
@@ -796,7 +805,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
if
(
name
)
*
name
=
XATTR_SMACK_SUFFIX
;
if
(
value
)
{
if
(
value
&&
len
)
{
rcu_read_lock
();
may
=
smk_access_entry
(
skp
->
smk_known
,
dsp
->
smk_known
,
&
skp
->
smk_rules
);
...
...
@@ -817,10 +826,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
*
value
=
kstrdup
(
isp
->
smk_known
,
GFP_NOFS
);
if
(
*
value
==
NULL
)
return
-
ENOMEM
;
}
if
(
len
)
*
len
=
strlen
(
isp
->
smk_known
);
}
return
0
;
}
...
...
@@ -1344,6 +1352,9 @@ static int smack_file_permission(struct file *file, int mask)
* The security blob for a file is a pointer to the master
* label list, so no allocation is done.
*
* f_security is the owner security information. It
* isn't used on file access checks, it's for send_sigio.
*
* Returns 0
*/
static
int
smack_file_alloc_security
(
struct
file
*
file
)
...
...
@@ -1381,17 +1392,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
{
int
rc
=
0
;
struct
smk_audit_info
ad
;
struct
inode
*
inode
=
file_inode
(
file
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
if
(
_IOC_DIR
(
cmd
)
&
_IOC_WRITE
)
{
rc
=
smk_curacc
(
file
->
f_security
,
MAY_WRITE
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_WRITE
,
rc
);
}
if
(
rc
==
0
&&
(
_IOC_DIR
(
cmd
)
&
_IOC_READ
))
{
rc
=
smk_curacc
(
file
->
f_security
,
MAY_READ
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
MAY_READ
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_READ
,
rc
);
}
...
...
@@ -1409,10 +1421,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
{
struct
smk_audit_info
ad
;
int
rc
;
struct
inode
*
inode
=
file_inode
(
file
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_LOCK
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
MAY_LOCK
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_LOCK
,
rc
);
return
rc
;
}
...
...
@@ -1434,7 +1447,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
{
struct
smk_audit_info
ad
;
int
rc
=
0
;
struct
inode
*
inode
=
file_inode
(
file
);
switch
(
cmd
)
{
case
F_GETLK
:
...
...
@@ -1443,14 +1456,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
case
F_SETLKW
:
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_LOCK
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
MAY_LOCK
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_LOCK
,
rc
);
break
;
case
F_SETOWN
:
case
F_SETSIG
:
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_curacc
(
file
->
f_security
,
MAY_WRITE
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_file
(
file
,
MAY_WRITE
,
rc
);
break
;
default:
...
...
@@ -1568,14 +1581,10 @@ static int smack_mmap_file(struct file *file,
* smack_file_set_fowner - set the file security blob value
* @file: object in question
*
* Returns 0
* Further research may be required on this one.
*/
static
void
smack_file_set_fowner
(
struct
file
*
file
)
{
struct
smack_known
*
skp
=
smk_of_current
();
file
->
f_security
=
skp
;
file
->
f_security
=
smk_of_current
();
}
/**
...
...
@@ -1627,6 +1636,7 @@ static int smack_file_receive(struct file *file)
int
rc
;
int
may
=
0
;
struct
smk_audit_info
ad
;
struct
inode
*
inode
=
file_inode
(
file
);
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
...
...
@@ -1638,7 +1648,7 @@ static int smack_file_receive(struct file *file)
if
(
file
->
f_mode
&
FMODE_WRITE
)
may
|=
MAY_WRITE
;
rc
=
smk_curacc
(
file
->
f_security
,
may
,
&
ad
);
rc
=
smk_curacc
(
smk_of_inode
(
inode
)
,
may
,
&
ad
);
rc
=
smk_bu_file
(
file
,
may
,
rc
);
return
rc
;
}
...
...
@@ -1658,21 +1668,17 @@ static int smack_file_receive(struct file *file)
static
int
smack_file_open
(
struct
file
*
file
,
const
struct
cred
*
cred
)
{
struct
task_smack
*
tsp
=
cred
->
security
;
struct
inode
_smack
*
isp
=
file_inode
(
file
)
->
i_security
;
struct
inode
*
inode
=
file_inode
(
file
)
;
struct
smk_audit_info
ad
;
int
rc
;
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
{
file
->
f_security
=
isp
->
smk_inode
;
if
(
smack_privileged
(
CAP_MAC_OVERRIDE
))
return
0
;
}
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_PATH
);
smk_ad_setfield_u_fs_path
(
&
ad
,
file
->
f_path
);
rc
=
smk_access
(
tsp
->
smk_task
,
isp
->
smk_inode
,
MAY_READ
,
&
ad
);
rc
=
smk_access
(
tsp
->
smk_task
,
smk_of_inode
(
inode
)
,
MAY_READ
,
&
ad
);
rc
=
smk_bu_credfile
(
cred
,
file
,
MAY_READ
,
rc
);
if
(
rc
==
0
)
file
->
f_security
=
isp
->
smk_inode
;
return
rc
;
}
...
...
@@ -1826,7 +1832,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
const
char
*
caller
)
{
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
)
);
struct
smack_known
*
skp
=
smk_of_task
_struct
(
p
);
int
rc
;
smk_ad_init
(
&
ad
,
caller
,
LSM_AUDIT_DATA_TASK
);
...
...
@@ -1879,7 +1885,7 @@ static int smack_task_getsid(struct task_struct *p)
*/
static
void
smack_task_getsecid
(
struct
task_struct
*
p
,
u32
*
secid
)
{
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
)
);
struct
smack_known
*
skp
=
smk_of_task
_struct
(
p
);
*
secid
=
skp
->
smk_secid
;
}
...
...
@@ -1986,7 +1992,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
{
struct
smk_audit_info
ad
;
struct
smack_known
*
skp
;
struct
smack_known
*
tkp
=
smk_of_task
(
task_security
(
p
)
);
struct
smack_known
*
tkp
=
smk_of_task
_struct
(
p
);
int
rc
;
smk_ad_init
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_TASK
);
...
...
@@ -2040,7 +2046,7 @@ static int smack_task_wait(struct task_struct *p)
static
void
smack_task_to_inode
(
struct
task_struct
*
p
,
struct
inode
*
inode
)
{
struct
inode_smack
*
isp
=
inode
->
i_security
;
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
)
);
struct
smack_known
*
skp
=
smk_of_task
_struct
(
p
);
isp
->
smk_inode
=
skp
;
}
...
...
@@ -2212,6 +2218,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
return
smack_netlabel
(
sk
,
sk_lbl
);
}
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
/**
* smk_ipv6_port_label - Smack port access table management
* @sock: socket
...
...
@@ -2361,6 +2368,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
rc
=
smk_bu_note
(
"IPv6 port check"
,
skp
,
object
,
MAY_WRITE
,
rc
);
return
rc
;
}
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
/**
* smack_inode_setsecurity - set smack xattrs
...
...
@@ -2421,8 +2429,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
}
else
return
-
EOPNOTSUPP
;
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
if
(
sock
->
sk
->
sk_family
==
PF_INET6
)
smk_ipv6_port_label
(
sock
,
NULL
);
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
return
0
;
}
...
...
@@ -2450,6 +2460,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
return
smack_netlabel
(
sock
->
sk
,
SMACK_CIPSO_SOCKET
);
}
#ifndef CONFIG_SECURITY_SMACK_NETFILTER
/**
* smack_socket_bind - record port binding information.
* @sock: the socket
...
...
@@ -2463,11 +2474,14 @@ static int smack_socket_post_create(struct socket *sock, int family,
static
int
smack_socket_bind
(
struct
socket
*
sock
,
struct
sockaddr
*
address
,
int
addrlen
)
{
#if IS_ENABLED(CONFIG_IPV6)
if
(
sock
->
sk
!=
NULL
&&
sock
->
sk
->
sk_family
==
PF_INET6
)
smk_ipv6_port_label
(
sock
,
address
);
#endif
return
0
;
}
#endif
/* !CONFIG_SECURITY_SMACK_NETFILTER */
/**
* smack_socket_connect - connect access check
...
...
@@ -2496,8 +2510,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
case
PF_INET6
:
if
(
addrlen
<
sizeof
(
struct
sockaddr_in6
))
return
-
EINVAL
;
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
rc
=
smk_ipv6_port_check
(
sock
->
sk
,
(
struct
sockaddr_in6
*
)
sap
,
SMK_CONNECTING
);
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
break
;
}
return
rc
;
...
...
@@ -3033,7 +3049,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* of the superblock.
*/
if
(
opt_dentry
->
d_parent
==
opt_dentry
)
{
if
(
sbp
->
s_magic
==
CGROUP_SUPER_MAGIC
)
{
switch
(
sbp
->
s_magic
)
{
case
CGROUP_SUPER_MAGIC
:
/*
* The cgroup filesystem is never mounted,
* so there's no opportunity to set the mount
...
...
@@ -3041,8 +3058,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
sbsp
->
smk_root
=
&
smack_known_star
;
sbsp
->
smk_default
=
&
smack_known_star
;
isp
->
smk_inode
=
sbsp
->
smk_root
;
break
;
case
TMPFS_MAGIC
:
/*
* What about shmem/tmpfs anonymous files with dentry
* obtained from d_alloc_pseudo()?
*/
isp
->
smk_inode
=
smk_of_current
();
break
;
default:
isp
->
smk_inode
=
sbsp
->
smk_root
;
break
;
}
isp
->
smk_inode
=
sbsp
->
smk_root
;
isp
->
smk_flags
|=
SMK_INODE_INSTANT
;
goto
unlockandout
;
}
...
...
@@ -3200,7 +3228,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
static
int
smack_getprocattr
(
struct
task_struct
*
p
,
char
*
name
,
char
**
value
)
{
struct
smack_known
*
skp
=
smk_of_task
(
task_security
(
p
)
);
struct
smack_known
*
skp
=
smk_of_task
_struct
(
p
);
char
*
cp
;
int
slen
;
...
...
@@ -3297,7 +3325,7 @@ static int smack_unix_stream_connect(struct sock *sock,
if
(
!
smack_privileged
(
CAP_MAC_OVERRIDE
))
{
skp
=
ssp
->
smk_out
;
okp
=
osp
->
smk_
out
;
okp
=
osp
->
smk_
in
;
#ifdef CONFIG_AUDIT
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
smk_ad_setfield_u_net_sk
(
&
ad
,
other
);
...
...
@@ -3305,7 +3333,9 @@ static int smack_unix_stream_connect(struct sock *sock,
rc
=
smk_access
(
skp
,
okp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"UDS connect"
,
skp
,
okp
,
MAY_WRITE
,
rc
);
if
(
rc
==
0
)
{
rc
=
smk_access
(
okp
,
skp
,
MAY_WRITE
,
NULL
);
okp
=
osp
->
smk_out
;
skp
=
ssp
->
smk_in
;
rc
=
smk_access
(
okp
,
skp
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"UDS connect"
,
okp
,
skp
,
MAY_WRITE
,
rc
);
}
...
...
@@ -3366,7 +3396,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
int
size
)
{
struct
sockaddr_in
*
sip
=
(
struct
sockaddr_in
*
)
msg
->
msg_name
;
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
struct
sockaddr_in6
*
sap
=
(
struct
sockaddr_in6
*
)
msg
->
msg_name
;
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
int
rc
=
0
;
/*
...
...
@@ -3380,7 +3412,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
rc
=
smack_netlabel_send
(
sock
->
sk
,
sip
);
break
;
case
AF_INET6
:
#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
rc
=
smk_ipv6_port_check
(
sock
->
sk
,
sap
,
SMK_SENDING
);
#endif
/* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */
break
;
}
return
rc
;
...
...
@@ -3471,6 +3505,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
return
smack_net_ambient
;
}
#if IS_ENABLED(CONFIG_IPV6)
static
int
smk_skb_to_addr_ipv6
(
struct
sk_buff
*
skb
,
struct
sockaddr_in6
*
sip
)
{
u8
nexthdr
;
...
...
@@ -3517,6 +3552,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
}
return
proto
;
}
#endif
/* CONFIG_IPV6 */
/**
* smack_socket_sock_rcv_skb - Smack packet delivery access check
...
...
@@ -3529,15 +3565,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
struct
netlbl_lsm_secattr
secattr
;
struct
socket_smack
*
ssp
=
sk
->
sk_security
;
struct
smack_known
*
skp
;
struct
sockaddr_in6
sadd
;
struct
smack_known
*
skp
=
NULL
;
int
rc
=
0
;
struct
smk_audit_info
ad
;
#ifdef CONFIG_AUDIT
struct
lsm_network_audit
net
;
#endif
#if IS_ENABLED(CONFIG_IPV6)
struct
sockaddr_in6
sadd
;
int
proto
;
#endif
/* CONFIG_IPV6 */
switch
(
sk
->
sk_family
)
{
case
PF_INET
:
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
/*
* If there is a secmark use it rather than the CIPSO label.
* If there is no secmark fall back to CIPSO.
* The secmark is assumed to reflect policy better.
*/
if
(
skb
&&
skb
->
secmark
!=
0
)
{
skp
=
smack_from_secid
(
skb
->
secmark
);
goto
access_check
;
}
#endif
/* CONFIG_SECURITY_SMACK_NETFILTER */
/*
* Translate what netlabel gave us.
*/
...
...
@@ -3551,6 +3602,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
netlbl_secattr_destroy
(
&
secattr
);
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
access_check:
#endif
#ifdef CONFIG_AUDIT
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
ad
.
a
.
u
.
net
->
family
=
sk
->
sk_family
;
...
...
@@ -3569,14 +3623,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
if
(
rc
!=
0
)
netlbl_skbuff_err
(
skb
,
rc
,
0
);
break
;
#if IS_ENABLED(CONFIG_IPV6)
case
PF_INET6
:
rc
=
smk_skb_to_addr_ipv6
(
skb
,
&
sadd
);
if
(
rc
==
IPPROTO_UDP
||
rc
==
IPPROTO_TCP
)
rc
=
smk_ipv6_port_check
(
sk
,
&
sadd
,
SMK_RECEIVING
);
proto
=
smk_skb_to_addr_ipv6
(
skb
,
&
sadd
);
if
(
proto
!=
IPPROTO_UDP
&&
proto
!=
IPPROTO_TCP
)
break
;
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
if
(
skb
&&
skb
->
secmark
!=
0
)
skp
=
smack_from_secid
(
skb
->
secmark
);
else
rc
=
0
;
skp
=
smack_net_ambient
;
#ifdef CONFIG_AUDIT
smk_ad_init_net
(
&
ad
,
__func__
,
LSM_AUDIT_DATA_NET
,
&
net
);
ad
.
a
.
u
.
net
->
family
=
sk
->
sk_family
;
ad
.
a
.
u
.
net
->
netif
=
skb
->
skb_iif
;
ipv6_skb_to_auditdata
(
skb
,
&
ad
.
a
,
NULL
);
#endif
/* CONFIG_AUDIT */
rc
=
smk_access
(
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
&
ad
);
rc
=
smk_bu_note
(
"IPv6 delivery"
,
skp
,
ssp
->
smk_in
,
MAY_WRITE
,
rc
);
#else
/* CONFIG_SECURITY_SMACK_NETFILTER */
rc
=
smk_ipv6_port_check
(
sk
,
&
sadd
,
SMK_RECEIVING
);
#endif
/* CONFIG_SECURITY_SMACK_NETFILTER */
break
;
#endif
/* CONFIG_IPV6 */
}
return
rc
;
}
...
...
@@ -3638,16 +3710,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
if
(
skb
!=
NULL
)
{
if
(
skb
->
protocol
==
htons
(
ETH_P_IP
))
family
=
PF_INET
;
#if IS_ENABLED(CONFIG_IPV6)
else
if
(
skb
->
protocol
==
htons
(
ETH_P_IPV6
))
family
=
PF_INET6
;
#endif
/* CONFIG_IPV6 */
}
if
(
family
==
PF_UNSPEC
&&
sock
!=
NULL
)
family
=
sock
->
sk
->
sk_family
;
if
(
family
==
PF_UNIX
)
{
switch
(
family
)
{
case
PF_UNIX
:
ssp
=
sock
->
sk
->
sk_security
;
s
=
ssp
->
smk_out
->
smk_secid
;
}
else
if
(
family
==
PF_INET
||
family
==
PF_INET6
)
{
break
;
case
PF_INET
:
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
s
=
skb
->
secmark
;
if
(
s
!=
0
)
break
;
#endif
/*
* Translate what netlabel gave us.
*/
...
...
@@ -3660,6 +3741,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
s
=
skp
->
smk_secid
;
}
netlbl_secattr_destroy
(
&
secattr
);
break
;
#if IS_ENABLED(CONFIG_IPV6)
case
PF_INET6
:
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
s
=
skb
->
secmark
;
#endif
/* CONFIG_SECURITY_SMACK_NETFILTER */
break
;
#endif
/* CONFIG_IPV6 */
}
*
secid
=
s
;
if
(
s
==
0
)
...
...
@@ -3715,6 +3804,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct
lsm_network_audit
net
;
#endif
#if IS_ENABLED(CONFIG_IPV6)
if
(
family
==
PF_INET6
)
{
/*
* Handle mapped IPv4 packets arriving
...
...
@@ -3726,6 +3816,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
else
return
0
;
}
#endif
/* CONFIG_IPV6 */
netlbl_secattr_init
(
&
secattr
);
rc
=
netlbl_skbuff_getattr
(
skb
,
family
,
&
secattr
);
...
...
@@ -3834,11 +3925,11 @@ static void smack_key_free(struct key *key)
key
->
security
=
NULL
;
}
/*
/*
*
* smack_key_permission - Smack access on a key
* @key_ref: gets to the object
* @cred: the credentials to use
* @perm:
unused
* @perm:
requested key permissions
*
* Return 0 if the task has read and write to the object,
* an error code otherwise
...
...
@@ -4184,7 +4275,9 @@ struct security_operations smack_ops = {
.
unix_may_send
=
smack_unix_may_send
,
.
socket_post_create
=
smack_socket_post_create
,
#ifndef CONFIG_SECURITY_SMACK_NETFILTER
.
socket_bind
=
smack_socket_bind
,
#endif
/* CONFIG_SECURITY_SMACK_NETFILTER */
.
socket_connect
=
smack_socket_connect
,
.
socket_sendmsg
=
smack_socket_sendmsg
,
.
socket_sock_rcv_skb
=
smack_socket_sock_rcv_skb
,
...
...
@@ -4265,6 +4358,8 @@ static __init int smack_init(void)
if
(
!
security_module_enable
(
&
smack_ops
))
return
0
;
smack_enabled
=
1
;
smack_inode_cache
=
KMEM_CACHE
(
inode_smack
,
0
);
if
(
!
smack_inode_cache
)
return
-
ENOMEM
;
...
...
security/smack/smack_netfilter.c
0 → 100644
View file @
9d5a5f65
/*
* Simplified MAC Kernel (smack) security module
*
* This file contains the Smack netfilter implementation
*
* Author:
* Casey Schaufler <casey@schaufler-ca.com>
*
* Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com>
* Copyright (C) 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*/
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netdevice.h>
#include "smack.h"
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static
unsigned
int
smack_ipv6_output
(
const
struct
nf_hook_ops
*
ops
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
struct
socket_smack
*
ssp
;
struct
smack_known
*
skp
;
if
(
skb
&&
skb
->
sk
&&
skb
->
sk
->
sk_security
)
{
ssp
=
skb
->
sk
->
sk_security
;
skp
=
ssp
->
smk_out
;
skb
->
secmark
=
skp
->
smk_secid
;
}
return
NF_ACCEPT
;
}
#endif
/* IPV6 */
static
unsigned
int
smack_ipv4_output
(
const
struct
nf_hook_ops
*
ops
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
struct
socket_smack
*
ssp
;
struct
smack_known
*
skp
;
if
(
skb
&&
skb
->
sk
&&
skb
->
sk
->
sk_security
)
{
ssp
=
skb
->
sk
->
sk_security
;
skp
=
ssp
->
smk_out
;
skb
->
secmark
=
skp
->
smk_secid
;
}
return
NF_ACCEPT
;
}
static
struct
nf_hook_ops
smack_nf_ops
[]
=
{
{
.
hook
=
smack_ipv4_output
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_SELINUX_FIRST
,
},
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
{
.
hook
=
smack_ipv6_output
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_SELINUX_FIRST
,
},
#endif
/* IPV6 */
};
static
int
__init
smack_nf_ip_init
(
void
)
{
int
err
;
if
(
smack_enabled
==
0
)
return
0
;
printk
(
KERN_DEBUG
"Smack: Registering netfilter hooks
\n
"
);
err
=
nf_register_hooks
(
smack_nf_ops
,
ARRAY_SIZE
(
smack_nf_ops
));
if
(
err
)
pr_info
(
"Smack: nf_register_hooks: error %d
\n
"
,
err
);
return
0
;
}
__initcall
(
smack_nf_ip_init
);
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