smack: Add a new '-CIPSO' option to the network address label configuration
This patch adds a new special option '-CIPSO' to the Smack subsystem. When used in the netlabel list, it means "use CIPSO networking". A use case is when your local network speaks CIPSO and you want also to connect to the unlabeled Internet. This patch also add some documentation describing that. The patch also corrects an oops when setting a '' SMACK64 xattr to a file. Signed-off-by: Etienne Basset <etienne.basset@numericable.fr> Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
committed by
James Morris
parent
07feee8f81
commit
4303154e86
@ -132,6 +132,8 @@ struct smack_known {
|
||||
#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
|
||||
#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
|
||||
|
||||
#define SMACK_CIPSO_OPTION "-CIPSO"
|
||||
|
||||
/*
|
||||
* How communications on this socket are treated.
|
||||
* Usually it's determined by the underlying netlabel code
|
||||
@ -199,6 +201,7 @@ u32 smack_to_secid(const char *);
|
||||
extern int smack_cipso_direct;
|
||||
extern char *smack_net_ambient;
|
||||
extern char *smack_onlycap;
|
||||
extern const char *smack_cipso_option;
|
||||
|
||||
extern struct smack_known smack_known_floor;
|
||||
extern struct smack_known smack_known_hat;
|
||||
|
@ -261,6 +261,9 @@ char *smk_import(const char *string, int len)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
|
||||
/* labels cannot begin with a '-' */
|
||||
if (string[0] == '-')
|
||||
return NULL;
|
||||
skp = smk_import_entry(string, len);
|
||||
if (skp == NULL)
|
||||
return NULL;
|
||||
|
@ -609,6 +609,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
|
||||
strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
|
||||
if (!capable(CAP_MAC_ADMIN))
|
||||
rc = -EPERM;
|
||||
/* a label cannot be void and cannot begin with '-' */
|
||||
if (size == 0 || (size > 0 && ((char *)value)[0] == '-'))
|
||||
rc = -EINVAL;
|
||||
} else
|
||||
rc = cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
|
||||
@ -1323,8 +1326,12 @@ static char *smack_host_label(struct sockaddr_in *sip)
|
||||
* so we have found the most specific match
|
||||
*/
|
||||
if ((&snp->smk_host.sin_addr)->s_addr ==
|
||||
(siap->s_addr & (&snp->smk_mask)->s_addr))
|
||||
(siap->s_addr & (&snp->smk_mask)->s_addr)) {
|
||||
/* we have found the special CIPSO option */
|
||||
if (snp->smk_label == smack_cipso_option)
|
||||
return NULL;
|
||||
return snp->smk_label;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1486,7 +1493,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
|
||||
struct socket *sock;
|
||||
int rc = 0;
|
||||
|
||||
if (value == NULL || size > SMK_LABELLEN)
|
||||
if (value == NULL || size > SMK_LABELLEN || size == 0)
|
||||
return -EACCES;
|
||||
|
||||
sp = smk_import(value, size);
|
||||
|
@ -86,6 +86,9 @@ LIST_HEAD(smack_rule_list);
|
||||
|
||||
static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
|
||||
|
||||
const char *smack_cipso_option = SMACK_CIPSO_OPTION;
|
||||
|
||||
|
||||
#define SEQ_READ_FINISHED 1
|
||||
|
||||
/*
|
||||
@ -565,6 +568,11 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
|
||||
goto unlockedout;
|
||||
}
|
||||
|
||||
/* labels cannot begin with a '-' */
|
||||
if (data[0] == '-') {
|
||||
rc = -EINVAL;
|
||||
goto unlockedout;
|
||||
}
|
||||
data[count] = '\0';
|
||||
rule = data;
|
||||
/*
|
||||
@ -808,9 +816,18 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
|
||||
if (m > BEBITS)
|
||||
return -EINVAL;
|
||||
|
||||
sp = smk_import(smack, 0);
|
||||
if (sp == NULL)
|
||||
return -EINVAL;
|
||||
/* if smack begins with '-', its an option, don't import it */
|
||||
if (smack[0] != '-') {
|
||||
sp = smk_import(smack, 0);
|
||||
if (sp == NULL)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
/* check known options */
|
||||
if (strcmp(smack, smack_cipso_option) == 0)
|
||||
sp = (char *)smack_cipso_option;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (temp_mask = 0; m > 0; m--) {
|
||||
temp_mask |= mask_bits;
|
||||
@ -849,18 +866,23 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
|
||||
smk_netlbladdr_insert(skp);
|
||||
}
|
||||
} else {
|
||||
rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
|
||||
&skp->smk_host.sin_addr, &skp->smk_mask,
|
||||
PF_INET, &audit_info);
|
||||
/* we delete the unlabeled entry, only if the previous label
|
||||
* wasnt the special CIPSO option */
|
||||
if (skp->smk_label != smack_cipso_option)
|
||||
rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
|
||||
&skp->smk_host.sin_addr, &skp->smk_mask,
|
||||
PF_INET, &audit_info);
|
||||
else
|
||||
rc = 0;
|
||||
skp->smk_label = sp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now tell netlabel about the single label nature of
|
||||
* this host so that incoming packets get labeled.
|
||||
* but only if we didn't get the special CIPSO option
|
||||
*/
|
||||
|
||||
if (rc == 0)
|
||||
if (rc == 0 && sp != smack_cipso_option)
|
||||
rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
|
||||
&skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
|
||||
smack_to_secid(skp->smk_label), &audit_info);
|
||||
|
Reference in New Issue
Block a user