From: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
To: linux-kernel@vger.kernel.org
Subject: [PATCH 2.6 NETFILTER] new netfilter module ipt_program.c
Date: Sat, 11 Sep 2004 13:41:06 +0100 [thread overview]
Message-ID: <20040911124106.GD24787@lkcl.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 969 bytes --]
decided to put this into a separate module. based on ipt_owner.c.
does full program's pathname. like ipt_owner, only suitable for
outgoing connections.
userspace-netfilter-patch sent to bugs.debian.org (270852).
as was kindly pointed out already, dealing with per-program
per-packet filtering is at least O(N*M) and some cacheing
would help.
... but it's better than O(N*M*L) in userspace (in fireflier's
present ip_queueing userspace code).
issue of where new function proc_task_dentry_lookup() should
go is still outstanding and i don't have the knowledge or authority
to say or even advise most appropriate location.
l.
--
--
Truth, honesty and respect are rare commodities that all spring from
the same well: Love. If you love yourself and everyone and everything
around you, funnily and coincidentally enough, life gets a lot better.
--
<a href="http://lkcl.net"> lkcl.net </a> <br />
<a href="mailto:lkcl@lkcl.net"> lkcl@lkcl.net </a> <br />
[-- Attachment #2: f --]
[-- Type: text/plain, Size: 1570 bytes --]
Index: net/ipv4/netfilter/Kconfig
===================================================================
RCS file: /cvsroot/selinux/nsa/linux-2.6/net/ipv4/netfilter/Kconfig,v
retrieving revision 1.1.1.7
diff -u -u -r1.1.1.7 Kconfig
--- net/ipv4/netfilter/Kconfig 13 May 2004 18:03:22 -0000 1.1.1.7
+++ net/ipv4/netfilter/Kconfig 11 Sep 2004 12:17:53 -0000
@@ -256,6 +256,15 @@
To compile it as a module, choose M here. If unsure, say N.
+config IP_NF_MATCH_PROGRAM
+ tristate "Full program pathname match support"
+ depends on IP_NF_IPTABLES
+ help
+ Packet program name matching allows you to match locally-generated packets
+ based on the full path name of the program that generated them.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config IP_NF_MATCH_OWNER
tristate "Owner match support"
depends on IP_NF_IPTABLES
Index: net/ipv4/netfilter/Makefile
===================================================================
RCS file: /cvsroot/selinux/nsa/linux-2.6/net/ipv4/netfilter/Makefile,v
retrieving revision 1.1.1.3
diff -u -u -r1.1.1.3 Makefile
--- net/ipv4/netfilter/Makefile 13 May 2004 18:03:22 -0000 1.1.1.3
+++ net/ipv4/netfilter/Makefile 11 Sep 2004 12:17:53 -0000
@@ -50,6 +50,7 @@
obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
+obj-$(CONFIG_IP_NF_MATCH_PROGRAM) += ipt_program.o
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
Index: security/selinux/hooks.c
[-- Attachment #3: ipt_program.h --]
[-- Type: text/x-chdr, Size: 572 bytes --]
#ifndef _IPT_PROGRAM_H
#define _IPT_PROGRAM_H
/* lkcl: whilst most people would care about path names being their
* full length; whilst some people would want code that allocated
* the program name in a dynamic size buffer, i don't give a stuff:
* i just need something that works, and 256 chars is plenty to
* fit "/usr/lib/mozilla-firefox/bin/firefox-bin" and "/usr/bin/lynx"
* and "/usr/bin/kdeinit".
*/
#define IPT_PROGNAME_SZ 256
struct ipt_program_info {
char full_exe_path[IPT_PROGNAME_SZ];
u_int8_t invert; /* flags */
};
#endif /*_IPT_PROGRAM_H*/
[-- Attachment #4: ipt_program.c --]
[-- Type: text/x-csrc, Size: 4609 bytes --]
/* Kernel module to match the program name tied to sockets associated with
locally generated outgoing packets.
*/
/*
* (C) 2004 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
*
* 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.
*
* Module based on ipt_owner.c, by Mark Boucher.
*
* (C) 2000 Marc Boucher <marc@mbsi.ca>
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/file.h>
#include <linux/rwsem.h>
#include <linux/mount.h>
#include <linux/dcache.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/netfilter_ipv4/ipt_program.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Luke Kenneth Casson Leighton <lkcl@lkcl.net>");
MODULE_DESCRIPTION("iptables program match");
/* lkcl: this function is in fs/proc/base.c. it's a generic function
* derived from proc_exe_link(). it's inappropriate to leave that
* function in fs/proc/base.c. but i don't care: i don't have the
* knowledge to say where it should go. therefore i'm leaving
* it in fs/proc/base.c.
*/
extern int proc_task_dentry_lookup(struct task_struct *task,
struct dentry **dentry,
struct vfsmount **mnt);
/*
* look up the dentry (for the inode) of the task's executable,
* plus lookup the mountpoint of the filesystem from where that
* executable came from. then do exactly the same socket checking
* that all the other checks seem to be doing.
*/
static int proc_exe_check(struct task_struct *task,
const char *prog_full_name)
{
int result;
struct vfsmount *mnt;
struct dentry *dentry;
char exe_path[IPT_PROGNAME_SZ];
char *p;
result = proc_task_dentry_lookup(task, &dentry, &mnt);
if (result != 0)
return result;
/* turn the task info (dentry + mountpoint) into a program name... */
p = d_path(dentry, mnt, exe_path, sizeof(exe_path));
if (p == ERR_PTR(-ENAMETOOLONG))
return -1;
printk("ipt_program: program name %s\n", prog_full_name);
return strncmp(p, prog_full_name, sizeof(exe_path));
}
static int
match_inode(const struct sk_buff *skb, const char *prog_full_name)
{
struct task_struct *g, *p;
struct files_struct *files;
int i;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (proc_exe_check(p, prog_full_name))
continue;
//printk("ipt_program: program name %s matched, now looking for socket...\n", prog_full_name);
task_lock(p);
files = p->files;
if(files) {
spin_lock(&files->file_lock);
for (i=0; i < files->max_fds; i++) {
if (fcheck_files(files, i) ==
skb->sk->sk_socket->file) {
spin_unlock(&files->file_lock);
task_unlock(p);
read_unlock(&tasklist_lock);
printk("ipt_program: program name %s matched\n", prog_full_name);
return 1;
}
}
spin_unlock(&files->file_lock);
}
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
return 0;
}
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
int *hotdrop)
{
const struct ipt_program_info *info = matchinfo;
printk("ipt_program...\n");
if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
{
printk("ipt_program: not enough info, no sk, no sk_socket, no file\n");
return 0;
}
if (!match_inode(skb, info->full_exe_path) ^
!!info->invert)
return 0;
return 1;
}
static int
checkentry(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (hook_mask
& ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
printk("ipt_program: warning - code based on ipt_owner, which is only valid for LOCAL_OUT or POST_ROUTING. continuing at your own risk!\n");
/*return 0;*/
}
if (matchsize != IPT_ALIGN(sizeof(struct ipt_program_info))) {
printk("Matchsize %u != %Zu\n", matchsize,
IPT_ALIGN(sizeof(struct ipt_program_info)));
return 0;
}
return 1;
}
static struct ipt_match program_match = {
.name = "program",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ipt_register_match(&program_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&program_match);
}
module_init(init);
module_exit(fini);
next reply other threads:[~2004-09-11 12:30 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-11 12:41 Luke Kenneth Casson Leighton [this message]
2004-09-11 12:51 ` [PATCH 2.6 NETFILTER] new netfilter module ipt_program.c Patrick McHardy
2004-09-11 12:51 ` Patrick McHardy
2004-09-11 13:29 ` Luke Kenneth Casson Leighton
2004-09-11 13:34 ` Luke Kenneth Casson Leighton
2004-09-11 14:36 ` Patrick McHardy
2004-09-11 14:36 ` Patrick McHardy
2004-09-11 17:57 ` Luke Kenneth Casson Leighton
2004-09-11 14:49 ` Gianni Tedesco
2004-09-11 17:36 ` Luke Kenneth Casson Leighton
2004-09-13 11:50 ` Maciej Soltysiak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040911124106.GD24787@lkcl.net \
--to=lkcl@lkcl.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.