Skip to contentSkip to conversation

Status of owner-socketlookup

PATCH In review James Morris 6 participants 30 messages Apr 27, 2005 – May 12, 2005

Subsystems (4)
lore
Share & tools
lore
maintainer
#1 lore raw
Quoted 2 lines · On Wed, 27 Apr 2005 00:22:16 -0400 (EDT) James Morris <[email protected]>…

What's the status of this patch, are there any plans to submit it upstream?

If this is the patch I think it is, I believe I told Patrick it was too ugly to live :)

#2 lore raw
Quoted 8 lines · David S. Miller
Quoted 2 lines · On Wed, 27 Apr 2005 00:22:16 -0400 (EDT) James Morris <[email protected]>…

What's the status of this patch, are there any plans to submit it upstream?

If this is the patch I think it is, I believe I told Patrick it was too ugly to live :)

It probably is. I'd like to find a clean way to get at the destination sock via iptables for locally arriving packets, for SELinux. i.e. match incoming packets against a destination security context.

There's already an LSM hook via sk_filter(), but I also need the iptables framework to make use of matches, targets, chains etc.

I've had one idea for this but it's too ugly to even describe :-)

- James

Signature · 2 lines
James Morris
<[email protected]>
#3 lore raw
Quoted 6 lines · James Morris

It probably is. I'd like to find a clean way to get at the destination sock via iptables for locally arriving packets, for SELinux. i.e. match incoming packets against a destination security context.

There's already an LSM hook via sk_filter(), but I also need the iptables framework to make use of matches, targets, chains etc.

I also need a clean way for work, so I started with Dave's suggestion of putting new hooks in the protocols that get the socket as new argument. The ->rcv functions are split after the socket lookup and netfilter is called:

        return NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb, skb->dev, NULL,
                          udp_rcv_finish);

I still need to convert parts of iptables to handle the new argument, I'll post a patch in a few days. Unfortunately, this doesn't solve the other problems of the owner match, for properly working pid and command matching we need at least the pid of the sending process to look it up. Any ideas for solving this are welcome.

Regards
Patrick

#4 lore raw

Also, I wonder, if we're doing the socket lookup early (in Netfilter), perhaps there's some way of caching this so we don't have to do it again later.

If this is racy, then the initial lookup is also racy :-)

- James

Signature · 2 lines
James Morris
<[email protected]>
#5 lore raw
Quoted 1 line · James Morris

Also, I wonder, if we're doing the socket lookup early (in Netfilter), perhaps there's some way of caching this so we don't have to do it again later.

With NF_SK_HOOK(), filtering would happen in socket context, so there is no need to cache it. Otherwise it makes sense I guess.

Regards
Patrick

maintainer
#6 lore raw
Quoted 7 lines · On Wed, 27 Apr 2005 16:04:48 +0200 Patrick McHardy <[email protected]> wrote:
Quoted 3 lines · James Morris

Also, I wonder, if we're doing the socket lookup early (in Netfilter), perhaps there's some way of caching this so we don't have to do it again later.

With NF_SK_HOOK(), filtering would happen in socket context, so there is no need to cache it. Otherwise it makes sense I guess.

The TCP socket can be reset between when netfilter looks up the socket on input and when TCP input processing does the same.

You aren't locking the socket in this new netfilter input socket code, so nothing prevents incoming packets from being delivered to that socket on another cpu and thus causing the aforementioned resets.

This is why such caching would be illegal.

#7 lore raw
In reply to Patrick McHardy
Quoted 5 lines · Patrick McHardy

I still need to convert parts of iptables to handle the new argument, I'll post a patch in a few days. Unfortunately, this doesn't solve the other problems of the owner match, for properly working pid and command matching we need at least the pid of the sending process to look it up. Any ideas for solving this are welcome.

I am working on the other issues you mentioned. Or at least doing some research.

To authenticate _receiving_ process reliably I created a socket usage surveillance module. It keeps track of the processes that access PF_INET sockets. If the accessing process is not already in the surveillance list then the absolute path and stat(2) of the process image is stored. plus some other relevant information like pid.

When a packet is received the socket is located by using tcp/udp_v4_lookup functions. After the socket is found the modified version of sock_def_readable is used to get information about the receiving tasks that are stored into surveillance module. After this I just compare data to e.g. ipt_owner_info. Works great!

Ideas how to identify sending process are indeed needed. How about adding sender information (pid) into skb?

I am working on thesis about process network access control in Linux. I will make announcement (hopefully) within a week.

Regards,
Juha Heljoranta

#8 lore raw
Quoted 2 lines · Juha Heljoranta

Ideas how to identify sending process are indeed needed. How about adding sender information (pid) into skb?

Well, it seems the whole concept of associating sockets with processes is flawed, a socket can be owned by any number of processes, and even a single packet can be created by multiple processes. For outgoing packets it would be possible to store the pid in the skb and handle the unlikely case of a packet created by multiple processes somehow, but for incoming packets we really don't know which process is going to receive a packet until it calls recvmsg(). This is too late for filtering with netfilter because multiple references (device, conntrack, ..) need to be dropped earlier.

Regards
Patrick

maintainer
#9 lore raw
Quoted 2 lines · On Wed, 27 Apr 2005 16:52:46 +0200 Patrick McHardy <[email protected]> wrote:

for incoming packets we really don't know which process is going to receive a packet until it calls recvmsg().

Good point. It does mean that the best thing you can do is block reception at recvmsg() time, nothing more. You can't drop the packet at recvmsg() time because TCP has ACK'd the thing already etc.

#10 lore raw
Quoted 4 lines · David S. Miller

Good point. It does mean that the best thing you can do is block reception at recvmsg() time, nothing more. You can't drop the packet at recvmsg() time because TCP has ACK'd the thing already etc.

