1/*
2 *  Simplified MAC Kernel (smack) security module
3 *
4 *  This file contains the Smack netfilter implementation
5 *
6 *  Author:
7 *	Casey Schaufler <casey@schaufler-ca.com>
8 *
9 *  Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com>
10 *  Copyright (C) 2014 Intel Corporation.
11 *
12 *	This program is free software; you can redistribute it and/or modify
13 *	it under the terms of the GNU General Public License version 2,
14 *	as published by the Free Software Foundation.
15 */
16
17#include <linux/netfilter_ipv4.h>
18#include <linux/netfilter_ipv6.h>
19#include <linux/netdevice.h>
20#include "smack.h"
21
22#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
23
24static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops,
25					struct sk_buff *skb,
26					const struct nf_hook_state *state)
27{
28	struct socket_smack *ssp;
29	struct smack_known *skp;
30
31	if (skb && skb->sk && skb->sk->sk_security) {
32		ssp = skb->sk->sk_security;
33		skp = ssp->smk_out;
34		skb->secmark = skp->smk_secid;
35	}
36
37	return NF_ACCEPT;
38}
39#endif	/* IPV6 */
40
41static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops,
42					struct sk_buff *skb,
43					const struct nf_hook_state *state)
44{
45	struct socket_smack *ssp;
46	struct smack_known *skp;
47
48	if (skb && skb->sk && skb->sk->sk_security) {
49		ssp = skb->sk->sk_security;
50		skp = ssp->smk_out;
51		skb->secmark = skp->smk_secid;
52	}
53
54	return NF_ACCEPT;
55}
56
57static struct nf_hook_ops smack_nf_ops[] = {
58	{
59		.hook =		smack_ipv4_output,
60		.owner =	THIS_MODULE,
61		.pf =		NFPROTO_IPV4,
62		.hooknum =	NF_INET_LOCAL_OUT,
63		.priority =	NF_IP_PRI_SELINUX_FIRST,
64	},
65#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
66	{
67		.hook =		smack_ipv6_output,
68		.owner =	THIS_MODULE,
69		.pf =		NFPROTO_IPV6,
70		.hooknum =	NF_INET_LOCAL_OUT,
71		.priority =	NF_IP6_PRI_SELINUX_FIRST,
72	},
73#endif	/* IPV6 */
74};
75
76static int __init smack_nf_ip_init(void)
77{
78	int err;
79
80	if (smack_enabled == 0)
81		return 0;
82
83	printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
84
85	err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
86	if (err)
87		pr_info("Smack: nf_register_hooks: error %d\n", err);
88
89	return 0;
90}
91
92__initcall(smack_nf_ip_init);
93