0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/netfilter_ipv4.h>
0015 #include <linux/netfilter_ipv6.h>
0016 #include <linux/netdevice.h>
0017 #include <net/inet_sock.h>
0018 #include <net/net_namespace.h>
0019 #include "smack.h"
0020
0021 static unsigned int smack_ip_output(void *priv,
0022 struct sk_buff *skb,
0023 const struct nf_hook_state *state)
0024 {
0025 struct sock *sk = skb_to_full_sk(skb);
0026 struct socket_smack *ssp;
0027 struct smack_known *skp;
0028
0029 if (sk && sk->sk_security) {
0030 ssp = sk->sk_security;
0031 skp = ssp->smk_out;
0032 skb->secmark = skp->smk_secid;
0033 }
0034
0035 return NF_ACCEPT;
0036 }
0037
0038 static const struct nf_hook_ops smack_nf_ops[] = {
0039 {
0040 .hook = smack_ip_output,
0041 .pf = NFPROTO_IPV4,
0042 .hooknum = NF_INET_LOCAL_OUT,
0043 .priority = NF_IP_PRI_SELINUX_FIRST,
0044 },
0045 #if IS_ENABLED(CONFIG_IPV6)
0046 {
0047 .hook = smack_ip_output,
0048 .pf = NFPROTO_IPV6,
0049 .hooknum = NF_INET_LOCAL_OUT,
0050 .priority = NF_IP6_PRI_SELINUX_FIRST,
0051 },
0052 #endif
0053 };
0054
0055 static int __net_init smack_nf_register(struct net *net)
0056 {
0057 return nf_register_net_hooks(net, smack_nf_ops,
0058 ARRAY_SIZE(smack_nf_ops));
0059 }
0060
0061 static void __net_exit smack_nf_unregister(struct net *net)
0062 {
0063 nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
0064 }
0065
0066 static struct pernet_operations smack_net_ops = {
0067 .init = smack_nf_register,
0068 .exit = smack_nf_unregister,
0069 };
0070
0071 static int __init smack_nf_ip_init(void)
0072 {
0073 if (smack_enabled == 0)
0074 return 0;
0075
0076 printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
0077 return register_pernet_subsys(&smack_net_ops);
0078 }
0079
0080 __initcall(smack_nf_ip_init);