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:
Casey Schaufler
2023-12-11 10:56:53 -08:00
committed by Paolo Pisati
parent 3f8660dcc1
commit 1b0649d395
8 changed files with 34 additions and 7 deletions
+1
View File
@@ -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 */
};
/**
+5
View File
@@ -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;
+4 -3
View File
@@ -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);
+6
View File
@@ -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. */
+3 -1
View File
@@ -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
+5
View File
@@ -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.
*/
+2 -1
View File
@@ -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 = {
+8 -2
View File
@@ -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");