![Casey Schaufler](/assets/img/avatar_default.png)
Smack uses CIPSO to label internet packets and thus provide for access control on delivery of packets. The netfilter facility was not used to allow for Smack to work properly without netfilter configuration. Smack does not need netfilter, however there are cases where it would be handy. As a side effect, the labeling of local IPv4 packets can be optimized and the handling of local IPv6 packets is just all out better. The best part is that the netfilter tools use "contexts" that are just strings, and they work just as well for Smack as they do for SELinux. All of the conditional compilation for IPv6 was implemented by Rafal Krypa <r.krypa@samsung.com> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
97 lines
2.2 KiB
C
97 lines
2.2 KiB
C
/*
|
|
* Simplified MAC Kernel (smack) security module
|
|
*
|
|
* This file contains the Smack netfilter implementation
|
|
*
|
|
* Author:
|
|
* Casey Schaufler <casey@schaufler-ca.com>
|
|
*
|
|
* Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com>
|
|
* Copyright (C) 2014 Intel Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2,
|
|
* as published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/netfilter_ipv4.h>
|
|
#include <linux/netfilter_ipv6.h>
|
|
#include <linux/netdevice.h>
|
|
#include "smack.h"
|
|
|
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
|
|
static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops,
|
|
struct sk_buff *skb,
|
|
const struct net_device *in,
|
|
const struct net_device *out,
|
|
int (*okfn)(struct sk_buff *))
|
|
{
|
|
struct socket_smack *ssp;
|
|
struct smack_known *skp;
|
|
|
|
if (skb && skb->sk && skb->sk->sk_security) {
|
|
ssp = skb->sk->sk_security;
|
|
skp = ssp->smk_out;
|
|
skb->secmark = skp->smk_secid;
|
|
}
|
|
|
|
return NF_ACCEPT;
|
|
}
|
|
#endif /* IPV6 */
|
|
|
|
static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops,
|
|
struct sk_buff *skb,
|
|
const struct net_device *in,
|
|
const struct net_device *out,
|
|
int (*okfn)(struct sk_buff *))
|
|
{
|
|
struct socket_smack *ssp;
|
|
struct smack_known *skp;
|
|
|
|
if (skb && skb->sk && skb->sk->sk_security) {
|
|
ssp = skb->sk->sk_security;
|
|
skp = ssp->smk_out;
|
|
skb->secmark = skp->smk_secid;
|
|
}
|
|
|
|
return NF_ACCEPT;
|
|
}
|
|
|
|
static struct nf_hook_ops smack_nf_ops[] = {
|
|
{
|
|
.hook = smack_ipv4_output,
|
|
.owner = THIS_MODULE,
|
|
.pf = NFPROTO_IPV4,
|
|
.hooknum = NF_INET_LOCAL_OUT,
|
|
.priority = NF_IP_PRI_SELINUX_FIRST,
|
|
},
|
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
{
|
|
.hook = smack_ipv6_output,
|
|
.owner = THIS_MODULE,
|
|
.pf = NFPROTO_IPV6,
|
|
.hooknum = NF_INET_LOCAL_OUT,
|
|
.priority = NF_IP6_PRI_SELINUX_FIRST,
|
|
},
|
|
#endif /* IPV6 */
|
|
};
|
|
|
|
static int __init smack_nf_ip_init(void)
|
|
{
|
|
int err;
|
|
|
|
if (smack_enabled == 0)
|
|
return 0;
|
|
|
|
printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
|
|
|
|
err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
|
|
if (err)
|
|
pr_info("Smack: nf_register_hooks: error %d\n", err);
|
|
|
|
return 0;
|
|
}
|
|
|
|
__initcall(smack_nf_ip_init);
|