I think what it comes down to is that we can filter in socket context, but the only useable attributes in both input- and output-path for owner-matching are sk->sk_socket->file->f_{uid,gid}. This should still be enough for many usage cases (and for mine), so I'm going to finish the patch.

@james: Out of interest, what are the requirements for selinux?

Regards
Patrick

#11 lore raw
Quoted 8 lines · Patrick McHardy

I think what it comes down to is that we can filter in socket context, but the only useable attributes in both input- and output-path for owner-matching are sk->sk_socket->file->f_{uid,gid}. This should still be enough for many usage cases (and for mine), so I'm going to finish the patch.

@james: Out of interest, what are the requirements for selinux?

We only need to get at the inode associated with the receiving sk, which has security info already attached.

SELinux currently does this via an LSM hook in sk_filter() (see selinux_socket_sock_rcv_skb()).

- James

Signature · 2 lines
James Morris
<[email protected]>
#12 lore raw

Netfilter socket hooks (was: Re: Status of owner-socketlookup)

In reply to Patrick McHardy
Quoted 6 lines · Patrick McHardy

I think what it comes down to is that we can filter in socket context, but the only useable attributes in both input- and output-path for owner-matching are sk->sk_socket->file->f_{uid,gid}. This should still be enough for many usage cases (and for mine), so I'm going to finish the patch.

Here is a first shot at socket hooks. Nothing uses them yet, and at least two things are still missing:

- conntrack reference should not be dropped before socket hooks
- conntrack should be confirmed in socket hooks

Comments?

#13 lore raw

PATCH 1/5 : Add socket hook infrastructure

[NETFILTER]: Add socket hook infrastructure

---
commit 4ca9ffc0b58dd44e91cbaaa2de3c27faa220e047
tree e97143c76936d02bb1817a1e109e36707202a6bb
parent e8108c98dd6d65613fa0ec9d2300f89c48d554bf
author Patrick McHardy <[email protected]> Mon, 09 May 2005 16:47:43 +0200 committer Patrick McHardy <[email protected]> Mon, 09 May 2005 16:47:43 +0200

 include/linux/netfilter.h |   44 +++++++++++++++++++++
 net/core/netfilter.c      |   96 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 139 insertions(+), 1 deletion(-)
include/linux/netfilter.h (mode:100644) +44 -0
Index: include/linux/netfilter.h
===================================================================
@@ -57,6 +57,25 @@
 	int priority;
 };
 
+typedef unsigned int nf_sk_hookfn(unsigned int hooknum,
+                                  struct sock *sk, struct sk_buff **skb,
+                                  const struct net_device *in,
+                                  const struct net_device *out,
+                                  int (*okfn)(struct sock *sk, struct sk_buff *));
+
+struct nf_sk_hook_ops
+{
+	struct list_head list;
+
+	/* User fills in from here down. */
+	nf_sk_hookfn *hook;
+	struct module *owner;
+	unsigned int pf;
+	unsigned int hooknum;
+	/* Hooks are ordered in ascending priority. */
+	int priority;
+};
+
 struct nf_sockopt_ops
 {
 	struct list_head list;
@@ -94,12 +113,16 @@
 int nf_register_hook(struct nf_hook_ops *reg);
 void nf_unregister_hook(struct nf_hook_ops *reg);
 
+int nf_register_sk_hook(struct nf_sk_hook_ops *reg);
+void nf_unregister_sk_hook(struct nf_sk_hook_ops *reg);
+
 /* Functions to register get/setsockopt ranges (non-inclusive).  You
    need to check permissions yourself! */
 int nf_register_sockopt(struct nf_sockopt_ops *reg);
 void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
 
 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
+extern struct list_head nf_sk_hooks[NPROTO][NF_MAX_HOOKS];
 
 typedef void nf_logfn(unsigned int hooknum,
 		      const struct sk_buff *skb,
@@ -149,6 +172,13 @@
 if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)  \
 	__ret = (okfn)(skb);						       \
 __ret;})
+#define NF_SK_HOOK(pf, hook, sk, skb, indev, outdev, okfn, skputfn)	       \
+({int __ret;								       \
+if ((__ret=nf_sk_hook_slow(pf, hook, sk, &(skb), indev, outdev, okfn)) == 0)   \
+	__ret = (okfn)(sk, skb);					       \
+else if (sk && skputfn)							       \
+	((void (*)(struct sock *))skputfn)(sk);				       \
+__ret;})
 #else
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn)			       \
 ({int __ret;								       \
@@ -162,12 +192,25 @@
     (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)  \
 	__ret = (okfn)(skb);						       \
 __ret;})
+#define NF_SK_HOOK(pf, hook, sk, skb, indev, outdev, okfn, skputfn)	       \
+({int __ret;								       \
+if (list_empty(&nf_sk_hooks[pf][hook]) ||				       \
+    (__ret=nf_sk_hook_slow(pf, hook, sk, &(skb), indev, outdev, okfn)) == 0)   \
+	__ret = (okfn)(sk, skb);					       \
+else if (sk && skputfn)							       \
+	((void (*)(struct sock *))skputfn)(sk);				       \
+__ret;})
 #endif
 
 int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
 		 struct net_device *indev, struct net_device *outdev,
 		 int (*okfn)(struct sk_buff *), int thresh);
 
+int nf_sk_hook_slow(int pf, unsigned int hook,
+                    struct sock *sk, struct sk_buff **pskb,
+                    struct net_device *indev, struct net_device *outdev,
+                    int (*okfn)(struct sock *, struct sk_buff *));
+
 /* Call setsockopt() */
 int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, 
 		  int len);
@@ -192,6 +235,7 @@
 
 #else /* !CONFIG_NETFILTER */
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+#define NF_SK_HOOK(pf, hook, sk, skb, indev, outdev, okfn, skputfn) (okfn)(sk, skb)
 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
 #endif /*CONFIG_NETFILTER*/
 
