Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.27 213 lines 5.8 kB view raw
1/* 2 * Kernel module to match various things tied to sockets associated with 3 * locally generated outgoing packets. 4 * 5 * (C) 2000 Marc Boucher <marc@mbsi.ca> 6 * 7 * Copyright © CC Computer Consultants GmbH, 2007 - 2008 8 * <jengelh@computergmbh.de> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14#include <linux/module.h> 15#include <linux/skbuff.h> 16#include <linux/file.h> 17#include <net/sock.h> 18#include <linux/netfilter/x_tables.h> 19#include <linux/netfilter/xt_owner.h> 20#include <linux/netfilter_ipv4/ipt_owner.h> 21#include <linux/netfilter_ipv6/ip6t_owner.h> 22 23static bool 24owner_mt_v0(const struct sk_buff *skb, const struct net_device *in, 25 const struct net_device *out, const struct xt_match *match, 26 const void *matchinfo, int offset, unsigned int protoff, 27 bool *hotdrop) 28{ 29 const struct ipt_owner_info *info = matchinfo; 30 const struct file *filp; 31 32 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 33 return false; 34 35 filp = skb->sk->sk_socket->file; 36 if (filp == NULL) 37 return false; 38 39 if (info->match & IPT_OWNER_UID) 40 if ((filp->f_uid != info->uid) ^ 41 !!(info->invert & IPT_OWNER_UID)) 42 return false; 43 44 if (info->match & IPT_OWNER_GID) 45 if ((filp->f_gid != info->gid) ^ 46 !!(info->invert & IPT_OWNER_GID)) 47 return false; 48 49 return true; 50} 51 52static bool 53owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in, 54 const struct net_device *out, const struct xt_match *match, 55 const void *matchinfo, int offset, unsigned int protoff, 56 bool *hotdrop) 57{ 58 const struct ip6t_owner_info *info = matchinfo; 59 const struct file *filp; 60 61 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 62 return false; 63 64 filp = skb->sk->sk_socket->file; 65 if (filp == NULL) 66 return false; 67 68 if (info->match & IP6T_OWNER_UID) 69 if ((filp->f_uid != info->uid) ^ 70 !!(info->invert & IP6T_OWNER_UID)) 71 return false; 72 73 if (info->match & IP6T_OWNER_GID) 74 if ((filp->f_gid != info->gid) ^ 75 !!(info->invert & IP6T_OWNER_GID)) 76 return false; 77 78 return true; 79} 80 81static bool 82owner_mt(const struct sk_buff *skb, const struct net_device *in, 83 const struct net_device *out, const struct xt_match *match, 84 const void *matchinfo, int offset, unsigned int protoff, 85 bool *hotdrop) 86{ 87 const struct xt_owner_match_info *info = matchinfo; 88 const struct file *filp; 89 90 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 91 return (info->match ^ info->invert) == 0; 92 else if (info->match & info->invert & XT_OWNER_SOCKET) 93 /* 94 * Socket exists but user wanted ! --socket-exists. 95 * (Single ampersands intended.) 96 */ 97 return false; 98 99 filp = skb->sk->sk_socket->file; 100 if (filp == NULL) 101 return ((info->match ^ info->invert) & 102 (XT_OWNER_UID | XT_OWNER_GID)) == 0; 103 104 if (info->match & XT_OWNER_UID) 105 if ((filp->f_uid >= info->uid_min && 106 filp->f_uid <= info->uid_max) ^ 107 !(info->invert & XT_OWNER_UID)) 108 return false; 109 110 if (info->match & XT_OWNER_GID) 111 if ((filp->f_gid >= info->gid_min && 112 filp->f_gid <= info->gid_max) ^ 113 !(info->invert & XT_OWNER_GID)) 114 return false; 115 116 return true; 117} 118 119static bool 120owner_mt_check_v0(const char *tablename, const void *ip, 121 const struct xt_match *match, void *matchinfo, 122 unsigned int hook_mask) 123{ 124 const struct ipt_owner_info *info = matchinfo; 125 126 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { 127 printk(KERN_WARNING KBUILD_MODNAME 128 ": PID, SID and command matching is not " 129 "supported anymore\n"); 130 return false; 131 } 132 133 return true; 134} 135 136static bool 137owner_mt6_check_v0(const char *tablename, const void *ip, 138 const struct xt_match *match, void *matchinfo, 139 unsigned int hook_mask) 140{ 141 const struct ip6t_owner_info *info = matchinfo; 142 143 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { 144 printk(KERN_WARNING KBUILD_MODNAME 145 ": PID and SID matching is not supported anymore\n"); 146 return false; 147 } 148 149 return true; 150} 151 152static struct xt_match owner_mt_reg[] __read_mostly = { 153 { 154 .name = "owner", 155 .revision = 0, 156 .family = AF_INET, 157 .match = owner_mt_v0, 158 .matchsize = sizeof(struct ipt_owner_info), 159 .checkentry = owner_mt_check_v0, 160 .hooks = (1 << NF_INET_LOCAL_OUT) | 161 (1 << NF_INET_POST_ROUTING), 162 .me = THIS_MODULE, 163 }, 164 { 165 .name = "owner", 166 .revision = 0, 167 .family = AF_INET6, 168 .match = owner_mt6_v0, 169 .matchsize = sizeof(struct ip6t_owner_info), 170 .checkentry = owner_mt6_check_v0, 171 .hooks = (1 << NF_INET_LOCAL_OUT) | 172 (1 << NF_INET_POST_ROUTING), 173 .me = THIS_MODULE, 174 }, 175 { 176 .name = "owner", 177 .revision = 1, 178 .family = AF_INET, 179 .match = owner_mt, 180 .matchsize = sizeof(struct xt_owner_match_info), 181 .hooks = (1 << NF_INET_LOCAL_OUT) | 182 (1 << NF_INET_POST_ROUTING), 183 .me = THIS_MODULE, 184 }, 185 { 186 .name = "owner", 187 .revision = 1, 188 .family = AF_INET6, 189 .match = owner_mt, 190 .matchsize = sizeof(struct xt_owner_match_info), 191 .hooks = (1 << NF_INET_LOCAL_OUT) | 192 (1 << NF_INET_POST_ROUTING), 193 .me = THIS_MODULE, 194 }, 195}; 196 197static int __init owner_mt_init(void) 198{ 199 return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); 200} 201 202static void __exit owner_mt_exit(void) 203{ 204 xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); 205} 206 207module_init(owner_mt_init); 208module_exit(owner_mt_exit); 209MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 210MODULE_DESCRIPTION("Xtables: socket owner matching"); 211MODULE_LICENSE("GPL"); 212MODULE_ALIAS("ipt_owner"); 213MODULE_ALIAS("ip6t_owner");