diff options
author | Christoph Hellwig <hch@lst.de> | 2005-08-14 20:33:59 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:59:07 -0400 |
commit | 34b4a4a624bafe089107966a6c56d2a1aca026d4 (patch) | |
tree | d0546ea54dc1f7169447133df89e1512eb48ae39 | |
parent | 000efe1d86620244b8e017429e57fab4170ab05a (diff) |
[NETFILTER]: Remove tasklist_lock abuse in ipt{,6}owner
Rip out cmd/sid/pid matching since its unfixable broken and stands in the
way of locking changes to tasklist_lock.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ipt_owner.c | 132 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_owner.c | 90 |
2 files changed, 14 insertions, 208 deletions
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c index 3b9065e06381..c1889f88262b 100644 --- a/net/ipv4/netfilter/ipt_owner.c +++ b/net/ipv4/netfilter/ipt_owner.c | |||
@@ -21,106 +21,6 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | |||
21 | MODULE_DESCRIPTION("iptables owner match"); | 21 | MODULE_DESCRIPTION("iptables owner match"); |
22 | 22 | ||
23 | static int | 23 | static int |
24 | match_comm(const struct sk_buff *skb, const char *comm) | ||
25 | { | ||
26 | struct task_struct *g, *p; | ||
27 | struct files_struct *files; | ||
28 | int i; | ||
29 | |||
30 | read_lock(&tasklist_lock); | ||
31 | do_each_thread(g, p) { | ||
32 | if(strncmp(p->comm, comm, sizeof(p->comm))) | ||
33 | continue; | ||
34 | |||
35 | task_lock(p); | ||
36 | files = p->files; | ||
37 | if(files) { | ||
38 | spin_lock(&files->file_lock); | ||
39 | for (i=0; i < files->max_fds; i++) { | ||
40 | if (fcheck_files(files, i) == | ||
41 | skb->sk->sk_socket->file) { | ||
42 | spin_unlock(&files->file_lock); | ||
43 | task_unlock(p); | ||
44 | read_unlock(&tasklist_lock); | ||
45 | return 1; | ||
46 | } | ||
47 | } | ||
48 | spin_unlock(&files->file_lock); | ||
49 | } | ||
50 | task_unlock(p); | ||
51 | } while_each_thread(g, p); | ||
52 | read_unlock(&tasklist_lock); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int | ||
57 | match_pid(const struct sk_buff *skb, pid_t pid) | ||
58 | { | ||
59 | struct task_struct *p; | ||
60 | struct files_struct *files; | ||
61 | int i; | ||
62 | |||
63 | read_lock(&tasklist_lock); | ||
64 | p = find_task_by_pid(pid); | ||
65 | if (!p) | ||
66 | goto out; | ||
67 | task_lock(p); | ||
68 | files = p->files; | ||
69 | if(files) { | ||
70 | spin_lock(&files->file_lock); | ||
71 | for (i=0; i < files->max_fds; i++) { | ||
72 | if (fcheck_files(files, i) == | ||
73 | skb->sk->sk_socket->file) { | ||
74 | spin_unlock(&files->file_lock); | ||
75 | task_unlock(p); | ||
76 | read_unlock(&tasklist_lock); | ||
77 | return 1; | ||
78 | } | ||
79 | } | ||
80 | spin_unlock(&files->file_lock); | ||
81 | } | ||
82 | task_unlock(p); | ||
83 | out: | ||
84 | read_unlock(&tasklist_lock); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int | ||
89 | match_sid(const struct sk_buff *skb, pid_t sid) | ||
90 | { | ||
91 | struct task_struct *g, *p; | ||
92 | struct file *file = skb->sk->sk_socket->file; | ||
93 | int i, found=0; | ||
94 | |||
95 | read_lock(&tasklist_lock); | ||
96 | do_each_thread(g, p) { | ||
97 | struct files_struct *files; | ||
98 | if (p->signal->session != sid) | ||
99 | continue; | ||
100 | |||
101 | task_lock(p); | ||
102 | files = p->files; | ||
103 | if (files) { | ||
104 | spin_lock(&files->file_lock); | ||
105 | for (i=0; i < files->max_fds; i++) { | ||
106 | if (fcheck_files(files, i) == file) { | ||
107 | found = 1; | ||
108 | break; | ||
109 | } | ||
110 | } | ||
111 | spin_unlock(&files->file_lock); | ||
112 | } | ||
113 | task_unlock(p); | ||
114 | if (found) | ||
115 | goto out; | ||
116 | } while_each_thread(g, p); | ||
117 | out: | ||
118 | read_unlock(&tasklist_lock); | ||
119 | |||
120 | return found; | ||
121 | } | ||
122 | |||
123 | static int | ||
124 | match(const struct sk_buff *skb, | 24 | match(const struct sk_buff *skb, |
125 | const struct net_device *in, | 25 | const struct net_device *in, |
126 | const struct net_device *out, | 26 | const struct net_device *out, |
@@ -145,24 +45,6 @@ match(const struct sk_buff *skb, | |||
145 | return 0; | 45 | return 0; |
146 | } | 46 | } |
147 | 47 | ||
148 | if(info->match & IPT_OWNER_PID) { | ||
149 | if (!match_pid(skb, info->pid) ^ | ||
150 | !!(info->invert & IPT_OWNER_PID)) | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | if(info->match & IPT_OWNER_SID) { | ||
155 | if (!match_sid(skb, info->sid) ^ | ||
156 | !!(info->invert & IPT_OWNER_SID)) | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | if(info->match & IPT_OWNER_COMM) { | ||
161 | if (!match_comm(skb, info->comm) ^ | ||
162 | !!(info->invert & IPT_OWNER_COMM)) | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | return 1; | 48 | return 1; |
167 | } | 49 | } |
168 | 50 | ||
@@ -173,6 +55,8 @@ checkentry(const char *tablename, | |||
173 | unsigned int matchsize, | 55 | unsigned int matchsize, |
174 | unsigned int hook_mask) | 56 | unsigned int hook_mask) |
175 | { | 57 | { |
58 | const struct ipt_owner_info *info = matchinfo; | ||
59 | |||
176 | if (hook_mask | 60 | if (hook_mask |
177 | & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) { | 61 | & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) { |
178 | printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); | 62 | printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); |
@@ -184,15 +68,13 @@ checkentry(const char *tablename, | |||
184 | IPT_ALIGN(sizeof(struct ipt_owner_info))); | 68 | IPT_ALIGN(sizeof(struct ipt_owner_info))); |
185 | return 0; | 69 | return 0; |
186 | } | 70 | } |
187 | #ifdef CONFIG_SMP | 71 | |
188 | /* files->file_lock can not be used in a BH */ | 72 | if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) { |
189 | if (((struct ipt_owner_info *)matchinfo)->match | 73 | printk("ipt_owner: pid, sid and command matching " |
190 | & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) { | 74 | "not supported anymore\n"); |
191 | printk("ipt_owner: pid, sid and command matching is broken " | ||
192 | "on SMP.\n"); | ||
193 | return 0; | 75 | return 0; |
194 | } | 76 | } |
195 | #endif | 77 | |
196 | return 1; | 78 | return 1; |
197 | } | 79 | } |
198 | 80 | ||
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c index ab0e32d3de46..9b91decbfddb 100644 --- a/net/ipv6/netfilter/ip6t_owner.c +++ b/net/ipv6/netfilter/ip6t_owner.c | |||
@@ -20,71 +20,6 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | |||
20 | MODULE_DESCRIPTION("IP6 tables owner matching module"); | 20 | MODULE_DESCRIPTION("IP6 tables owner matching module"); |
21 | MODULE_LICENSE("GPL"); | 21 | MODULE_LICENSE("GPL"); |
22 | 22 | ||
23 | static int | ||
24 | match_pid(const struct sk_buff *skb, pid_t pid) | ||
25 | { | ||
26 | struct task_struct *p; | ||
27 | struct files_struct *files; | ||
28 | int i; | ||
29 | |||
30 | read_lock(&tasklist_lock); | ||
31 | p = find_task_by_pid(pid); | ||
32 | if (!p) | ||
33 | goto out; | ||
34 | task_lock(p); | ||
35 | files = p->files; | ||
36 | if(files) { | ||
37 | spin_lock(&files->file_lock); | ||
38 | for (i=0; i < files->max_fds; i++) { | ||
39 | if (fcheck_files(files, i) == skb->sk->sk_socket->file) { | ||
40 | spin_unlock(&files->file_lock); | ||
41 | task_unlock(p); | ||
42 | read_unlock(&tasklist_lock); | ||
43 | return 1; | ||
44 | } | ||
45 | } | ||
46 | spin_unlock(&files->file_lock); | ||
47 | } | ||
48 | task_unlock(p); | ||
49 | out: | ||
50 | read_unlock(&tasklist_lock); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static int | ||
55 | match_sid(const struct sk_buff *skb, pid_t sid) | ||
56 | { | ||
57 | struct task_struct *g, *p; | ||
58 | struct file *file = skb->sk->sk_socket->file; | ||
59 | int i, found=0; | ||
60 | |||
61 | read_lock(&tasklist_lock); | ||
62 | do_each_thread(g, p) { | ||
63 | struct files_struct *files; | ||
64 | if (p->signal->session != sid) | ||
65 | continue; | ||
66 | |||
67 | task_lock(p); | ||
68 | files = p->files; | ||
69 | if (files) { | ||
70 | spin_lock(&files->file_lock); | ||
71 | for (i=0; i < files->max_fds; i++) { | ||
72 | if (fcheck_files(files, i) == file) { | ||
73 | found = 1; | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | spin_unlock(&files->file_lock); | ||
78 | } | ||
79 | task_unlock(p); | ||
80 | if (found) | ||
81 | goto out; | ||
82 | } while_each_thread(g, p); | ||
83 | out: | ||
84 | read_unlock(&tasklist_lock); | ||
85 | |||
86 | return found; | ||
87 | } | ||
88 | 23 | ||
89 | static int | 24 | static int |
90 | match(const struct sk_buff *skb, | 25 | match(const struct sk_buff *skb, |
@@ -112,18 +47,6 @@ match(const struct sk_buff *skb, | |||
112 | return 0; | 47 | return 0; |
113 | } | 48 | } |
114 | 49 | ||
115 | if(info->match & IP6T_OWNER_PID) { | ||
116 | if (!match_pid(skb, info->pid) ^ | ||
117 | !!(info->invert & IP6T_OWNER_PID)) | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | if(info->match & IP6T_OWNER_SID) { | ||
122 | if (!match_sid(skb, info->sid) ^ | ||
123 | !!(info->invert & IP6T_OWNER_SID)) | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | return 1; | 50 | return 1; |
128 | } | 51 | } |
129 | 52 | ||
@@ -134,6 +57,8 @@ checkentry(const char *tablename, | |||
134 | unsigned int matchsize, | 57 | unsigned int matchsize, |
135 | unsigned int hook_mask) | 58 | unsigned int hook_mask) |
136 | { | 59 | { |
60 | const struct ip6t_owner_info *info = matchinfo; | ||
61 | |||
137 | if (hook_mask | 62 | if (hook_mask |
138 | & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) { | 63 | & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) { |
139 | printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); | 64 | printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); |
@@ -142,14 +67,13 @@ checkentry(const char *tablename, | |||
142 | 67 | ||
143 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info))) | 68 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info))) |
144 | return 0; | 69 | return 0; |
145 | #ifdef CONFIG_SMP | 70 | |
146 | /* files->file_lock can not be used in a BH */ | 71 | if (info->match & (IP6T_OWNER_PID|IP6T_OWNER_SID)) { |
147 | if (((struct ip6t_owner_info *)matchinfo)->match | 72 | printk("ipt_owner: pid and sid matching " |
148 | & (IP6T_OWNER_PID|IP6T_OWNER_SID)) { | 73 | "not supported anymore\n"); |
149 | printk("ip6t_owner: pid and sid matching is broken on SMP.\n"); | ||
150 | return 0; | 74 | return 0; |
151 | } | 75 | } |
152 | #endif | 76 | |
153 | return 1; | 77 | return 1; |
154 | } | 78 | } |
155 | 79 | ||