|
@@ -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 @@ auditout:
|
|
|
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 @@ unlockandout:
|
|
|
*/
|
|
|
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;
|