diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 605aaf38c3f5..4deb1a4d2d1a 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -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 */ }; /** diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h index c42ed8a73f1c..2e43e1e8303c 100644 --- a/security/apparmor/include/net.h +++ b/security/apparmor/include/net.h @@ -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; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index e62a00d198e0..748e8cca495f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -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); diff --git a/security/security.c b/security/security.c index b0e08573257f..1d50b59ee656 100644 --- a/security/security.c +++ b/security/security.c @@ -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. */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a7e2e9a9a744..334a6b79753a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -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 diff --git a/security/smack/smack.h b/security/smack/smack.h index 297f21446f45..0f5bc5c03b9e 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -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. */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 220fda8ea101..51bfb3a656a0 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -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 = { diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index bad71b7e648d..fd146e3a2286 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -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");