On Fri, 20 Jul 2001, Chris Vance wrote: > > To that end, we are going to see what we can do with the netfilter code > rather than directly modifying the ip input/ouput > routines or modifying the sk_buff structure (which apparently would be > difficult to gain approval for). > Hi Chris, folks, Attached below is an initial patch which use Netfilter to implement access & audit hooks for IP-layer networking. It consists of a "glue" module which grabs every Netfilter hook twice, before and after packets are passed through the standard iptables-based packet filtering and mangling mechanisms. (This is probably overkill, but it's difficult to know exactly which hooks and priorities implementations will want to use. If needed, the code can be modified to accept parameters specifying which hooks and priorities to grab). Once the packets have been hooked by Netfilter, they are passed to LSM as ip_ops calls. These calls correspond to IPv4 packets which pass through the following paths in the stack: pre-routing local input (to user process) forwarding local output (from user process) post-routing Note that I've included Keith Owen's softirq bugfix for the 2.4.6-pre4/3 kernels, which is needed for Netfilter applications and some other networking components. As far as I can see, the this patch will allow at least the selinux code to do what it needs to do at the IP layer. Some further hooks may be required (not using Netfilter) to implement more capabilities calls, but the real purpose of this code is to have something for discussion. At this stage, it will probably only work as a module, and you need Netfilter enabled in the kernel configuration before it appears as an option in the Security menu. - James -- James Morris <jmorrisat_private> diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/include/asm-i386/softirq.h lsm-w3/include/asm-i386/softirq.h --- lsm/include/asm-i386/softirq.h Fri Jun 29 23:18:16 2001 +++ lsm-w3/include/asm-i386/softirq.h Sun Jul 22 02:54:12 2001 @@ -36,13 +36,13 @@ \ ".section .text.lock,\"ax\";" \ "2: pushl %%eax; pushl %%ecx; pushl %%edx;" \ - "call do_softirq;" \ + "call %c1;" \ "popl %%edx; popl %%ecx; popl %%eax;" \ "jmp 1b;" \ ".previous;" \ \ : /* no output */ \ - : "r" (ptr) \ + : "r" (ptr), "i" (do_softirq) \ /* no registers clobbered */ ); \ } while (0) diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/include/linux/security.h lsm-w3/include/linux/security.h --- lsm/include/linux/security.h Sat Jul 21 15:07:21 2001 +++ lsm-w3/include/linux/security.h Sun Jul 22 02:54:12 2001 @@ -124,6 +124,24 @@ struct socket_security_ops { }; +struct sk_buff; +struct net_device; +typedef unsigned int (*ip_opfn)(unsigned int hooknum, struct sk_buff **skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)); +struct ip_security_ops { + ip_opfn preroute_first; + ip_opfn preroute_last; + ip_opfn input_first; + ip_opfn input_last; + ip_opfn forward_first; + ip_opfn forward_last; + ip_opfn output_first; + ip_opfn output_last; + ip_opfn postroute_first; + ip_opfn postroute_last; +}; + struct module_security_ops { int (* create_module) (const char *name_user, size_t size); int (* init_module) (const char *name_user, struct module *mod_user); @@ -197,6 +215,7 @@ struct file_security_ops * file_ops; struct task_security_ops * task_ops; struct socket_security_ops * socket_ops; + struct ip_security_ops * ip_ops; struct module_security_ops * module_ops; struct ipc_security_ops * ipc_ops; struct msg_msg_security_ops * msg_msg_ops; diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/kernel/Makefile lsm-w3/kernel/Makefile --- lsm/kernel/Makefile Thu Jun 28 04:01:57 2001 +++ lsm-w3/kernel/Makefile Sun Jul 22 00:47:12 2001 @@ -22,6 +22,8 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CAPABILITIES) += capability_plug.o +obj-$(CONFIG_LSM_IP) += ip_lsm_glue.o + ifneq ($(CONFIG_IA64),y) # According to Alan Modra <alanat_private>, the -fno-omit-frame-pointer is # needed for x86 only. Why this used to be enabled for all architectures is beyond diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/kernel/capability_plug.c lsm-w3/kernel/capability_plug.c --- lsm/kernel/capability_plug.c Sat Jul 21 15:07:21 2001 +++ lsm-w3/kernel/capability_plug.c Sun Jul 22 02:43:08 2001 @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/smp_lock.h> #include <asm/uaccess.h> +#include <linux/netfilter.h> /* flag to keep track of how we were registered */ static int secondary; @@ -295,6 +296,37 @@ return; } +static unsigned int cap_ip_preroute_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_preroute_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_input_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_input_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_forward_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_forward_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_output_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_output_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_postroute_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int cap_ip_postroute_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} + static int cap_module_create_module (const char *name_user, size_t size) {return 0;} static int cap_module_init_module (const char *name_user, struct module *mod_user) {return 0;} static int cap_module_delete_module (const char *name_user) {return 0;} @@ -404,6 +436,19 @@ static struct socket_security_ops cap_socket_ops = {}; +static struct ip_security_ops cap_ip_ops = { + preroute_first: cap_ip_preroute_first, + preroute_last: cap_ip_preroute_last, + input_first: cap_ip_input_first, + input_last: cap_ip_input_last, + forward_first: cap_ip_forward_first, + forward_last: cap_ip_forward_last, + output_first: cap_ip_output_first, + output_last: cap_ip_output_last, + postroute_first: cap_ip_postroute_first, + postroute_last: cap_ip_postroute_last, +}; + static struct module_security_ops cap_module_ops = { create_module: cap_module_create_module, init_module: cap_module_init_module, @@ -475,6 +520,7 @@ file_ops: &cap_file_ops, task_ops: &cap_task_ops, socket_ops: &cap_socket_ops, + ip_ops: &cap_ip_ops, module_ops: &cap_module_ops, ipc_ops: &cap_ipc_ops, msg_msg_ops: &cap_msg_ops, diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/kernel/ip_lsm_glue.c lsm-w3/kernel/ip_lsm_glue.c --- lsm/kernel/ip_lsm_glue.c Thu Jan 1 10:00:00 1970 +++ lsm-w3/kernel/ip_lsm_glue.c Sun Jul 22 02:50:12 2001 @@ -0,0 +1,152 @@ +/* + * Nefilter IPv4 Operations Glue Module for LSM + * + * Copyright (c) 2001 James Morris <jmorrisat_private> + * This code is GPL. + * + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/security.h> +#include <linux/netfilter.h> +#include <linux/netfilter_ipv4.h> + +#define NF_IP_PRI_LSM_FIRST (NF_IP_PRI_FIRST + 20) +#define NF_IP_PRI_LSM_LAST (NF_IP_PRI_LAST - 20) + +static unsigned int +preroute_first(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->preroute_first(hooknum, pskb, in, out, okfn); +} + +static unsigned int +preroute_last(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->preroute_last(hooknum, pskb, in, out, okfn); +} + +static unsigned int +input_first(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->input_first(hooknum, pskb, in, out, okfn); +} + +static unsigned int +input_last(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->input_last(hooknum, pskb, in, out, okfn); +} + +static unsigned int +forward_first(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->forward_first(hooknum, pskb, in, out, okfn); +} + +static unsigned int +forward_last(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->forward_last(hooknum, pskb, in, out, okfn); +} + +static unsigned int +output_first(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->output_first(hooknum, pskb, in, out, okfn); +} + +static unsigned int +output_last(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->output_last(hooknum, pskb, in, out, okfn); +} + +static unsigned int +postroute_first(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->postroute_first(hooknum, pskb, in, out, okfn); +} + +static unsigned int +postroute_last(unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return security_ops->ip_ops->postroute_last(hooknum, pskb, in, out, okfn); +} + +static struct nf_hook_ops lsm_ip_ops[] = { + { { NULL, NULL }, preroute_first, + PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_LSM_FIRST }, + + { { NULL, NULL }, preroute_last, + PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_LSM_LAST }, + + { { NULL, NULL }, input_first, + PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_LSM_FIRST }, + + { { NULL, NULL }, input_last, + PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_LSM_LAST }, + + { { NULL, NULL }, forward_first, + PF_INET, NF_IP_FORWARD, NF_IP_PRI_LSM_FIRST }, + + { { NULL, NULL }, forward_last, + PF_INET, NF_IP_FORWARD, NF_IP_PRI_LSM_LAST }, + + { { NULL, NULL }, output_first, + PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_LSM_FIRST }, + + { { NULL, NULL }, output_last, + PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_LSM_LAST }, + + { { NULL, NULL }, postroute_first, + PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_LSM_FIRST }, + + { { NULL, NULL }, postroute_last, + PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_LSM_LAST } +}; + +static int __init init(void) +{ + int i; + + /* Hook registration never returns error (for now) */ + for (i = 0; i < sizeof(lsm_ip_ops)/sizeof(struct nf_hook_ops); i++) + nf_register_hook(&lsm_ip_ops[i]); + + return 0; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(lsm_ip_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&lsm_ip_ops[i]); +} + +module_init(init); +module_exit(fini); + +MODULE_DESCRIPTION("Nefilter IPv4 Operations Glue for Linux Security Module"); + diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/kernel/security.c lsm-w3/kernel/security.c --- lsm/kernel/security.c Sat Jul 21 15:07:21 2001 +++ lsm-w3/kernel/security.c Sun Jul 22 02:37:05 2001 @@ -30,7 +30,7 @@ #include <linux/module.h> #include <linux/sysctl.h> - +#include <linux/netfilter.h> @@ -132,6 +132,39 @@ static void dummy_task_kmod_set_label (void) {return;} + +static unsigned int dummy_ip_preroute_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_preroute_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_input_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_input_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_forward_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_forward_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_output_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_output_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_postroute_first (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} +static unsigned int dummy_ip_postroute_last (unsigned int hooknum, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) {return NF_ACCEPT;} + + static int dummy_module_create_module (const char *name_user, size_t size) {return 0;} static int dummy_module_init_module (const char *name_user, struct module *mod_user) {return 0;} static int dummy_module_delete_module (const char *name_user) {return 0;} @@ -239,6 +272,19 @@ static struct socket_security_ops dummy_socket_ops = {}; +static struct ip_security_ops dummy_ip_ops = { + preroute_first: dummy_ip_preroute_first, + preroute_last: dummy_ip_preroute_last, + input_first: dummy_ip_input_first, + input_last: dummy_ip_input_last, + forward_first: dummy_ip_forward_first, + forward_last: dummy_ip_forward_last, + output_first: dummy_ip_output_first, + output_last: dummy_ip_output_last, + postroute_first: dummy_ip_postroute_first, + postroute_last: dummy_ip_postroute_last, +}; + static struct module_security_ops dummy_module_ops = { create_module: dummy_module_create_module, init_module: dummy_module_init_module, @@ -310,6 +356,7 @@ file_ops: &dummy_file_ops, task_ops: &dummy_task_ops, socket_ops: &dummy_socket_ops, + ip_ops: &dummy_ip_ops, ipc_ops: &dummy_ipc_ops, module_ops: &dummy_module_ops, msg_msg_ops: &dummy_msg_msg_ops, @@ -380,6 +427,7 @@ !ops->file_ops || !ops->task_ops || !ops->socket_ops || + !ops->ip_ops || !ops->module_ops || !ops->ipc_ops || !ops->msg_msg_ops || diff -urN --exclude SCCS --exclude BitKeeper --exclude ChangeSet lsm/security/Config.in lsm-w3/security/Config.in --- lsm/security/Config.in Thu Jul 5 15:28:18 2001 +++ lsm-w3/security/Config.in Sun Jul 22 00:17:51 2001 @@ -4,5 +4,5 @@ mainmenu_option next_comment comment 'Security options' tristate 'Capabilities Support' CONFIG_CAPABILITIES - +dep_tristate 'IP Networking Support' CONFIG_LSM_IP $CONFIG_NETFILTER endmenu _______________________________________________ linux-security-module mailing list linux-security-moduleat_private http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Sat Jul 21 2001 - 10:29:59 PDT