1 /* Kernel module to match various things tied to sockets associated with
2 locally generated outgoing packets.
4 Copyright (C) 2000 Marc Boucher
6 #include <linux/module.h>
7 #include <linux/skbuff.h>
8 #include <linux/file.h>
11 #include <linux/netfilter_ipv4/ipt_owner.h>
12 #include <linux/netfilter_ipv4/ip_tables.h>
15 match_comm(const struct sk_buff *skb, const char *comm)
17 struct task_struct *p;
18 struct files_struct *files;
21 read_lock(&tasklist_lock);
23 if(strncmp(p->comm, comm, sizeof(p->comm)))
29 read_lock(&files->file_lock);
30 for (i=0; i < files->max_fds; i++) {
31 if (fcheck_files(files, i) == skb->sk->socket->file) {
32 read_unlock(&files->file_lock);
34 read_unlock(&tasklist_lock);
38 read_unlock(&files->file_lock);
42 read_unlock(&tasklist_lock);
47 match_pid(const struct sk_buff *skb, pid_t pid)
49 struct task_struct *p;
50 struct files_struct *files;
53 read_lock(&tasklist_lock);
54 p = find_task_by_pid(pid);
60 read_lock(&files->file_lock);
61 for (i=0; i < files->max_fds; i++) {
62 if (fcheck_files(files, i) == skb->sk->socket->file) {
63 read_unlock(&files->file_lock);
65 read_unlock(&tasklist_lock);
69 read_unlock(&files->file_lock);
73 read_unlock(&tasklist_lock);
78 match_sid(const struct sk_buff *skb, pid_t sid)
80 struct task_struct *p;
81 struct file *file = skb->sk->socket->file;
84 read_lock(&tasklist_lock);
86 struct files_struct *files;
87 if (p->session != sid)
93 read_lock(&files->file_lock);
94 for (i=0; i < files->max_fds; i++) {
95 if (fcheck_files(files, i) == file) {
100 read_unlock(&files->file_lock);
106 read_unlock(&tasklist_lock);
112 match(const struct sk_buff *skb,
113 const struct net_device *in,
114 const struct net_device *out,
115 const void *matchinfo,
121 const struct ipt_owner_info *info = matchinfo;
123 if (!skb->sk || !skb->sk->socket || !skb->sk->socket->file)
126 if(info->match & IPT_OWNER_UID) {
127 if((skb->sk->socket->file->f_uid != info->uid) ^
128 !!(info->invert & IPT_OWNER_UID))
132 if(info->match & IPT_OWNER_GID) {
133 if((skb->sk->socket->file->f_gid != info->gid) ^
134 !!(info->invert & IPT_OWNER_GID))
138 if(info->match & IPT_OWNER_PID) {
139 if (!match_pid(skb, info->pid) ^
140 !!(info->invert & IPT_OWNER_PID))
144 if(info->match & IPT_OWNER_SID) {
145 if (!match_sid(skb, info->sid) ^
146 !!(info->invert & IPT_OWNER_SID))
150 if(info->match & IPT_OWNER_COMM) {
151 if (!match_comm(skb, info->comm) ^
152 !!(info->invert & IPT_OWNER_COMM))
160 checkentry(const char *tablename,
161 const struct ipt_ip *ip,
163 unsigned int matchsize,
164 unsigned int hook_mask)
167 & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
168 printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
172 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
175 /* files->file_lock can not be used in a BH */
176 if (((struct ipt_owner_info *)matchinfo)->match
177 & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
178 printk("ipt_owner: pid, sid and command matching is broken "
186 static struct ipt_match owner_match
187 = { { NULL, NULL }, "owner", &match, &checkentry, NULL, THIS_MODULE };
189 static int __init init(void)
191 return ipt_register_match(&owner_match);
194 static void __exit fini(void)
196 ipt_unregister_match(&owner_match);
201 MODULE_LICENSE("GPL");