net/core/netfilter.c (mode:100644) +95 -1

115 lines not on this page · raw message

#14 lore raw

Re: [netfilter socket hooks 1/5]: Add socket hook infrastructure

include/linux/netfilter.h (mode:100644) line 77

Quoted 12 lines · Patrick McHardy
include/linux/netfilter.h (mode:100644) +12 -0
+struct nf_sk_hook_ops
+{
+	struct list_head list;
+
+	/* User fills in from here down. */
+	nf_sk_hookfn *hook;
+	struct module *owner;
+	unsigned int pf;
+	unsigned int hooknum;
+	/* Hooks are ordered in ascending priority. */
+	int priority;
+};

Do you need to add this struct? It's the same as nf_hook_ops.

- James

Signature · 2 lines
James Morris
<[email protected]>
#15 lore raw

Re: [netfilter socket hooks 1/5]: Add socket hook infrastructure

Quoted 1 line · James Morris

Do you need to add this struct? It's the same as nf_hook_ops.

Don't worry, I can see nf_sk_hookfn is differnt.

- James

Signature · 2 lines
James Morris
<[email protected]>
#16 lore raw

Re: [netfilter socket hooks 1/5]: Add socket hook infrastructure

In reply to James Morris
Quoted 18 lines · James Morris

include/linux/netfilter.h (mode:100644) line 77

Quoted 12 lines · Patrick McHardy
include/linux/netfilter.h (mode:100644) +12 -0
+struct nf_sk_hook_ops
+{
+	struct list_head list;
+
+	/* User fills in from here down. */
+	nf_sk_hookfn *hook;
+	struct module *owner;
+	unsigned int pf;
+	unsigned int hooknum;
+	/* Hooks are ordered in ascending priority. */
+	int priority;
+};

Do you need to add this struct? It's the same as nf_hook_ops.

Unfortunately yes, the hook functions have different prototypes.

Regards
Patrick

#17 lore raw

PATCH 2/5 : Add protocol hooks

In reply to Patrick McHardy

[NETFILTER]: Add protocol hooks

---
commit 03a2e97e71c3c9bfbfc3d357544348d393551658
tree b53df6f327c03ec282a1b75326db321dbd2f0bc0
parent 4ca9ffc0b58dd44e91cbaaa2de3c27faa220e047
author Patrick McHardy <[email protected]> Mon, 09 May 2005 18:34:53 +0200 committer Patrick McHardy <[email protected]> Mon, 09 May 2005 18:34:53 +0200

 net/ipv4/raw.c      |    8 ++-
 net/ipv4/tcp_ipv4.c |  123 +++++++++++++++++++++++++++++++++-------------------
 net/ipv4/udp.c      |  109 +++++++++++++++++++++++++++-------------------
 3 files changed, 151 insertions(+), 89 deletions(-)
net/ipv4/raw.c (mode:100644) +7 -1
Index: net/ipv4/raw.c
===================================================================
@@ -246,7 +246,7 @@
 	return NET_RX_SUCCESS;
 }
 
-int raw_rcv(struct sock *sk, struct sk_buff *skb)
+static inline int raw_rcv_finish(struct sock *sk, struct sk_buff *skb)
 {
 	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
 		kfree_skb(skb);
@@ -259,6 +259,12 @@
 	return 0;
 }
 
+int raw_rcv(struct sock *sk, struct sk_buff *skb)
+{
+	return NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb, skb->dev, NULL,
+	                  raw_rcv_finish, NULL);
+}
+
 static int raw_send_hdrinc(struct sock *sk, void *from, int length,
 			struct rtable *rt, 
 			unsigned int flags)
net/ipv4/tcp_ipv4.c (mode:100644) +79 -44

156 lines not on this page · raw message

net/ipv4/udp.c (mode:100644) +65 -44

135 lines not on this page · raw message

#18 lore raw

PATCH 3/5 : Add struct sock * argument to ipt_do_table()

In reply to Patrick McHardy

[NETFILTER]: Add struct sock * argument to ipt_do_table()

---
commit 2816668ea745b16e1da608bf4d7b638a75389bd6
tree 8bd69ddefbecc96b2253453c6b4da15bbff92988
parent 03a2e97e71c3c9bfbfc3d357544348d393551658
author Patrick McHardy <[email protected]> Mon, 09 May 2005 18:36:10 +0200 committer Patrick McHardy <[email protected]> Mon, 09 May 2005 18:36:10 +0200

 include/linux/netfilter_ipv4/ip_tables.h |    3 ++-
 net/ipv4/netfilter/ip_nat_rule.c         |    2 +-
 net/ipv4/netfilter/ip_tables.c           |    3 ++-
 net/ipv4/netfilter/iptable_filter.c      |    4 ++--
 net/ipv4/netfilter/iptable_mangle.c      |    4 ++--
 net/ipv4/netfilter/iptable_raw.c         |    2 +-
 6 files changed, 10 insertions(+), 8 deletions(-)
include/linux/netfilter_ipv4/ip_tables.h (mode:100644) +2 -1
Index: include/linux/netfilter_ipv4/ip_tables.h
===================================================================
@@ -478,7 +478,8 @@
 extern int ipt_register_table(struct ipt_table *table,
 			      const struct ipt_replace *repl);
 extern void ipt_unregister_table(struct ipt_table *table);
