diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index fdeffa0c8d13..da60bf163447 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -84,6 +84,7 @@ struct lsm_blob_sizes { int lbs_xattr_count; /* number of xattr slots in new_xattrs array */ int lbs_mnt_opts; bool lbs_secmark; /* expressed desire for secmark use */ + bool lbs_netlabel; /* expressed desire for netlabel use */ }; /** diff --git a/security/security.c b/security/security.c index aaa7f62e9d46..17589f4d0759 100644 --- a/security/security.c +++ b/security/security.c @@ -243,6 +243,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) else needed->lbs_secmark = false; } + if (needed->lbs_netlabel) { + if (!blob_sizes.lbs_netlabel) + blob_sizes.lbs_netlabel = true; + else + needed->lbs_netlabel = false; + } } /* Prepare LSM for initialization. */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1dabf7eef33f..3f1001cd68cd 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -183,7 +183,7 @@ static int selinux_secmark_enabled(void) static int selinux_peerlbl_enabled(void) { return (selinux_policycap_alwaysnetwork() || - netlbl_enabled() || selinux_xfrm_enabled()); + selinux_netlbl_enabled() || selinux_xfrm_enabled()); } static int selinux_netcache_avc_callback(u32 event) @@ -5730,7 +5730,7 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb, SECCLASS_PACKET, PACKET__FORWARD_IN, &ad)) return NF_DROP; - if (netlbl_enabled()) + if (selinux_netlbl_enabled()) /* we do this in the FORWARD path and not the POST_ROUTING * path because we want to make sure we apply the necessary * labeling before IPsec is applied so we can leverage AH @@ -5747,7 +5747,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb, struct sock *sk; u32 sid; - if (!netlbl_enabled()) + if (!selinux_netlbl_enabled()) return NF_ACCEPT; /* we do this in the LOCAL_OUT path and not the POST_ROUTING path @@ -7021,6 +7021,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = { .lbs_xattr_count = SELINUX_INODE_INIT_XATTRS, .lbs_mnt_opts = sizeof(struct selinux_mnt_opts), .lbs_secmark = true, + .lbs_netlabel = true, }; #ifdef CONFIG_PERF_EVENTS diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 5731c0dcd3e8..5be82aa8e7ca 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -134,4 +134,9 @@ static inline int selinux_netlbl_socket_connect_locked(struct sock *sk, } #endif /* CONFIG_NETLABEL */ +static inline bool selinux_netlbl_enabled(void) +{ + return selinux_blob_sizes.lbs_netlabel && netlbl_enabled(); +} + #endif diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index e8832726bd86..1242296b5fe1 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -198,7 +198,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, int rc; struct netlbl_lsm_secattr secattr; - if (!netlbl_enabled()) { + if (!selinux_netlbl_enabled()) { *type = NETLBL_NLTYPE_NONE; *sid = SECSID_NULL; return 0; @@ -440,7 +440,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, u32 perm; struct netlbl_lsm_secattr secattr; - if (!netlbl_enabled()) + if (!selinux_netlbl_enabled()) return 0; netlbl_secattr_init(&secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index 85ec8141fe70..2191f8304e4f 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -367,6 +367,11 @@ static inline struct smack_known **smack_key(const struct key *key) } #endif /* CONFIG_KEYS */ +static inline bool smack_netlabel(void) +{ + return smack_blob_sizes.lbs_netlabel; +} + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index f53fac3137c3..cb730e6e53b9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2585,6 +2585,9 @@ static int smack_netlbl_add(struct sock *sk) struct smack_known *skp = ssp->smk_out; int rc; + if (!smack_netlabel()) + return 0; + local_bh_disable(); bh_lock_sock_nested(sk); @@ -2615,6 +2618,9 @@ static void smack_netlbl_delete(struct sock *sk) { struct socket_smack *ssp = smack_sock(sk); + if (!smack_netlabel()) + return; + /* * Take the label off the socket if one is set. */ @@ -2665,7 +2671,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap) /* * Clear the socket netlabel if it's set. */ - if (!rc) + if (!rc && smack_netlabel()) smack_netlbl_delete(sk); } rcu_read_unlock(); @@ -3971,6 +3977,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, int acat; int kcat; + if (!smack_netlabel()) + return smack_net_ambient; /* * Netlabel found it in the cache. */ @@ -4127,6 +4135,9 @@ static struct smack_known *smack_from_netlbl(const struct sock *sk, u16 family, struct socket_smack *ssp = NULL; struct smack_known *skp = NULL; + if (!smack_netlabel()) + return NULL; + netlbl_secattr_init(&secattr); if (sk) @@ -4197,7 +4208,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in, MAY_WRITE, rc); - if (rc != 0) + if (rc != 0 && smack_netlabel()) netlbl_skbuff_err(skb, family, rc, 0); break; #if IS_ENABLED(CONFIG_IPV6) @@ -4408,7 +4419,7 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb, if (skp == NULL) { skp = smack_from_netlbl(sk, family, skb); if (skp == NULL) - skp = &smack_known_huh; + skp = smack_net_ambient; } #ifdef CONFIG_AUDIT @@ -4429,8 +4440,11 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb, /* * Save the peer's label in the request_sock so we can later setup * smk_packet in the child socket so that SO_PEERCRED can report it. + * + * Only do this if Smack is using netlabel. */ - req->peer_secid = skp->smk_secid; + if (smack_netlabel()) + req->peer_secid = skp->smk_secid; /* * We need to decide if we want to label the incoming connection here @@ -4443,10 +4457,12 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb, hskp = smack_ipv4host_label(&addr); rcu_read_unlock(); - if (hskp == NULL) - rc = netlbl_req_setattr(req, &skp->smk_netlabel); - else - netlbl_req_delattr(req); + if (smack_netlabel()) { + if (hskp == NULL) + rc = netlbl_req_setattr(req, &skp->smk_netlabel); + else + netlbl_req_delattr(req); + } return rc; } @@ -4464,7 +4480,7 @@ static void smack_inet_csk_clone(struct sock *sk, struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp; - if (req->peer_secid != 0) { + if (smack_netlabel() && req->peer_secid != 0) { skp = smack_from_secid(req->peer_secid); ssp->smk_packet = skp; } else @@ -5063,6 +5079,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = { .lbs_xattr_count = SMACK_INODE_INIT_XATTRS, .lbs_mnt_opts = sizeof(struct smack_mnt_opts), .lbs_secmark = true, + .lbs_netlabel = true, }; static const struct lsm_id smack_lsmid = { diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 878fe44b662d..f8c0ea18b2fe 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -77,7 +77,7 @@ static DEFINE_MUTEX(smk_net6addr_lock); * If it isn't somehow marked, use this. * It can be reset via smackfs/ambient */ -struct smack_known *smack_net_ambient; +struct smack_known *smack_net_ambient = &smack_known_floor; /* * This is the level in a CIPSO header that indicates a @@ -685,6 +685,9 @@ static void smk_cipso_doi(void) struct cipso_v4_doi *doip; struct netlbl_audit nai; + if (!smack_netlabel()) + return; + smk_netlabel_audit_set(&nai); rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai); @@ -725,6 +728,9 @@ static void smk_unlbl_ambient(char *oldambient) int rc; struct netlbl_audit nai; + if (!smack_netlabel()) + return; + smk_netlabel_audit_set(&nai); if (oldambient != NULL) { @@ -848,6 +854,8 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, */ if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (*ppos != 0) return -EINVAL; if (format == SMK_FIXED24_FMT && @@ -1178,6 +1186,8 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, */ if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (*ppos != 0) return -EINVAL; if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) @@ -1437,6 +1447,8 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf, */ if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (*ppos != 0) return -EINVAL; if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) @@ -1608,6 +1620,8 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (count >= sizeof(temp) || count == 0) return -EINVAL; @@ -1675,6 +1689,8 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (count >= sizeof(temp) || count == 0) return -EINVAL; @@ -1753,6 +1769,8 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; + if (!smack_netlabel()) + return -EINVAL; if (count >= sizeof(temp) || count == 0) return -EINVAL;