From: Patrick McHardy <kaber@trash.net>
To: marc@mbsi.ca
Cc: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
Subject: [PATCH] LOCAL_IN support for owner match
Date: Wed, 26 Mar 2003 15:15:43 +0100 [thread overview]
Message-ID: <3E81B60F.1000609@trash.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 509 bytes --]
Hi Marc,
this patch adds LOCAL_IN support to the owner match.
My previous patches which i sent to netfilter-devel had
problems, namely they didn't knew about tcp sockets
in TIME_WAIT state so the crashed. This one is tested
on several computers for some time and seems to work well.
I think this is a very useful feature for filtering weird protocols
like H.323 or IIOB without conntrack helpers, but also for
local user traffic accounting or similar stuff. Please consider
for inclusion.
Regards,
Patrick
[-- Attachment #2: pom-owner.diff --]
[-- Type: text/plain, Size: 7358 bytes --]
diff -urN a/extra/owner-socketlookup.patch b/extra/owner-socketlookup.patch
--- a/extra/owner-socketlookup.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/extra/owner-socketlookup.patch 2003-03-26 14:29:09.000000000 +0100
@@ -0,0 +1,205 @@
+diff -urN a/include/net/tcp.h b/include/net/tcp.h
+--- a/include/net/tcp.h 2002-11-29 00:53:15.000000000 +0100
++++ b/include/net/tcp.h 2003-03-26 14:11:33.000000000 +0100
+@@ -140,6 +140,7 @@
+ extern void tcp_bucket_unlock(struct sock *sk);
+ extern int tcp_port_rover;
+ extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
++extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
+
+ /* These are AF independent. */
+ static __inline__ int tcp_bhashfn(__u16 lport)
+diff -urN a/include/net/udp.h b/include/net/udp.h
+--- a/include/net/udp.h 2001-11-22 20:47:15.000000000 +0100
++++ b/include/net/udp.h 2003-03-26 14:11:33.000000000 +0100
+@@ -69,6 +69,8 @@
+ extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+ extern int udp_disconnect(struct sock *sk, int flags);
+
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
++
+ extern struct udp_mib udp_statistics[NR_CPUS*2];
+ #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
+ #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
+diff -urN a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
+--- a/net/ipv4/netfilter/ipt_owner.c 2002-11-29 00:53:15.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_owner.c 2003-03-26 14:26:20.000000000 +0100
+@@ -2,17 +2,25 @@
+ locally generated outgoing packets.
+
+ Copyright (C) 2000 Marc Boucher
++
++ 03/26/2003 Patrick McHardy <kaber@trash.net>: LOCAL_IN support
+ */
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/file.h>
++#include <linux/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
+ #include <net/sock.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++#include <net/route.h>
+
+ #include <linux/netfilter_ipv4/ipt_owner.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+
+ static int
+-match_comm(const struct sk_buff *skb, const char *comm)
++match_comm(const struct sock *sk, const char *comm)
+ {
+ struct task_struct *p;
+ struct files_struct *files;
+@@ -28,7 +36,7 @@
+ if(files) {
+ read_lock(&files->file_lock);
+ for (i=0; i < files->max_fds; i++) {
+- if (fcheck_files(files, i) == skb->sk->socket->file) {
++ if (fcheck_files(files, i) == sk->socket->file) {
+ read_unlock(&files->file_lock);
+ task_unlock(p);
+ read_unlock(&tasklist_lock);
+@@ -44,7 +52,7 @@
+ }
+
+ static int
+-match_pid(const struct sk_buff *skb, pid_t pid)
++match_pid(const struct sock *sk, pid_t pid)
+ {
+ struct task_struct *p;
+ struct files_struct *files;
+@@ -59,7 +67,7 @@
+ if(files) {
+ read_lock(&files->file_lock);
+ for (i=0; i < files->max_fds; i++) {
+- if (fcheck_files(files, i) == skb->sk->socket->file) {
++ if (fcheck_files(files, i) == sk->socket->file) {
+ read_unlock(&files->file_lock);
+ task_unlock(p);
+ read_unlock(&tasklist_lock);
+@@ -75,10 +83,10 @@
+ }
+
+ static int
+-match_sid(const struct sk_buff *skb, pid_t sid)
++match_sid(const struct sock *sk, pid_t sid)
+ {
+ struct task_struct *p;
+- struct file *file = skb->sk->socket->file;
++ struct file *file = sk->socket->file;
+ int i, found=0;
+
+ read_lock(&tasklist_lock);
+@@ -119,41 +127,71 @@
+ int *hotdrop)
+ {
+ const struct ipt_owner_info *info = matchinfo;
+-
+- if (!skb->sk || !skb->sk->socket || !skb->sk->socket->file)
+- return 0;
++ struct iphdr *iph = skb->nh.iph;
++ struct sock *sk = NULL;
++ int ret = 0;
++
++ if (out) {
++ sk = skb->sk;
++ } else {
++ if (iph->protocol == IPPROTO_TCP) {
++ struct tcphdr *tcph =
++ (struct tcphdr*)((u_int32_t*)iph + iph->ihl);
++ sk = tcp_v4_lookup(iph->saddr, tcph->source,
++ iph->daddr, tcph->dest,
++ ((struct rtable*)skb->dst)->rt_iif);
++ if (sk && sk->state == TCP_TIME_WAIT) {
++ tcp_tw_put((struct tcp_tw_bucket *)sk);
++ return ret;
++ }
++ } else if (iph->protocol == IPPROTO_UDP) {
++ struct udphdr *udph =
++ (struct udphdr*)((u_int32_t*)iph + iph->ihl);
++ sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
++ udph->dest, skb->dev->ifindex);
++ }
++ }
++
++ if (!sk || !sk->socket || !sk->socket->file)
++ goto out;
+
+ if(info->match & IPT_OWNER_UID) {
+- if((skb->sk->socket->file->f_uid != info->uid) ^
++ if((sk->socket->file->f_uid != info->uid) ^
+ !!(info->invert & IPT_OWNER_UID))
+- return 0;
++ goto out;
+ }
+
+ if(info->match & IPT_OWNER_GID) {
+- if((skb->sk->socket->file->f_gid != info->gid) ^
++ if((sk->socket->file->f_gid != info->gid) ^
+ !!(info->invert & IPT_OWNER_GID))
+- return 0;
++ goto out;
+ }
+
+ if(info->match & IPT_OWNER_PID) {
+- if (!match_pid(skb, info->pid) ^
++ if (!match_pid(sk, info->pid) ^
+ !!(info->invert & IPT_OWNER_PID))
+- return 0;
++ goto out;
+ }
+
+ if(info->match & IPT_OWNER_SID) {
+- if (!match_sid(skb, info->sid) ^
++ if (!match_sid(sk, info->sid) ^
+ !!(info->invert & IPT_OWNER_SID))
+- return 0;
++ goto out;
+ }
+
+ if(info->match & IPT_OWNER_COMM) {
+- if (!match_comm(skb, info->comm) ^
++ if (!match_comm(sk, info->comm) ^
+ !!(info->invert & IPT_OWNER_COMM))
+- return 0;
++ goto out;
+ }
+
+- return 1;
++ ret = 1;
++
++out:
++ if (in && sk)
++ sock_put(sk);
++
++ return ret;
+ }
+
+ static int
+@@ -164,8 +202,10 @@
+ unsigned int hook_mask)
+ {
+ if (hook_mask
+- & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
+- printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
++ & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
++ (1 << NF_IP_LOCAL_IN))) {
++ printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
++ "or POST_ROUTING.\n");
+ return 0;
+ }
+
+diff -urN a/net/netsyms.c b/net/netsyms.c
+--- a/net/netsyms.c 2002-11-29 00:53:16.000000000 +0100
++++ b/net/netsyms.c 2003-03-26 14:11:33.000000000 +0100
+@@ -596,4 +596,9 @@
+ EXPORT_SYMBOL(wireless_send_event);
+ #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
+
++#if defined(CONFIG_IP_NF_MATCH_OWNER)||defined(CONFIG_IP_NF_MATCH_OWNER_MODULE)
++EXPORT_SYMBOL(tcp_v4_lookup);
++EXPORT_SYMBOL(udp_v4_lookup);
++#endif /* CONFIG_IP_NF_MATCH_OWNER */
++
+ #endif /* CONFIG_NET */
diff -urN a/extra/owner-socketlookup.patch.help b/extra/owner-socketlookup.patch.help
--- a/extra/owner-socketlookup.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/extra/owner-socketlookup.patch.help 2003-03-26 14:23:32.000000000 +0100
@@ -0,0 +1,14 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: working
+
+The patch allows you to use the owner match in the INPUT chain to match
+properties of the receiving socket. This could be used to filter like
+those "personal firewalls", but is mainly intended to help filter weird
+protocols like H.323 or IIOB without conntrack helpers.
+
+Example:
+
+ # Allow packets on eth0 to sockets owned by local user gnugk
+
+ iptables -A INPUT -i eth0 -m owner --uid-owner gnugk -j ACCEPT
+
next reply other threads:[~2003-03-26 14:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-03-26 14:15 Patrick McHardy [this message]
2003-03-27 13:12 ` [PATCH] LOCAL_IN support for owner match Harald Welte
2003-03-27 14:02 ` Patrick McHardy
2003-03-27 14:21 ` Patrick McHardy
2003-03-27 14:49 ` [UPDATED PATCH] " Patrick McHardy
2003-04-01 11:44 ` Patrick McHardy
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=3E81B60F.1000609@trash.net \
--to=kaber@trash.net \
--cc=marc@mbsi.ca \
--cc=netfilter-devel@lists.netfilter.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.