-extern unsigned int ipt_do_table(struct sk_buff **pskb,
+extern unsigned int ipt_do_table(struct sock *sk,
+				 struct sk_buff **pskb,
 				 unsigned int hook,
 				 const struct net_device *in,
 				 const struct net_device *out,
net/ipv4/netfilter/ip_nat_rule.c (mode:100644) +1 -1
Index: net/ipv4/netfilter/ip_nat_rule.c
===================================================================
@@ -264,7 +264,7 @@
 {
 	int ret;
 
-	ret = ipt_do_table(pskb, hooknum, in, out, &nat_table, NULL);
+	ret = ipt_do_table(NULL, pskb, hooknum, in, out, &nat_table, NULL);
 
 	if (ret == NF_ACCEPT) {
 		if (!ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
net/ipv4/netfilter/ip_tables.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ip_tables.c
===================================================================
@@ -257,7 +257,8 @@
 
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
-ipt_do_table(struct sk_buff **pskb,
+ipt_do_table(struct sock *sk,
+	     struct sk_buff **pskb,
 	     unsigned int hook,
 	     const struct net_device *in,
 	     const struct net_device *out,
net/ipv4/netfilter/iptable_filter.c (mode:100644) +2 -2
Index: net/ipv4/netfilter/iptable_filter.c
===================================================================
@@ -89,7 +89,7 @@
 	 const struct net_device *out,
 	 int (*okfn)(struct sk_buff *))
 {
-	return ipt_do_table(pskb, hook, in, out, &packet_filter, NULL);
+	return ipt_do_table(NULL, pskb, hook, in, out, &packet_filter, NULL);
 }
 
 static unsigned int
@@ -107,7 +107,7 @@
 		return NF_ACCEPT;
 	}
 
-	return ipt_do_table(pskb, hook, in, out, &packet_filter, NULL);
+	return ipt_do_table(NULL, pskb, hook, in, out, &packet_filter, NULL);
 }
 
 static struct nf_hook_ops ipt_ops[] = {
net/ipv4/netfilter/iptable_mangle.c (mode:100644) +2 -2
Index: net/ipv4/netfilter/iptable_mangle.c
===================================================================
@@ -119,7 +119,7 @@
 	 const struct net_device *out,
 	 int (*okfn)(struct sk_buff *))
 {
-	return ipt_do_table(pskb, hook, in, out, &packet_mangler, NULL);
+	return ipt_do_table(NULL, pskb, hook, in, out, &packet_mangler, NULL);
 }
 
 static unsigned int
@@ -148,7 +148,7 @@
 	daddr = (*pskb)->nh.iph->daddr;
 	tos = (*pskb)->nh.iph->tos;
 
-	ret = ipt_do_table(pskb, hook, in, out, &packet_mangler, NULL);
+	ret = ipt_do_table(NULL, pskb, hook, in, out, &packet_mangler, NULL);
 	/* Reroute for ANY change. */
 	if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE
 	    && ((*pskb)->nh.iph->saddr != saddr
net/ipv4/netfilter/iptable_raw.c (mode:100644) +1 -1
Index: net/ipv4/netfilter/iptable_raw.c
===================================================================
@@ -94,7 +94,7 @@
 	 const struct net_device *out,
 	 int (*okfn)(struct sk_buff *))
 {
-	return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
+	return ipt_do_table(NULL, pskb, hook, in, out, &packet_raw, NULL);
 }
 
 /* 'raw' is the very first table. */
#19 lore raw

PATCH 4/5 : Add struct sock * argument to match functions

In reply to Patrick McHardy

[NETFILTER]: Add struct sock * argument to match functions

---
commit 3e78de8c1e4b12407299b48cf9f024786415639f
tree a24014694fc1a7ed32010fe4524b2601c6516eaf
parent 2816668ea745b16e1da608bf4d7b638a75389bd6
author Patrick McHardy <[email protected]> Mon, 09 May 2005 18:37:19 +0200 committer Patrick McHardy <[email protected]> Mon, 09 May 2005 18:37:19 +0200

 include/linux/netfilter_ipv4/ip_tables.h |    3 ++-
 net/ipv4/netfilter/ip_tables.c           |   14 +++++++++-----
 net/ipv4/netfilter/ipt_addrtype.c        |    6 +++---
 net/ipv4/netfilter/ipt_ah.c              |    3 ++-
 net/ipv4/netfilter/ipt_comment.c         |    3 ++-
 net/ipv4/netfilter/ipt_connmark.c        |    3 ++-
 net/ipv4/netfilter/ipt_conntrack.c       |    3 ++-
 net/ipv4/netfilter/ipt_dscp.c            |    6 +++---
 net/ipv4/netfilter/ipt_ecn.c             |    6 +++---
 net/ipv4/netfilter/ipt_esp.c             |    3 ++-
 net/ipv4/netfilter/ipt_hashlimit.c       |    3 ++-
 net/ipv4/netfilter/ipt_helper.c          |    3 ++-
 net/ipv4/netfilter/ipt_iprange.c         |    3 ++-
 net/ipv4/netfilter/ipt_length.c          |    3 ++-
 net/ipv4/netfilter/ipt_limit.c           |    3 ++-
 net/ipv4/netfilter/ipt_mac.c             |    3 ++-
 net/ipv4/netfilter/ipt_mark.c            |    3 ++-
 net/ipv4/netfilter/ipt_multiport.c       |    6 ++++--
 net/ipv4/netfilter/ipt_owner.c           |    3 ++-
 net/ipv4/netfilter/ipt_physdev.c         |    3 ++-
 net/ipv4/netfilter/ipt_pkttype.c         |   13 +++++++------
 net/ipv4/netfilter/ipt_realm.c           |    3 ++-
 net/ipv4/netfilter/ipt_recent.c          |    8 +++++---
 net/ipv4/netfilter/ipt_sctp.c            |    3 ++-
 net/ipv4/netfilter/ipt_state.c           |    3 ++-
 net/ipv4/netfilter/ipt_tcpmss.c          |    3 ++-
 net/ipv4/netfilter/ipt_tos.c             |    3 ++-
 net/ipv4/netfilter/ipt_ttl.c             |    6 +++---
 28 files changed, 77 insertions(+), 48 deletions(-)
include/linux/netfilter_ipv4/ip_tables.h (mode:100644) +2 -1
Index: include/linux/netfilter_ipv4/ip_tables.h
===================================================================
@@ -368,7 +368,8 @@
 	/* Arguments changed since 2.4, as this must now handle
            non-linear skbs, using skb_copy_bits and
            skb_ip_make_writable. */
-	int (*match)(const struct sk_buff *skb,
+	int (*match)(const struct sock *sk,
+		     const struct sk_buff *skb,
 		     const struct net_device *in,
 		     const struct net_device *out,
 		     const void *matchinfo,
net/ipv4/netfilter/ip_tables.c (mode:100644) +9 -5
Index: net/ipv4/netfilter/ip_tables.c
===================================================================
@@ -236,6 +236,7 @@
 
 static inline
 int do_match(struct ipt_entry_match *m,
+             const struct sock *sk,
 	     const struct sk_buff *skb,
 	     const struct net_device *in,
 	     const struct net_device *out,
@@ -243,7 +244,7 @@
 	     int *hotdrop)
 {
 	/* Stop iteration if it doesn't match */
-	if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop))
+	if (!m->u.kernel.match->match(sk, skb, in, out, m->data, offset, hotdrop))
 		return 1;
 	else
 		return 0;
@@ -319,7 +320,7 @@
 			struct ipt_entry_target *t;
 
 			if (IPT_MATCH_ITERATE(e, do_match,
-					      *pskb, in, out,
+					      sk, *pskb, in, out,
 					      offset, &hotdrop) != 0)
 				goto no_match;
 
@@ -1569,7 +1570,8 @@
 }
 
 static int
-tcp_match(const struct sk_buff *skb,
+tcp_match(const struct sock *sk,
+	  const struct sk_buff *skb,
 	  const struct net_device *in,
 	  const struct net_device *out,
 	  const void *matchinfo,
@@ -1650,7 +1652,8 @@
 }
 
 static int
-udp_match(const struct sk_buff *skb,
+udp_match(const struct sock *sk,
+	  const struct sk_buff *skb,
 	  const struct net_device *in,
 	  const struct net_device *out,
 	  const void *matchinfo,
@@ -1723,7 +1726,8 @@
 }
 
 static int
-icmp_match(const struct sk_buff *skb,
+icmp_match(const struct sock *sk,
+	   const struct sk_buff *skb,
 	   const struct net_device *in,
 	   const struct net_device *out,
 	   const void *matchinfo,
net/ipv4/netfilter/ipt_addrtype.c (mode:100644) +3 -3
Index: net/ipv4/netfilter/ipt_addrtype.c
===================================================================
@@ -27,9 +27,9 @@
 	return !!(mask & (1 << inet_addr_type(addr)));
 }
 
-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)
+static int match(const struct sock *sk, 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_addrtype_info *info = matchinfo;
 	const struct iphdr *iph = skb->nh.iph;
net/ipv4/netfilter/ipt_ah.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_ah.c
===================================================================
@@ -36,7 +36,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_comment.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_comment.c
===================================================================
@@ -14,7 +14,8 @@
 MODULE_LICENSE("GPL");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_connmark.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_connmark.c
===================================================================
@@ -31,7 +31,8 @@
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_conntrack.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_conntrack.c
===================================================================
@@ -19,7 +19,8 @@
 MODULE_DESCRIPTION("iptables connection tracking match module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_dscp.c (mode:100644) +3 -3
Index: net/ipv4/netfilter/ipt_dscp.c
===================================================================
@@ -19,9 +19,9 @@
 MODULE_DESCRIPTION("iptables DSCP matching module");
 MODULE_LICENSE("GPL");
 
-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)
+static int match(const struct sock *sk, 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_dscp_info *info = matchinfo;
 	const struct iphdr *iph = skb->nh.iph;
net/ipv4/netfilter/ipt_ecn.c (mode:100644) +3 -3
Index: net/ipv4/netfilter/ipt_ecn.c
===================================================================
@@ -65,9 +65,9 @@
 	return 1;
 }
 
-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)
+static int match(const struct sock *sk, 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_ecn_info *info = matchinfo;
 
net/ipv4/netfilter/ipt_esp.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_esp.c
===================================================================
@@ -37,7 +37,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_hashlimit.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_hashlimit.c
===================================================================
@@ -425,7 +425,8 @@
 
 
 static int
-hashlimit_match(const struct sk_buff *skb,
+hashlimit_match(const struct sock *sk,
+		const struct sk_buff *skb,
 		const struct net_device *in,
 		const struct net_device *out,
 		const void *matchinfo,
net/ipv4/netfilter/ipt_helper.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_helper.c
===================================================================
@@ -30,7 +30,8 @@
 #endif
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_iprange.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_iprange.c
===================================================================
@@ -24,7 +24,8 @@
 #endif
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_length.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_length.c
===================================================================
@@ -17,7 +17,8 @@
 MODULE_LICENSE("GPL");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_limit.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_limit.c
===================================================================
@@ -63,7 +63,8 @@
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
 static int
-ipt_limit_match(const struct sk_buff *skb,
+ipt_limit_match(const struct sock *sk,
+		const struct sk_buff *skb,
 		const struct net_device *in,
 		const struct net_device *out,
 		const void *matchinfo,
net/ipv4/netfilter/ipt_mac.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_mac.c
===================================================================
@@ -20,7 +20,8 @@
 MODULE_DESCRIPTION("iptables mac matching module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_mark.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_mark.c
===================================================================
@@ -18,7 +18,8 @@
 MODULE_DESCRIPTION("iptables mark matching module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_multiport.c (mode:100644) +4 -2
Index: net/ipv4/netfilter/ipt_multiport.c
===================================================================
@@ -92,7 +92,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
@@ -123,7 +124,8 @@
 }
 
 static int
-match_v1(const struct sk_buff *skb,
+match_v1(const struct sock *sk,
+	 const struct sk_buff *skb,
 	 const struct net_device *in,
 	 const struct net_device *out,
 	 const void *matchinfo,
net/ipv4/netfilter/ipt_owner.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_owner.c
===================================================================
@@ -121,7 +121,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_physdev.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_physdev.c
===================================================================
@@ -21,7 +21,8 @@
 MODULE_DESCRIPTION("iptables bridge physical device match module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_pkttype.c (mode:100644) +7 -6
Index: net/ipv4/netfilter/ipt_pkttype.c
===================================================================
@@ -17,12 +17,13 @@
 MODULE_AUTHOR("Michal Ludvig <[email protected]>");
 MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
 
-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)
+static int match(const struct sock *sk,
+                 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_pkttype_info *info = matchinfo;
 
net/ipv4/netfilter/ipt_realm.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_realm.c
===================================================================
@@ -22,7 +22,8 @@
 MODULE_DESCRIPTION("iptables realm match");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_recent.c (mode:100644) +5 -3
Index: net/ipv4/netfilter/ipt_recent.c
===================================================================
@@ -99,7 +99,8 @@
 
 /* Function declaration for later. */
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
@@ -317,7 +318,7 @@
 	skb->nh.iph->daddr = 0;
 	/* Clear ttl since we have no way of knowing it */
 	skb->nh.iph->ttl = 0;
-	match(skb,NULL,NULL,info,0,NULL);
+	match(NULL,skb,NULL,NULL,info,0,NULL);
 
 	kfree(skb->nh.iph);
 out_free_skb:
@@ -352,7 +353,8 @@
  * --seconds and --hitcount can be combined
  */
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_sctp.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_sctp.c
===================================================================
@@ -113,7 +113,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_state.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_state.c
===================================================================
@@ -19,7 +19,8 @@
 MODULE_DESCRIPTION("iptables connection tracking state match module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_tcpmss.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_tcpmss.c
===================================================================
@@ -74,7 +74,8 @@
 }
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_tos.c (mode:100644) +2 -1
Index: net/ipv4/netfilter/ipt_tos.c
===================================================================
@@ -18,7 +18,8 @@
 MODULE_DESCRIPTION("iptables TOS match module");
 
 static int
-match(const struct sk_buff *skb,
+match(const struct sock *sk,
+      const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const void *matchinfo,
net/ipv4/netfilter/ipt_ttl.c (mode:100644) +3 -3
Index: net/ipv4/netfilter/ipt_ttl.c
===================================================================
@@ -19,9 +19,9 @@
 MODULE_DESCRIPTION("IP tables TTL matching module");
 MODULE_LICENSE("GPL");
 
-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)
+static int match(const struct sock *sk, 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_ttl_info *info = matchinfo;
 
#20 lore raw

PATCH 5/5 : Add skfilter table

In reply to Patrick McHardy

[NETFILTER]: Add skfilter table

---
commit 52c8e9e72ec788e5829c6e3d412ab9d1816d79a0
tree 4919a5761d3ba1c668a54d32a8f028f002c8ff24
parent 3e78de8c1e4b12407299b48cf9f024786415639f
author Patrick McHardy <[email protected]> Mon, 09 May 2005 18:41:31 +0200 committer Patrick McHardy <[email protected]> Mon, 09 May 2005 18:41:31 +0200

 net/ipv4/netfilter/Kconfig            |    4 
 net/ipv4/netfilter/Makefile           |    2 
 net/ipv4/netfilter/iptable_skfilter.c |  140 ++++++++++++++++++++++++++++++++++
 3 files changed, 146 insertions(+)
net/ipv4/netfilter/Kconfig (mode:100644) +4 -0
Index: net/ipv4/netfilter/Kconfig
===================================================================
@@ -386,6 +386,10 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_SK_FILTER
+	tristate "Socket packet filtering"
+	depends on IP_NF_IPTABLES
+
 config IP_NF_TARGET_REJECT
 	tristate "REJECT target support"
 	depends on IP_NF_FILTER
net/ipv4/netfilter/Makefile (mode:100644) +2 -0
Index: net/ipv4/netfilter/Makefile
===================================================================
@@ -33,6 +33,8 @@
 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 
+obj-$(CONFIG_IP_NF_SK_FILTER)	+= iptable_skfilter.o
+
 # matches
 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
net/ipv4/netfilter/iptable_skfilter.c (mode:100644) renamed from dev/null (tree:a24014694fc1a7ed32010fe4524b2601c6516eaf) +140 -0

140 lines not on this page · raw message

#22 lore raw

Re: Netfilter socket hooks

In reply to Patrick McHardy

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoting Patrick McHardy on 2005-05-10 15:59 UTC:

Quoted 1 line

Here is a first shot at socket hooks.

Great :)

Quoted 1 line

Comments?

On what level will this be.. would one be able to filter what userspace programs do in addition to filtering what internet clients are allowed to do?

I.e. would one be able to filter userspace socket calls like accept(), connect(), bind(), recv(), send(), and maybe even setsockopt() etc?

Isn't it almost as important to protect the internet from malicious users as to protect users from the internet ?-) SELinux could maybe add features to base web access policies on SELinux's normal mechanism that currently grants/restricts access.

Example: If wget tryes to access the internet as a child of process A (which has been granted all web access), then wget would be allowed to do whatever it wants. Otherwise, wget's connect() call (when connecting to a http server) would fail with some Exxxx errno code..

It would also be nice if this skfilter provided something similar to the
QUEUE target to allow users yet another level to hook in.. This could
possibly allow quite clean implementations of interactive firewall clients..

//

I would also be interested if you could give some idea of what kind of commands you were thinking of that would be used to control skfilter..

- --
- - xkr47
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFCgRt0xyF48ZTvn+4RAr3iAJ9Hl3TNHKn6wlBQNXUCgBtK7LY3tQCfWsM3 6TfPFQaGf02SD9XZVHOmmd0=
=n1tg
-----END PGP SIGNATURE-----

maintainer
#23 lore raw

Re: Netfilter socket hooks

In reply to Patrick McHardy

From: Patrick McHardy <[email protected]>
Subject: Netfilter socket hooks (was: Re: Status of owner-socketlookup)
Date: Tue, 10 May 2005 17:59:13 +0200

Quoted 7 lines

Here is a first shot at socket hooks. Nothing uses them yet, and at least two things are still missing:

- conntrack reference should not be dropped before socket hooks
- conntrack should be confirmed in socket hooks

Comments?

No major objections here, in fact it's actually kind of nice. :-)

I'd like to go over the TCP input changes with a very fine toothed comb before integration, but that's it.

#24 lore raw

Re: Netfilter socket hooks (was: Re: Status of owner-socketlookup)

In reply to Patrick McHardy

What about adding an output hook to the table? This would make it much easier to manage rules.

Something like:

net/ipv4/netfilter/iptable_skfilter.c +60 -16
diff -purN -X dontdiff linux-2.6.12-rc4-sk.o/net/ipv4/netfilter/iptable_skfilter.c linux-2.6.12-rc4-sk.w/net/ipv4/netfilter/iptable_skfilter.c
@@ -11,24 +11,26 @@
 #include <linux/module.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
-#define SKFILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN))
+#define SKFILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_LOCAL_OUT))
 
 static struct
 {
 	struct ipt_replace repl;
-	struct ipt_standard entries[1];
+	struct ipt_standard entries[2];
 	struct ipt_error term;
 } initial_table __initdata = {
 	.repl = {
 		.name = "skfilter", 
 		.valid_hooks = SKFILTER_VALID_HOOKS, 
-		.num_entries = 2,
-		.size = sizeof(struct ipt_standard) * 1 + sizeof(struct ipt_error),
+		.num_entries = 3,
+		.size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
 		.hook_entry = { 
-			[NF_IP_LOCAL_IN] = 0,
+			[NF_IP_LOCAL_IN]	= 0,
+			[NF_IP_LOCAL_OUT]	= sizeof(struct ipt_standard),
 		},
 		.underflow = { 
-			[NF_IP_LOCAL_IN] = 0,
+			[NF_IP_LOCAL_IN]	= 0,
+			[NF_IP_LOCAL_OUT]       = sizeof(struct ipt_standard),
 		},
 	},
 	.entries = {
@@ -47,6 +49,21 @@ static struct
 			  .verdict = -NF_ACCEPT - 1,
 		     },
 	     },
+	     /* LOCAL_OUT */
+	     { 
+		     .entry = { 
+			     .target_offset = sizeof(struct ipt_entry),
+			     .next_offset = sizeof(struct ipt_standard),
+		     },
+		     .target = { 
+			  .target = { 
+				  .u = {
+					  .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
+				  },
+			  },
+			  .verdict = -NF_ACCEPT - 1,
+		     },
+	     },
 	},
 	/* ERROR */
 	.term = {
@@ -77,12 +94,12 @@ static struct ipt_table skfilter = { 
 
 /* The work comes in here from netfilter.c. */
 static unsigned int
-ipt_hook(unsigned int hook,
-         struct sock *sk,
-	 struct sk_buff **pskb,
-	 const struct net_device *in,
-	 const struct net_device *out,
-	 int (*okfn)(struct sock *, struct sk_buff *))
+ipt_sk_hook(unsigned int hook,
+            struct sock *sk,
+            struct sk_buff **pskb,
+            const struct net_device *in,
+            const struct net_device *out,
+            int (*okfn)(struct sock *, struct sk_buff *))
 {
 	unsigned int ret;
 	int pull = 0;
@@ -97,9 +114,19 @@ ipt_hook(unsigned int hook,
 	return ret;
 }
 
-static struct nf_sk_hook_ops ipt_ops[] = {
+static unsigned int
+ipt_hook(unsigned int hook,
+         struct sk_buff **pskb,
+         const struct net_device *in,
+         const struct net_device *out,
+         int (*okfn)(struct sk_buff *))
+{
+	return ipt_do_table(NULL, pskb, hook, in, out, &skfilter, NULL);
+}
+
+static struct nf_sk_hook_ops ipt_sk_ops[] = {
 	{
-		.hook		= ipt_hook,
+		.hook		= ipt_sk_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET, 
 		.hooknum	= NF_IP_LOCAL_IN,
@@ -107,6 +134,16 @@ static struct nf_sk_hook_ops ipt_ops[] =
 	},
 };
 
+static struct nf_hook_ops ipt_ops[] = {
+	{
+		.hook		= ipt_hook,
+		.owner		= THIS_MODULE,
+		.pf		= PF_INET, 
+		.hooknum	= NF_IP_LOCAL_OUT,
+		.priority	= NF_IP_PRI_FILTER,
+	},
+};
+
 static int __init init(void)
 {
 	int ret;
@@ -117,12 +154,18 @@ static int __init init(void)
 		return ret;
 
 	/* Register hooks */
-	ret = nf_register_sk_hook(&ipt_ops[0]);
+	ret = nf_register_sk_hook(&ipt_sk_ops[0]);
 	if (ret < 0)
 		goto cleanup_table;
 
+	ret = nf_register_hook(&ipt_ops[0]);
+	if (ret < 0)
+		goto cleanup_hook0;
+
 	return ret;
 
+ cleanup_hook0:
+	nf_unregister_sk_hook(&ipt_sk_ops[0]);
  cleanup_table:
 	ipt_unregister_table(&skfilter);
 
@@ -131,7 +174,8 @@ static int __init init(void)
 
 static void __exit fini(void)
 {
-	nf_unregister_sk_hook(&ipt_ops[0]);
+	nf_unregister_hook(&ipt_ops[0]);
+	nf_unregister_sk_hook(&ipt_sk_ops[0]);
 	ipt_unregister_table(&skfilter);
 }
 
#25 lore raw

Re: Netfilter socket hooks

Quoted 2 lines · James Morris

What about adding an output hook to the table? This would make it much easier to manage rules.

Sure. For symetry, I would prefer only to pass packets with skb->sk != NULL through OUTPUT and use skb->sk as socket argument to ipt_do_table(). But rule mangement is still tricky since only protocols which use sockets can be handled in the skfilter table. A more radical approach would be to use the socket hooks for filter/INPUT for all protocols with hooks - but I haven't thought much about this yet.

Regards
Patrick

#26 lore raw

PATCH 1/1 owner-socketlookup update for 2.6.12-rc3

In reply to James Morris

Here's an updated version of the patch (based on the latest pom-ng patch), had to uninline udp_v4_lookup().

---

include/net/tcp.h +1 -0
diff -purN -X dontdiff linux-2.6.12-rc3.s/include/net/tcp.h linux-2.6.12-rc3.w/include/net/tcp.h
@@ -159,6 +159,7 @@ extern struct tcp_bind_bucket *tcp_bucke
 extern void tcp_bucket_destroy(struct tcp_bind_bucket *tb);
 extern void tcp_bucket_unlock(struct sock *sk);
 extern int tcp_port_rover;
+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)
include/net/udp.h +2 -0
diff -purN -X dontdiff linux-2.6.12-rc3.s/include/net/udp.h linux-2.6.12-rc3.w/include/net/udp.h
@@ -74,6 +74,8 @@ extern int	udp_disconnect(struct sock *s
 extern unsigned int udp_poll(struct file *file, struct socket *sock,
 			     poll_table *wait);
 
+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
+
 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
 #define UDP_INC_STATS(field)		SNMP_INC_STATS(udp_statistics, field)
 #define UDP_INC_STATS_BH(field)		SNMP_INC_STATS_BH(udp_statistics, field)
net/ipv4/netfilter/ipt_owner.c +69 -24

171 lines not on this page · raw message

net/ipv4/udp.c +2 -2
diff -purN -X dontdiff linux-2.6.12-rc3.s/net/ipv4/udp.c linux-2.6.12-rc3.w/net/ipv4/udp.c
@@ -264,8 +264,7 @@ static struct sock *udp_v4_lookup_longwa
 	return result;
 }
 
-static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
-					     u32 daddr, u16 dport, int dif)
+struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
 {
 	struct sock *sk;
 
@@ -1570,6 +1569,7 @@ EXPORT_SYMBOL(udp_port_rover);
 EXPORT_SYMBOL(udp_prot);
 EXPORT_SYMBOL(udp_sendmsg);
 EXPORT_SYMBOL(udp_poll);
+EXPORT_SYMBOL(udp_v4_lookup);
 
 #ifdef CONFIG_PROC_FS
 EXPORT_SYMBOL(udp_proc_register);
maintainer
#27 lore raw

Re: [PATCH] owner-socketlookup update for 2.6.12-rc3

Quoted 2 lines · On Wed, 27 Apr 2005 02:04:04 -0400 (EDT) James Morris <[email protected]>…

Here's an updated version of the patch (based on the latest pom-ng patch), had to uninline udp_v4_lookup().

If you really want to do this, can we at least export it via some of the proto_ops infrastructure? We already have "hash" and "unhash", a "lookup" method could thus be added.

It still hurts my eyes to see the tcp_tw_bucket internals being referenced in netfilter code :-)

Or even:

extern struct sock *ip_lookup_socket(saddr, sport, daddr, dport);

And this new function knows TCP internals and does not return time-wait sockets and stuff like that.

What about an idea like that?

#28 lore raw

Re: [PATCH] owner-socketlookup update for 2.6.12-rc3

Quoted 2 lines

It still hurts my eyes to see the tcp_tw_bucket internals being referenced in netfilter code :-)

Is it even correct to make an exception (return 0, i.e. do not match) when a TW socket is hit? Conceptually, a TW socket is the same logical entity as its former "established and owned" socket - wouldn't one expect a rule accepting the established socket, to also match that socket in the TW phase?

Quoted 6 lines

Or even:

extern struct sock *ip_lookup_socket(saddr, sport, daddr, dport);

And this new function knows TCP internals and does not return time-wait sockets and stuff like that.

Hmm. In the light of the above, what about this:

int ip_socket_owner(struct sockowner *so, prot, src, sport, dst, dport) {}

with the 'struct sockowner *' an OUT parameter that is to be filled, and boolean found/notfound return.

struct sockowner {
... contains whatever the owner match needs to look at
};

This way, no sock internals need to be visible to the owner match.

To solve the mentioned conceptional TW problem, the tw sock must be extended

	struct sockowner *tw_ownerinfo;

and, for performance reasons, the normal sock would probably need a single DID_OWNER state bit, which would be set whenever the normal sock is queried by ip_socket_owner(). Finally, when the normal sock morphs into the tw sock, set

	tw_ownerinfo = sk->DID_OWNER ? X(sk) : 0

with X(sk) kmalloc()ing a struct sockowner, and initializing it like a call to ip_socket_owner() would.

Very convoluted, but what good is a matching feature that only sometimes works?

(or maybe I'm just silly?)

best regards
Patrick

#29 lore raw

Re: [PATCH] owner-socketlookup update for 2.6.12-rc3

Completely different question re semantics: what about listening sockets, and the incoming connection requests to them?

How would the initial SYN be classified by a LOCAL_IN owner match? Consider the case that a uid:0 process created the listening socket, then dropped to uid:1234 and execed a different binary.

best regards
Patrick