1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
269f287aeSCasey Schaufler /*
369f287aeSCasey Schaufler * Simplified MAC Kernel (smack) security module
469f287aeSCasey Schaufler *
569f287aeSCasey Schaufler * This file contains the Smack netfilter implementation
669f287aeSCasey Schaufler *
769f287aeSCasey Schaufler * Author:
869f287aeSCasey Schaufler * Casey Schaufler <casey@schaufler-ca.com>
969f287aeSCasey Schaufler *
1069f287aeSCasey Schaufler * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com>
1169f287aeSCasey Schaufler * Copyright (C) 2014 Intel Corporation.
1269f287aeSCasey Schaufler */
1369f287aeSCasey Schaufler
1469f287aeSCasey Schaufler #include <linux/netfilter_ipv4.h>
1569f287aeSCasey Schaufler #include <linux/netfilter_ipv6.h>
1669f287aeSCasey Schaufler #include <linux/netdevice.h>
178827d90eSEric Dumazet #include <net/inet_sock.h>
18e661a582SFlorian Westphal #include <net/net_namespace.h>
1969f287aeSCasey Schaufler #include "smack.h"
2069f287aeSCasey Schaufler
smack_ip_output(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)21*f8de49efSFlorian Westphal static unsigned int smack_ip_output(void *priv,
2269f287aeSCasey Schaufler struct sk_buff *skb,
23238e54c9SDavid S. Miller const struct nf_hook_state *state)
2469f287aeSCasey Schaufler {
258827d90eSEric Dumazet struct sock *sk = skb_to_full_sk(skb);
2669f287aeSCasey Schaufler struct socket_smack *ssp;
2769f287aeSCasey Schaufler struct smack_known *skp;
2869f287aeSCasey Schaufler
298827d90eSEric Dumazet if (sk && sk->sk_security) {
308827d90eSEric Dumazet ssp = sk->sk_security;
3169f287aeSCasey Schaufler skp = ssp->smk_out;
3269f287aeSCasey Schaufler skb->secmark = skp->smk_secid;
3369f287aeSCasey Schaufler }
3469f287aeSCasey Schaufler
3569f287aeSCasey Schaufler return NF_ACCEPT;
3669f287aeSCasey Schaufler }
3769f287aeSCasey Schaufler
38591bb278SFlorian Westphal static const struct nf_hook_ops smack_nf_ops[] = {
3969f287aeSCasey Schaufler {
40*f8de49efSFlorian Westphal .hook = smack_ip_output,
4169f287aeSCasey Schaufler .pf = NFPROTO_IPV4,
4269f287aeSCasey Schaufler .hooknum = NF_INET_LOCAL_OUT,
4369f287aeSCasey Schaufler .priority = NF_IP_PRI_SELINUX_FIRST,
4469f287aeSCasey Schaufler },
451a93a6eaSJavier Martinez Canillas #if IS_ENABLED(CONFIG_IPV6)
4669f287aeSCasey Schaufler {
47*f8de49efSFlorian Westphal .hook = smack_ip_output,
4869f287aeSCasey Schaufler .pf = NFPROTO_IPV6,
4969f287aeSCasey Schaufler .hooknum = NF_INET_LOCAL_OUT,
5069f287aeSCasey Schaufler .priority = NF_IP6_PRI_SELINUX_FIRST,
5169f287aeSCasey Schaufler },
5269f287aeSCasey Schaufler #endif /* IPV6 */
5369f287aeSCasey Schaufler };
5469f287aeSCasey Schaufler
smack_nf_register(struct net * net)55e661a582SFlorian Westphal static int __net_init smack_nf_register(struct net *net)
56e661a582SFlorian Westphal {
57e661a582SFlorian Westphal return nf_register_net_hooks(net, smack_nf_ops,
58e661a582SFlorian Westphal ARRAY_SIZE(smack_nf_ops));
59e661a582SFlorian Westphal }
60e661a582SFlorian Westphal
smack_nf_unregister(struct net * net)61e661a582SFlorian Westphal static void __net_exit smack_nf_unregister(struct net *net)
62e661a582SFlorian Westphal {
63e661a582SFlorian Westphal nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
64e661a582SFlorian Westphal }
65e661a582SFlorian Westphal
66e661a582SFlorian Westphal static struct pernet_operations smack_net_ops = {
67e661a582SFlorian Westphal .init = smack_nf_register,
68e661a582SFlorian Westphal .exit = smack_nf_unregister,
69e661a582SFlorian Westphal };
70e661a582SFlorian Westphal
smack_nf_ip_init(void)7169f287aeSCasey Schaufler static int __init smack_nf_ip_init(void)
7269f287aeSCasey Schaufler {
7369f287aeSCasey Schaufler if (smack_enabled == 0)
7469f287aeSCasey Schaufler return 0;
7569f287aeSCasey Schaufler
7669f287aeSCasey Schaufler printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
77e661a582SFlorian Westphal return register_pernet_subsys(&smack_net_ops);
7869f287aeSCasey Schaufler }
7969f287aeSCasey Schaufler
8069f287aeSCasey Schaufler __initcall(smack_nf_ip_init);
81