diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-18 00:50:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:58:36 -0500 |
commit | 3bc3fe5eed5e866c0871db6d745f3bf58af004ef (patch) | |
tree | 01c1906660209aeebd21307d61b5078d37e5baed /net/compat.c | |
parent | d924357c50d83e76d30dd5b81b5804815a2ae31c (diff) |
[NETFILTER]: ip6_tables: add compat support
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/compat.c')
-rw-r--r-- | net/compat.c | 106 |
1 files changed, 0 insertions, 106 deletions
diff --git a/net/compat.c b/net/compat.c index f4ef4c048652..80013fb69a61 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/syscalls.h> | 20 | #include <linux/syscalls.h> |
21 | #include <linux/filter.h> | 21 | #include <linux/filter.h> |
22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
23 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
24 | #include <linux/security.h> | 23 | #include <linux/security.h> |
25 | 24 | ||
26 | #include <net/scm.h> | 25 | #include <net/scm.h> |
@@ -317,107 +316,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) | |||
317 | } | 316 | } |
318 | 317 | ||
319 | /* | 318 | /* |
320 | * For now, we assume that the compatibility and native version | ||
321 | * of struct ipt_entry are the same - sfr. FIXME | ||
322 | */ | ||
323 | struct compat_ipt_replace { | ||
324 | char name[IPT_TABLE_MAXNAMELEN]; | ||
325 | u32 valid_hooks; | ||
326 | u32 num_entries; | ||
327 | u32 size; | ||
328 | u32 hook_entry[NF_INET_NUMHOOKS]; | ||
329 | u32 underflow[NF_INET_NUMHOOKS]; | ||
330 | u32 num_counters; | ||
331 | compat_uptr_t counters; /* struct ipt_counters * */ | ||
332 | struct ipt_entry entries[0]; | ||
333 | }; | ||
334 | |||
335 | static int do_netfilter_replace(int fd, int level, int optname, | ||
336 | char __user *optval, int optlen) | ||
337 | { | ||
338 | struct compat_ipt_replace __user *urepl; | ||
339 | struct ipt_replace __user *repl_nat; | ||
340 | char name[IPT_TABLE_MAXNAMELEN]; | ||
341 | u32 origsize, tmp32, num_counters; | ||
342 | unsigned int repl_nat_size; | ||
343 | int ret; | ||
344 | int i; | ||
345 | compat_uptr_t ucntrs; | ||
346 | |||
347 | urepl = (struct compat_ipt_replace __user *)optval; | ||
348 | if (get_user(origsize, &urepl->size)) | ||
349 | return -EFAULT; | ||
350 | |||
351 | /* Hack: Causes ipchains to give correct error msg --RR */ | ||
352 | if (optlen != sizeof(*urepl) + origsize) | ||
353 | return -ENOPROTOOPT; | ||
354 | |||
355 | /* XXX Assumes that size of ipt_entry is the same both in | ||
356 | * native and compat environments. | ||
357 | */ | ||
358 | repl_nat_size = sizeof(*repl_nat) + origsize; | ||
359 | repl_nat = compat_alloc_user_space(repl_nat_size); | ||
360 | |||
361 | ret = -EFAULT; | ||
362 | if (put_user(origsize, &repl_nat->size)) | ||
363 | goto out; | ||
364 | |||
365 | if (!access_ok(VERIFY_READ, urepl, optlen) || | ||
366 | !access_ok(VERIFY_WRITE, repl_nat, optlen)) | ||
367 | goto out; | ||
368 | |||
369 | if (__copy_from_user(name, urepl->name, sizeof(urepl->name)) || | ||
370 | __copy_to_user(repl_nat->name, name, sizeof(repl_nat->name))) | ||
371 | goto out; | ||
372 | |||
373 | if (__get_user(tmp32, &urepl->valid_hooks) || | ||
374 | __put_user(tmp32, &repl_nat->valid_hooks)) | ||
375 | goto out; | ||
376 | |||
377 | if (__get_user(tmp32, &urepl->num_entries) || | ||
378 | __put_user(tmp32, &repl_nat->num_entries)) | ||
379 | goto out; | ||
380 | |||
381 | if (__get_user(num_counters, &urepl->num_counters) || | ||
382 | __put_user(num_counters, &repl_nat->num_counters)) | ||
383 | goto out; | ||
384 | |||
385 | if (__get_user(ucntrs, &urepl->counters) || | ||
386 | __put_user(compat_ptr(ucntrs), &repl_nat->counters)) | ||
387 | goto out; | ||
388 | |||
389 | if (__copy_in_user(&repl_nat->entries[0], | ||
390 | &urepl->entries[0], | ||
391 | origsize)) | ||
392 | goto out; | ||
393 | |||
394 | for (i = 0; i < NF_INET_NUMHOOKS; i++) { | ||
395 | if (__get_user(tmp32, &urepl->hook_entry[i]) || | ||
396 | __put_user(tmp32, &repl_nat->hook_entry[i]) || | ||
397 | __get_user(tmp32, &urepl->underflow[i]) || | ||
398 | __put_user(tmp32, &repl_nat->underflow[i])) | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Since struct ipt_counters just contains two u_int64_t members | ||
404 | * we can just do the access_ok check here and pass the (converted) | ||
405 | * pointer into the standard syscall. We hope that the pointer is | ||
406 | * not misaligned ... | ||
407 | */ | ||
408 | if (!access_ok(VERIFY_WRITE, compat_ptr(ucntrs), | ||
409 | num_counters * sizeof(struct ipt_counters))) | ||
410 | goto out; | ||
411 | |||
412 | |||
413 | ret = sys_setsockopt(fd, level, optname, | ||
414 | (char __user *)repl_nat, repl_nat_size); | ||
415 | |||
416 | out: | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * A struct sock_filter is architecture independent. | 319 | * A struct sock_filter is architecture independent. |
422 | */ | 320 | */ |
423 | struct compat_sock_fprog { | 321 | struct compat_sock_fprog { |
@@ -485,10 +383,6 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, | |||
485 | int err; | 383 | int err; |
486 | struct socket *sock; | 384 | struct socket *sock; |
487 | 385 | ||
488 | if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE) | ||
489 | return do_netfilter_replace(fd, level, optname, | ||
490 | optval, optlen); | ||
491 | |||
492 | if (optlen < 0) | 386 | if (optlen < 0) |
493 | return -EINVAL; | 387 | return -EINVAL; |
494 | 388 | ||