From 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 16 Apr 2005 15:20:36 -0700 Subject: Linux-2.6.12-rc2 Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip! --- net/ipv6/netfilter/ip6t_owner.c | 174 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 net/ipv6/netfilter/ip6t_owner.c (limited to 'net/ipv6/netfilter/ip6t_owner.c') diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c new file mode 100644 index 00000000000..ab0e32d3de4 --- /dev/null +++ b/net/ipv6/netfilter/ip6t_owner.c @@ -0,0 +1,174 @@ +/* Kernel module to match various things tied to sockets associated with + locally generated outgoing packets. */ + +/* (C) 2000-2001 Marc Boucher + * + * 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. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("IP6 tables owner matching module"); +MODULE_LICENSE("GPL"); + +static int +match_pid(const struct sk_buff *skb, pid_t pid) +{ + struct task_struct *p; + struct files_struct *files; + int i; + + read_lock(&tasklist_lock); + p = find_task_by_pid(pid); + if (!p) + goto out; + 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); + return 1; + } + } + spin_unlock(&files->file_lock); + } + task_unlock(p); +out: + read_unlock(&tasklist_lock); + return 0; +} + +static int +match_sid(const struct sk_buff *skb, pid_t sid) +{ + struct task_struct *g, *p; + struct file *file = skb->sk->sk_socket->file; + int i, found=0; + + read_lock(&tasklist_lock); + do_each_thread(g, p) { + struct files_struct *files; + if (p->signal->session != sid) + continue; + + 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) == file) { + found = 1; + break; + } + } + spin_unlock(&files->file_lock); + } + task_unlock(p); + if (found) + goto out; + } while_each_thread(g, p); +out: + read_unlock(&tasklist_lock); + + return found; +} + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + const struct ip6t_owner_info *info = matchinfo; + + if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file) + return 0; + + if(info->match & IP6T_OWNER_UID) { + if((skb->sk->sk_socket->file->f_uid != info->uid) ^ + !!(info->invert & IP6T_OWNER_UID)) + return 0; + } + + if(info->match & IP6T_OWNER_GID) { + if((skb->sk->sk_socket->file->f_gid != info->gid) ^ + !!(info->invert & IP6T_OWNER_GID)) + return 0; + } + + if(info->match & IP6T_OWNER_PID) { + if (!match_pid(skb, info->pid) ^ + !!(info->invert & IP6T_OWNER_PID)) + return 0; + } + + if(info->match & IP6T_OWNER_SID) { + if (!match_sid(skb, info->sid) ^ + !!(info->invert & IP6T_OWNER_SID)) + return 0; + } + + return 1; +} + +static int +checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (hook_mask + & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) { + printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); + return 0; + } + + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info))) + return 0; +#ifdef CONFIG_SMP + /* files->file_lock can not be used in a BH */ + if (((struct ip6t_owner_info *)matchinfo)->match + & (IP6T_OWNER_PID|IP6T_OWNER_SID)) { + printk("ip6t_owner: pid and sid matching is broken on SMP.\n"); + return 0; + } +#endif + return 1; +} + +static struct ip6t_match owner_match = { + .name = "owner", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ip6t_register_match(&owner_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&owner_match); +} + +module_init(init); +module_exit(fini); -- cgit v1.2.3