@@ -553,4 +553,19 @@ static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
}
#endif
+#ifdef CONFIG_SECURITY_SMACK_NETFILTER
+extern bool smack_use_secmark;
+void smack_secmark_refcount_inc(void);
+
+static inline bool smk_use_secmark(void)
+{
+ return smack_use_secmark;
+}
+#else
+static inline bool smk_use_secmark(void)
+{
+ return false;
+}
+#endif
+
#endif /* _SECURITY_SMACK_H */
@@ -3742,7 +3742,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
*/
static struct smack_known *smack_from_skb(struct sk_buff *skb)
{
- if (skb == NULL || skb->secmark == 0)
+ if (skb == NULL || skb->secmark == 0 || !smk_use_secmark())
return NULL;
return smack_from_secid(skb->secmark);
@@ -3776,7 +3776,6 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
switch (family) {
case PF_INET:
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
/*
* If there is a secmark use it rather than the CIPSO label.
* If there is no secmark fall back to CIPSO.
@@ -3785,7 +3784,6 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
skp = smack_from_skb(skb);
if (skp)
goto access_check;
-#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
/*
* Translate what netlabel gave us.
*/
@@ -3799,9 +3797,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
netlbl_secattr_destroy(&secattr);
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
access_check:
-#endif
+
#ifdef CONFIG_AUDIT
smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net->family = family;
@@ -3928,13 +3925,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
s = ssp->smk_out->smk_secid;
break;
case PF_INET:
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
skp = smack_from_skb(skb);
if (skp) {
s = skp->smk_secid;
break;
}
-#endif
/*
* Translate what netlabel gave us.
*/
@@ -4024,7 +4019,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
}
#endif /* CONFIG_IPV6 */
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
/*
* If there is a secmark use it rather than the CIPSO label.
* If there is no secmark fall back to CIPSO.
@@ -4033,7 +4027,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
skp = smack_from_skb(skb);
if (skp)
goto access_check;
-#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
netlbl_secattr_init(&secattr);
rc = netlbl_skbuff_getattr(skb, family, &secattr);
@@ -4043,9 +4036,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
skp = &smack_known_huh;
netlbl_secattr_destroy(&secattr);
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
access_check:
-#endif
#ifdef CONFIG_AUDIT
smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
@@ -4620,6 +4611,9 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
#ifdef SMACK_IPV6_PORT_LABELING
LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
+#endif
+#ifdef CONFIG_SECURITY_SMACK_NETFILTER
+ LSM_HOOK_INIT(secmark_refcount_inc, smack_secmark_refcount_inc),
#endif
LSM_HOOK_INIT(sock_graft, smack_sock_graft),
LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
@@ -21,6 +21,15 @@
#include <net/net_namespace.h>
#include "smack.h"
+bool smack_use_secmark;
+static bool smack_checked_secmark;
+
+void smack_secmark_refcount_inc(void)
+{
+ smack_use_secmark = true;
+ pr_info("Smack: Using network secmarks.\n");
+}
+
#if IS_ENABLED(CONFIG_IPV6)
static unsigned int smack_ipv6_output(void *priv,
@@ -31,7 +40,13 @@ static unsigned int smack_ipv6_output(void *priv,
struct socket_smack *ssp;
struct smack_known *skp;
- if (sk && smack_sock(sk)) {
+ if (!smack_checked_secmark) {
+ security_secmark_refcount_inc();
+ security_secmark_refcount_dec();
+ smack_checked_secmark = true;
+ }
+
+ if (smack_use_secmark && sk && smack_sock(sk)) {
ssp = smack_sock(sk);
skp = ssp->smk_out;
skb->secmark = skp->smk_secid;
@@ -49,7 +64,13 @@ static unsigned int smack_ipv4_output(void *priv,
struct socket_smack *ssp;
struct smack_known *skp;
- if (sk && smack_sock(sk)) {
+ if (!smack_checked_secmark) {
+ security_secmark_refcount_inc();
+ security_secmark_refcount_dec();
+ smack_checked_secmark = true;
+ }
+
+ if (smack_use_secmark && sk && smack_sock(sk)) {
ssp = smack_sock(sk);
skp = ssp->smk_out;
skb->secmark = skp->smk_secid;