UBUNTU: SAUCE: apparmor4.0.0 [31/90]: LSM stacking v39: LSM: Exclusive secmark usage
BugLink: http://bugs.launchpad.net/bugs/2028253 The network secmark can only be used by one security module at a time. Establish mechanism to identify to security modules whether they have access to the secmark. SELinux already incorparates mechanism, but it has to be added to Smack and AppArmor. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> (cherry picked from commit c0c9497b3b4153c7cea3e7dec321996b24b96c04 https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
committed by
Paolo Pisati
parent
3f8660dcc1
commit
1b0649d395
@@ -81,6 +81,7 @@ struct lsm_blob_sizes {
|
||||
int lbs_msg_msg;
|
||||
int lbs_task;
|
||||
int lbs_xattr_count; /* number of xattr slots in new_xattrs array */
|
||||
bool lbs_secmark; /* expressed desire for secmark use */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,11 @@ struct aa_sk_ctx {
|
||||
struct aa_label *peer;
|
||||
};
|
||||
|
||||
static inline bool aa_secmark(void)
|
||||
{
|
||||
return apparmor_blob_sizes.lbs_secmark;
|
||||
}
|
||||
|
||||
static inline struct aa_sk_ctx *aa_sock(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_security + apparmor_blob_sizes.lbs_sock;
|
||||
|
||||
@@ -1296,7 +1296,7 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct aa_sk_ctx *ctx = aa_sock(sk);
|
||||
|
||||
if (!skb->secmark)
|
||||
if (!aa_secmark() || !skb->secmark)
|
||||
return 0;
|
||||
|
||||
return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE,
|
||||
@@ -1405,7 +1405,7 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb
|
||||
{
|
||||
struct aa_sk_ctx *ctx = aa_sock(sk);
|
||||
|
||||
if (!skb->secmark)
|
||||
if (!aa_secmark() || !skb->secmark)
|
||||
return 0;
|
||||
|
||||
return apparmor_secmark_check(ctx->label, OP_CONNECT, AA_MAY_CONNECT,
|
||||
@@ -1421,6 +1421,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = {
|
||||
.lbs_file = sizeof(struct aa_file_ctx),
|
||||
.lbs_task = sizeof(struct aa_task_ctx),
|
||||
.lbs_sock = sizeof(struct aa_sk_ctx),
|
||||
.lbs_secmark = true,
|
||||
};
|
||||
|
||||
static const struct lsm_id apparmor_lsmid = {
|
||||
@@ -2084,7 +2085,7 @@ static unsigned int apparmor_ip_postroute(void *priv,
|
||||
struct aa_sk_ctx *ctx;
|
||||
struct sock *sk;
|
||||
|
||||
if (!skb->secmark)
|
||||
if (!aa_secmark() || !skb->secmark)
|
||||
return NF_ACCEPT;
|
||||
|
||||
sk = skb_to_full_sk(skb);
|
||||
|
||||
@@ -233,6 +233,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
|
||||
lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
|
||||
lsm_set_blob_size(&needed->lbs_xattr_count,
|
||||
&blob_sizes.lbs_xattr_count);
|
||||
if (needed->lbs_secmark) {
|
||||
if (!blob_sizes.lbs_secmark)
|
||||
blob_sizes.lbs_secmark = true;
|
||||
else
|
||||
needed->lbs_secmark = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare LSM for initialization. */
|
||||
|
||||
@@ -165,7 +165,8 @@ __setup("checkreqprot=", checkreqprot_setup);
|
||||
*/
|
||||
static int selinux_secmark_enabled(void)
|
||||
{
|
||||
return (selinux_policycap_alwaysnetwork() ||
|
||||
return selinux_blob_sizes.lbs_secmark &&
|
||||
(selinux_policycap_alwaysnetwork() ||
|
||||
atomic_read(&selinux_secmark_refcount));
|
||||
}
|
||||
|
||||
@@ -7025,6 +7026,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
|
||||
.lbs_sock = sizeof(struct sk_security_struct),
|
||||
.lbs_superblock = sizeof(struct superblock_security_struct),
|
||||
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
|
||||
.lbs_secmark = true,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
|
||||
@@ -369,6 +369,11 @@ static inline int smk_inode_transmutable(const struct inode *isp)
|
||||
return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
|
||||
}
|
||||
|
||||
static inline bool smack_secmark(void)
|
||||
{
|
||||
return smack_blob_sizes.lbs_secmark;
|
||||
}
|
||||
|
||||
/*
|
||||
* Present a pointer to the smack label entry in an inode blob.
|
||||
*/
|
||||
|
||||
@@ -4091,7 +4091,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
|
||||
#ifdef CONFIG_NETWORK_SECMARK
|
||||
static struct smack_known *smack_from_skb(struct sk_buff *skb)
|
||||
{
|
||||
if (skb == NULL || skb->secmark == 0)
|
||||
if (!smack_secmark() || skb == NULL || skb->secmark == 0)
|
||||
return NULL;
|
||||
|
||||
return smack_from_secid(skb->secmark);
|
||||
@@ -5065,6 +5065,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
|
||||
.lbs_sock = sizeof(struct socket_smack),
|
||||
.lbs_superblock = sizeof(struct superblock_smack),
|
||||
.lbs_xattr_count = SMACK_INODE_INIT_XATTRS,
|
||||
.lbs_secmark = true,
|
||||
};
|
||||
|
||||
static const struct lsm_id smack_lsmid = {
|
||||
|
||||
@@ -26,7 +26,7 @@ static unsigned int smack_ip_output(void *priv,
|
||||
struct socket_smack *ssp;
|
||||
struct smack_known *skp;
|
||||
|
||||
if (sk) {
|
||||
if (smack_secmark() && sk) {
|
||||
ssp = smack_sock(sk);
|
||||
skp = ssp->smk_out;
|
||||
skb->secmark = skp->smk_secid;
|
||||
@@ -54,12 +54,18 @@ static const struct nf_hook_ops smack_nf_ops[] = {
|
||||
|
||||
static int __net_init smack_nf_register(struct net *net)
|
||||
{
|
||||
if (!smack_secmark())
|
||||
return 0;
|
||||
|
||||
return nf_register_net_hooks(net, smack_nf_ops,
|
||||
ARRAY_SIZE(smack_nf_ops));
|
||||
}
|
||||
|
||||
static void __net_exit smack_nf_unregister(struct net *net)
|
||||
{
|
||||
if (!smack_secmark())
|
||||
return;
|
||||
|
||||
nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
|
||||
}
|
||||
|
||||
@@ -70,7 +76,7 @@ static struct pernet_operations smack_net_ops = {
|
||||
|
||||
static int __init smack_nf_ip_init(void)
|
||||
{
|
||||
if (smack_enabled == 0)
|
||||
if (smack_enabled == 0 || !smack_secmark())
|
||||
return 0;
|
||||
|
||||
printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
|
||||
|
||||
Reference in New Issue
Block a user