1 /* 2 * Packet matching code. 3 * 4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 5 * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 6 * Copyright (c) 2006-2010 Patrick McHardy <kaber@trash.net> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 15 #include <linux/kernel.h> 16 #include <linux/capability.h> 17 #include <linux/in.h> 18 #include <linux/skbuff.h> 19 #include <linux/kmod.h> 20 #include <linux/vmalloc.h> 21 #include <linux/netdevice.h> 22 #include <linux/module.h> 23 #include <linux/poison.h> 24 #include <linux/icmpv6.h> 25 #include <net/ipv6.h> 26 #include <net/compat.h> 27 #include <linux/uaccess.h> 28 #include <linux/mutex.h> 29 #include <linux/proc_fs.h> 30 #include <linux/err.h> 31 #include <linux/cpumask.h> 32 33 #include <linux/netfilter_ipv6/ip6_tables.h> 34 #include <linux/netfilter/x_tables.h> 35 #include <net/netfilter/nf_log.h> 36 #include "../../netfilter/xt_repldata.h" 37 38 MODULE_LICENSE("GPL"); 39 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 40 MODULE_DESCRIPTION("IPv6 packet filter"); 41 MODULE_ALIAS("ip6t_icmp6"); 42 43 void *ip6t_alloc_initial_table(const struct xt_table *info) 44 { 45 return xt_alloc_initial_table(ip6t, IP6T); 46 } 47 EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); 48 49 /* Returns whether matches rule or not. */ 50 /* Performance critical - called for every packet */ 51 static inline bool 52 ip6_packet_match(const struct sk_buff *skb, 53 const char *indev, 54 const char *outdev, 55 const struct ip6t_ip6 *ip6info, 56 unsigned int *protoff, 57 int *fragoff, bool *hotdrop) 58 { 59 unsigned long ret; 60 const struct ipv6hdr *ipv6 = ipv6_hdr(skb); 61 62 if (NF_INVF(ip6info, IP6T_INV_SRCIP, 63 ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk, 64 &ip6info->src)) || 65 NF_INVF(ip6info, IP6T_INV_DSTIP, 66 ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, 67 &ip6info->dst))) 68 return false; 69 70 ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask); 71 72 if (NF_INVF(ip6info, IP6T_INV_VIA_IN, ret != 0)) 73 return false; 74 75 ret = ifname_compare_aligned(outdev, ip6info->outiface, ip6info->outiface_mask); 76 77 if (NF_INVF(ip6info, IP6T_INV_VIA_OUT, ret != 0)) 78 return false; 79 80 /* ... might want to do something with class and flowlabel here ... */ 81 82 /* look for the desired protocol header */ 83 if (ip6info->flags & IP6T_F_PROTO) { 84 int protohdr; 85 unsigned short _frag_off; 86 87 protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off, NULL); 88 if (protohdr < 0) { 89 if (_frag_off == 0) 90 *hotdrop = true; 91 return false; 92 } 93 *fragoff = _frag_off; 94 95 if (ip6info->proto == protohdr) { 96 if (ip6info->invflags & IP6T_INV_PROTO) 97 return false; 98 99 return true; 100 } 101 102 /* We need match for the '-p all', too! */ 103 if ((ip6info->proto != 0) && 104 !(ip6info->invflags & IP6T_INV_PROTO)) 105 return false; 106 } 107 return true; 108 } 109 110 /* should be ip6 safe */ 111 static bool 112 ip6_checkentry(const struct ip6t_ip6 *ipv6) 113 { 114 if (ipv6->flags & ~IP6T_F_MASK) 115 return false; 116 if (ipv6->invflags & ~IP6T_INV_MASK) 117 return false; 118 119 return true; 120 } 121 122 static unsigned int 123 ip6t_error(struct sk_buff *skb, const struct xt_action_param *par) 124 { 125 net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo); 126 127 return NF_DROP; 128 } 129 130 static inline struct ip6t_entry * 131 get_entry(const void *base, unsigned int offset) 132 { 133 return (struct ip6t_entry *)(base + offset); 134 } 135 136 /* All zeroes == unconditional rule. */ 137 /* Mildly perf critical (only if packet tracing is on) */ 138 static inline bool unconditional(const struct ip6t_entry *e) 139 { 140 static const struct ip6t_ip6 uncond; 141 142 return e->target_offset == sizeof(struct ip6t_entry) && 143 memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; 144 } 145 146 static inline const struct xt_entry_target * 147 ip6t_get_target_c(const struct ip6t_entry *e) 148 { 149 return ip6t_get_target((struct ip6t_entry *)e); 150 } 151 152 #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 153 /* This cries for unification! */ 154 static const char *const hooknames[] = { 155 [NF_INET_PRE_ROUTING] = "PREROUTING", 156 [NF_INET_LOCAL_IN] = "INPUT", 157 [NF_INET_FORWARD] = "FORWARD", 158 [NF_INET_LOCAL_OUT] = "OUTPUT", 159 [NF_INET_POST_ROUTING] = "POSTROUTING", 160 }; 161 162 enum nf_ip_trace_comments { 163 NF_IP6_TRACE_COMMENT_RULE, 164 NF_IP6_TRACE_COMMENT_RETURN, 165 NF_IP6_TRACE_COMMENT_POLICY, 166 }; 167 168 static const char *const comments[] = { 169 [NF_IP6_TRACE_COMMENT_RULE] = "rule", 170 [NF_IP6_TRACE_COMMENT_RETURN] = "return", 171 [NF_IP6_TRACE_COMMENT_POLICY] = "policy", 172 }; 173 174 static const struct nf_loginfo trace_loginfo = { 175 .type = NF_LOG_TYPE_LOG, 176 .u = { 177 .log = { 178 .level = LOGLEVEL_WARNING, 179 .logflags = NF_LOG_DEFAULT_MASK, 180 }, 181 }, 182 }; 183 184 /* Mildly perf critical (only if packet tracing is on) */ 185 static inline int 186 get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, 187 const char *hookname, const char **chainname, 188 const char **comment, unsigned int *rulenum) 189 { 190 const struct xt_standard_target *t = (void *)ip6t_get_target_c(s); 191 192 if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { 193 /* Head of user chain: ERROR target with chainname */ 194 *chainname = t->target.data; 195 (*rulenum) = 0; 196 } else if (s == e) { 197 (*rulenum)++; 198 199 if (unconditional(s) && 200 strcmp(t->target.u.kernel.target->name, 201 XT_STANDARD_TARGET) == 0 && 202 t->verdict < 0) { 203 /* Tail of chains: STANDARD target (return/policy) */ 204 *comment = *chainname == hookname 205 ? comments[NF_IP6_TRACE_COMMENT_POLICY] 206 : comments[NF_IP6_TRACE_COMMENT_RETURN]; 207 } 208 return 1; 209 } else 210 (*rulenum)++; 211 212 return 0; 213 } 214 215 static void trace_packet(struct net *net, 216 const struct sk_buff *skb, 217 unsigned int hook, 218 const struct net_device *in, 219 const struct net_device *out, 220 const char *tablename, 221 const struct xt_table_info *private, 222 const struct ip6t_entry *e) 223 { 224 const struct ip6t_entry *root; 225 const char *hookname, *chainname, *comment; 226 const struct ip6t_entry *iter; 227 unsigned int rulenum = 0; 228 229 root = get_entry(private->entries, private->hook_entry[hook]); 230 231 hookname = chainname = hooknames[hook]; 232 comment = comments[NF_IP6_TRACE_COMMENT_RULE]; 233 234 xt_entry_foreach(iter, root, private->size - private->hook_entry[hook]) 235 if (get_chainname_rulenum(iter, e, hookname, 236 &chainname, &comment, &rulenum) != 0) 237 break; 238 239 nf_log_trace(net, AF_INET6, hook, skb, in, out, &trace_loginfo, 240 "TRACE: %s:%s:%s:%u ", 241 tablename, chainname, comment, rulenum); 242 } 243 #endif 244 245 static inline struct ip6t_entry * 246 ip6t_next_entry(const struct ip6t_entry *entry) 247 { 248 return (void *)entry + entry->next_offset; 249 } 250 251 /* Returns one of the generic firewall policies, like NF_ACCEPT. */ 252 unsigned int 253 ip6t_do_table(struct sk_buff *skb, 254 const struct nf_hook_state *state, 255 struct xt_table *table) 256 { 257 unsigned int hook = state->hook; 258 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 259 /* Initializing verdict to NF_DROP keeps gcc happy. */ 260 unsigned int verdict = NF_DROP; 261 const char *indev, *outdev; 262 const void *table_base; 263 struct ip6t_entry *e, **jumpstack; 264 unsigned int stackidx, cpu; 265 const struct xt_table_info *private; 266 struct xt_action_param acpar; 267 unsigned int addend; 268 269 /* Initialization */ 270 stackidx = 0; 271 indev = state->in ? state->in->name : nulldevname; 272 outdev = state->out ? state->out->name : nulldevname; 273 /* We handle fragments by dealing with the first fragment as 274 * if it was a normal packet. All other fragments are treated 275 * normally, except that they will NEVER match rules that ask 276 * things we don't know, ie. tcp syn flag or ports). If the 277 * rule is also a fragment-specific rule, non-fragments won't 278 * match it. */ 279 acpar.hotdrop = false; 280 acpar.state = state; 281 282 WARN_ON(!(table->valid_hooks & (1 << hook))); 283 284 local_bh_disable(); 285 addend = xt_write_recseq_begin(); 286 private = READ_ONCE(table->private); /* Address dependency. */ 287 cpu = smp_processor_id(); 288 table_base = private->entries; 289 jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; 290 291 /* Switch to alternate jumpstack if we're being invoked via TEE. 292 * TEE issues XT_CONTINUE verdict on original skb so we must not 293 * clobber the jumpstack. 294 * 295 * For recursion via REJECT or SYNPROXY the stack will be clobbered 296 * but it is no problem since absolute verdict is issued by these. 297 */ 298 if (static_key_false(&xt_tee_enabled)) 299 jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); 300 301 e = get_entry(table_base, private->hook_entry[hook]); 302 303 do { 304 const struct xt_entry_target *t; 305 const struct xt_entry_match *ematch; 306 struct xt_counters *counter; 307 308 WARN_ON(!e); 309 acpar.thoff = 0; 310 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, 311 &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) { 312 no_match: 313 e = ip6t_next_entry(e); 314 continue; 315 } 316 317 xt_ematch_foreach(ematch, e) { 318 acpar.match = ematch->u.kernel.match; 319 acpar.matchinfo = ematch->data; 320 if (!acpar.match->match(skb, &acpar)) 321 goto no_match; 322 } 323 324 counter = xt_get_this_cpu_counter(&e->counters); 325 ADD_COUNTER(*counter, skb->len, 1); 326 327 t = ip6t_get_target_c(e); 328 WARN_ON(!t->u.kernel.target); 329 330 #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 331 /* The packet is traced: log it */ 332 if (unlikely(skb->nf_trace)) 333 trace_packet(state->net, skb, hook, state->in, 334 state->out, table->name, private, e); 335 #endif 336 /* Standard target? */ 337 if (!t->u.kernel.target->target) { 338 int v; 339 340 v = ((struct xt_standard_target *)t)->verdict; 341 if (v < 0) { 342 /* Pop from stack? */ 343 if (v != XT_RETURN) { 344 verdict = (unsigned int)(-v) - 1; 345 break; 346 } 347 if (stackidx == 0) 348 e = get_entry(table_base, 349 private->underflow[hook]); 350 else 351 e = ip6t_next_entry(jumpstack[--stackidx]); 352 continue; 353 } 354 if (table_base + v != ip6t_next_entry(e) && 355 !(e->ipv6.flags & IP6T_F_GOTO)) { 356 if (unlikely(stackidx >= private->stacksize)) { 357 verdict = NF_DROP; 358 break; 359 } 360 jumpstack[stackidx++] = e; 361 } 362 363 e = get_entry(table_base, v); 364 continue; 365 } 366 367 acpar.target = t->u.kernel.target; 368 acpar.targinfo = t->data; 369 370 verdict = t->u.kernel.target->target(skb, &acpar); 371 if (verdict == XT_CONTINUE) 372 e = ip6t_next_entry(e); 373 else 374 /* Verdict */ 375 break; 376 } while (!acpar.hotdrop); 377 378 xt_write_recseq_end(addend); 379 local_bh_enable(); 380 381 if (acpar.hotdrop) 382 return NF_DROP; 383 else return verdict; 384 } 385 386 /* Figures out from what hook each rule can be called: returns 0 if 387 there are loops. Puts hook bitmask in comefrom. */ 388 static int 389 mark_source_chains(const struct xt_table_info *newinfo, 390 unsigned int valid_hooks, void *entry0, 391 unsigned int *offsets) 392 { 393 unsigned int hook; 394 395 /* No recursion; use packet counter to save back ptrs (reset 396 to 0 as we leave), and comefrom to save source hook bitmask */ 397 for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) { 398 unsigned int pos = newinfo->hook_entry[hook]; 399 struct ip6t_entry *e = entry0 + pos; 400 401 if (!(valid_hooks & (1 << hook))) 402 continue; 403 404 /* Set initial back pointer. */ 405 e->counters.pcnt = pos; 406 407 for (;;) { 408 const struct xt_standard_target *t 409 = (void *)ip6t_get_target_c(e); 410 int visited = e->comefrom & (1 << hook); 411 412 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) 413 return 0; 414 415 e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); 416 417 /* Unconditional return/END. */ 418 if ((unconditional(e) && 419 (strcmp(t->target.u.user.name, 420 XT_STANDARD_TARGET) == 0) && 421 t->verdict < 0) || visited) { 422 unsigned int oldpos, size; 423 424 /* Return: backtrack through the last 425 big jump. */ 426 do { 427 e->comefrom ^= (1<<NF_INET_NUMHOOKS); 428 oldpos = pos; 429 pos = e->counters.pcnt; 430 e->counters.pcnt = 0; 431 432 /* We're at the start. */ 433 if (pos == oldpos) 434 goto next; 435 436 e = entry0 + pos; 437 } while (oldpos == pos + e->next_offset); 438 439 /* Move along one */ 440 size = e->next_offset; 441 e = entry0 + pos + size; 442 if (pos + size >= newinfo->size) 443 return 0; 444 e->counters.pcnt = pos; 445 pos += size; 446 } else { 447 int newpos = t->verdict; 448 449 if (strcmp(t->target.u.user.name, 450 XT_STANDARD_TARGET) == 0 && 451 newpos >= 0) { 452 /* This a jump; chase it. */ 453 if (!xt_find_jump_offset(offsets, newpos, 454 newinfo->number)) 455 return 0; 456 } else { 457 /* ... this is a fallthru */ 458 newpos = pos + e->next_offset; 459 if (newpos >= newinfo->size) 460 return 0; 461 } 462 e = entry0 + newpos; 463 e->counters.pcnt = pos; 464 pos = newpos; 465 } 466 } 467 next: ; 468 } 469 return 1; 470 } 471 472 static void cleanup_match(struct xt_entry_match *m, struct net *net) 473 { 474 struct xt_mtdtor_param par; 475 476 par.net = net; 477 par.match = m->u.kernel.match; 478 par.matchinfo = m->data; 479 par.family = NFPROTO_IPV6; 480 if (par.match->destroy != NULL) 481 par.match->destroy(&par); 482 module_put(par.match->me); 483 } 484 485 static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) 486 { 487 const struct ip6t_ip6 *ipv6 = par->entryinfo; 488 489 par->match = m->u.kernel.match; 490 par->matchinfo = m->data; 491 492 return xt_check_match(par, m->u.match_size - sizeof(*m), 493 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO); 494 } 495 496 static int 497 find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) 498 { 499 struct xt_match *match; 500 int ret; 501 502 match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name, 503 m->u.user.revision); 504 if (IS_ERR(match)) 505 return PTR_ERR(match); 506 507 m->u.kernel.match = match; 508 509 ret = check_match(m, par); 510 if (ret) 511 goto err; 512 513 return 0; 514 err: 515 module_put(m->u.kernel.match->me); 516 return ret; 517 } 518 519 static int check_target(struct ip6t_entry *e, struct net *net, const char *name) 520 { 521 struct xt_entry_target *t = ip6t_get_target(e); 522 struct xt_tgchk_param par = { 523 .net = net, 524 .table = name, 525 .entryinfo = e, 526 .target = t->u.kernel.target, 527 .targinfo = t->data, 528 .hook_mask = e->comefrom, 529 .family = NFPROTO_IPV6, 530 }; 531 532 return xt_check_target(&par, t->u.target_size - sizeof(*t), 533 e->ipv6.proto, 534 e->ipv6.invflags & IP6T_INV_PROTO); 535 } 536 537 static int 538 find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, 539 unsigned int size, 540 struct xt_percpu_counter_alloc_state *alloc_state) 541 { 542 struct xt_entry_target *t; 543 struct xt_target *target; 544 int ret; 545 unsigned int j; 546 struct xt_mtchk_param mtpar; 547 struct xt_entry_match *ematch; 548 549 if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) 550 return -ENOMEM; 551 552 j = 0; 553 memset(&mtpar, 0, sizeof(mtpar)); 554 mtpar.net = net; 555 mtpar.table = name; 556 mtpar.entryinfo = &e->ipv6; 557 mtpar.hook_mask = e->comefrom; 558 mtpar.family = NFPROTO_IPV6; 559 xt_ematch_foreach(ematch, e) { 560 ret = find_check_match(ematch, &mtpar); 561 if (ret != 0) 562 goto cleanup_matches; 563 ++j; 564 } 565 566 t = ip6t_get_target(e); 567 target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name, 568 t->u.user.revision); 569 if (IS_ERR(target)) { 570 ret = PTR_ERR(target); 571 goto cleanup_matches; 572 } 573 t->u.kernel.target = target; 574 575 ret = check_target(e, net, name); 576 if (ret) 577 goto err; 578 return 0; 579 err: 580 module_put(t->u.kernel.target->me); 581 cleanup_matches: 582 xt_ematch_foreach(ematch, e) { 583 if (j-- == 0) 584 break; 585 cleanup_match(ematch, net); 586 } 587 588 xt_percpu_counter_free(&e->counters); 589 590 return ret; 591 } 592 593 static bool check_underflow(const struct ip6t_entry *e) 594 { 595 const struct xt_entry_target *t; 596 unsigned int verdict; 597 598 if (!unconditional(e)) 599 return false; 600 t = ip6t_get_target_c(e); 601 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) 602 return false; 603 verdict = ((struct xt_standard_target *)t)->verdict; 604 verdict = -verdict - 1; 605 return verdict == NF_DROP || verdict == NF_ACCEPT; 606 } 607 608 static int 609 check_entry_size_and_hooks(struct ip6t_entry *e, 610 struct xt_table_info *newinfo, 611 const unsigned char *base, 612 const unsigned char *limit, 613 const unsigned int *hook_entries, 614 const unsigned int *underflows, 615 unsigned int valid_hooks) 616 { 617 unsigned int h; 618 int err; 619 620 if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || 621 (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || 622 (unsigned char *)e + e->next_offset > limit) 623 return -EINVAL; 624 625 if (e->next_offset 626 < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) 627 return -EINVAL; 628 629 if (!ip6_checkentry(&e->ipv6)) 630 return -EINVAL; 631 632 err = xt_check_entry_offsets(e, e->elems, e->target_offset, 633 e->next_offset); 634 if (err) 635 return err; 636 637 /* Check hooks & underflows */ 638 for (h = 0; h < NF_INET_NUMHOOKS; h++) { 639 if (!(valid_hooks & (1 << h))) 640 continue; 641 if ((unsigned char *)e - base == hook_entries[h]) 642 newinfo->hook_entry[h] = hook_entries[h]; 643 if ((unsigned char *)e - base == underflows[h]) { 644 if (!check_underflow(e)) 645 return -EINVAL; 646 647 newinfo->underflow[h] = underflows[h]; 648 } 649 } 650 651 /* Clear counters and comefrom */ 652 e->counters = ((struct xt_counters) { 0, 0 }); 653 e->comefrom = 0; 654 return 0; 655 } 656 657 static void cleanup_entry(struct ip6t_entry *e, struct net *net) 658 { 659 struct xt_tgdtor_param par; 660 struct xt_entry_target *t; 661 struct xt_entry_match *ematch; 662 663 /* Cleanup all matches */ 664 xt_ematch_foreach(ematch, e) 665 cleanup_match(ematch, net); 666 t = ip6t_get_target(e); 667 668 par.net = net; 669 par.target = t->u.kernel.target; 670 par.targinfo = t->data; 671 par.family = NFPROTO_IPV6; 672 if (par.target->destroy != NULL) 673 par.target->destroy(&par); 674 module_put(par.target->me); 675 xt_percpu_counter_free(&e->counters); 676 } 677 678 /* Checks and translates the user-supplied table segment (held in 679 newinfo) */ 680 static int 681 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, 682 const struct ip6t_replace *repl) 683 { 684 struct xt_percpu_counter_alloc_state alloc_state = { 0 }; 685 struct ip6t_entry *iter; 686 unsigned int *offsets; 687 unsigned int i; 688 int ret = 0; 689 690 newinfo->size = repl->size; 691 newinfo->number = repl->num_entries; 692 693 /* Init all hooks to impossible value. */ 694 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 695 newinfo->hook_entry[i] = 0xFFFFFFFF; 696 newinfo->underflow[i] = 0xFFFFFFFF; 697 } 698 699 offsets = xt_alloc_entry_offsets(newinfo->number); 700 if (!offsets) 701 return -ENOMEM; 702 i = 0; 703 /* Walk through entries, checking offsets. */ 704 xt_entry_foreach(iter, entry0, newinfo->size) { 705 ret = check_entry_size_and_hooks(iter, newinfo, entry0, 706 entry0 + repl->size, 707 repl->hook_entry, 708 repl->underflow, 709 repl->valid_hooks); 710 if (ret != 0) 711 goto out_free; 712 if (i < repl->num_entries) 713 offsets[i] = (void *)iter - entry0; 714 ++i; 715 if (strcmp(ip6t_get_target(iter)->u.user.name, 716 XT_ERROR_TARGET) == 0) 717 ++newinfo->stacksize; 718 } 719 720 ret = -EINVAL; 721 if (i != repl->num_entries) 722 goto out_free; 723 724 ret = xt_check_table_hooks(newinfo, repl->valid_hooks); 725 if (ret) 726 goto out_free; 727 728 if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) { 729 ret = -ELOOP; 730 goto out_free; 731 } 732 kvfree(offsets); 733 734 /* Finally, each sanity check must pass */ 735 i = 0; 736 xt_entry_foreach(iter, entry0, newinfo->size) { 737 ret = find_check_entry(iter, net, repl->name, repl->size, 738 &alloc_state); 739 if (ret != 0) 740 break; 741 ++i; 742 } 743 744 if (ret != 0) { 745 xt_entry_foreach(iter, entry0, newinfo->size) { 746 if (i-- == 0) 747 break; 748 cleanup_entry(iter, net); 749 } 750 return ret; 751 } 752 753 return ret; 754 out_free: 755 kvfree(offsets); 756 return ret; 757 } 758 759 static void 760 get_counters(const struct xt_table_info *t, 761 struct xt_counters counters[]) 762 { 763 struct ip6t_entry *iter; 764 unsigned int cpu; 765 unsigned int i; 766 767 for_each_possible_cpu(cpu) { 768 seqcount_t *s = &per_cpu(xt_recseq, cpu); 769 770 i = 0; 771 xt_entry_foreach(iter, t->entries, t->size) { 772 struct xt_counters *tmp; 773 u64 bcnt, pcnt; 774 unsigned int start; 775 776 tmp = xt_get_per_cpu_counter(&iter->counters, cpu); 777 do { 778 start = read_seqcount_begin(s); 779 bcnt = tmp->bcnt; 780 pcnt = tmp->pcnt; 781 } while (read_seqcount_retry(s, start)); 782 783 ADD_COUNTER(counters[i], bcnt, pcnt); 784 ++i; 785 cond_resched(); 786 } 787 } 788 } 789 790 static void get_old_counters(const struct xt_table_info *t, 791 struct xt_counters counters[]) 792 { 793 struct ip6t_entry *iter; 794 unsigned int cpu, i; 795 796 for_each_possible_cpu(cpu) { 797 i = 0; 798 xt_entry_foreach(iter, t->entries, t->size) { 799 const struct xt_counters *tmp; 800 801 tmp = xt_get_per_cpu_counter(&iter->counters, cpu); 802 ADD_COUNTER(counters[i], tmp->bcnt, tmp->pcnt); 803 ++i; 804 } 805 cond_resched(); 806 } 807 } 808 809 static struct xt_counters *alloc_counters(const struct xt_table *table) 810 { 811 unsigned int countersize; 812 struct xt_counters *counters; 813 const struct xt_table_info *private = table->private; 814 815 /* We need atomic snapshot of counters: rest doesn't change 816 (other than comefrom, which userspace doesn't care 817 about). */ 818 countersize = sizeof(struct xt_counters) * private->number; 819 counters = vzalloc(countersize); 820 821 if (counters == NULL) 822 return ERR_PTR(-ENOMEM); 823 824 get_counters(private, counters); 825 826 return counters; 827 } 828 829 static int 830 copy_entries_to_user(unsigned int total_size, 831 const struct xt_table *table, 832 void __user *userptr) 833 { 834 unsigned int off, num; 835 const struct ip6t_entry *e; 836 struct xt_counters *counters; 837 const struct xt_table_info *private = table->private; 838 int ret = 0; 839 const void *loc_cpu_entry; 840 841 counters = alloc_counters(table); 842 if (IS_ERR(counters)) 843 return PTR_ERR(counters); 844 845 loc_cpu_entry = private->entries; 846 847 /* FIXME: use iterator macros --RR */ 848 /* ... then go back and fix counters and names */ 849 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ 850 unsigned int i; 851 const struct xt_entry_match *m; 852 const struct xt_entry_target *t; 853 854 e = loc_cpu_entry + off; 855 if (copy_to_user(userptr + off, e, sizeof(*e))) { 856 ret = -EFAULT; 857 goto free_counters; 858 } 859 if (copy_to_user(userptr + off 860 + offsetof(struct ip6t_entry, counters), 861 &counters[num], 862 sizeof(counters[num])) != 0) { 863 ret = -EFAULT; 864 goto free_counters; 865 } 866 867 for (i = sizeof(struct ip6t_entry); 868 i < e->target_offset; 869 i += m->u.match_size) { 870 m = (void *)e + i; 871 872 if (xt_match_to_user(m, userptr + off + i)) { 873 ret = -EFAULT; 874 goto free_counters; 875 } 876 } 877 878 t = ip6t_get_target_c(e); 879 if (xt_target_to_user(t, userptr + off + e->target_offset)) { 880 ret = -EFAULT; 881 goto free_counters; 882 } 883 } 884 885 free_counters: 886 vfree(counters); 887 return ret; 888 } 889 890 #ifdef CONFIG_COMPAT 891 static void compat_standard_from_user(void *dst, const void *src) 892 { 893 int v = *(compat_int_t *)src; 894 895 if (v > 0) 896 v += xt_compat_calc_jump(AF_INET6, v); 897 memcpy(dst, &v, sizeof(v)); 898 } 899 900 static int compat_standard_to_user(void __user *dst, const void *src) 901 { 902 compat_int_t cv = *(int *)src; 903 904 if (cv > 0) 905 cv -= xt_compat_calc_jump(AF_INET6, cv); 906 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 907 } 908 909 static int compat_calc_entry(const struct ip6t_entry *e, 910 const struct xt_table_info *info, 911 const void *base, struct xt_table_info *newinfo) 912 { 913 const struct xt_entry_match *ematch; 914 const struct xt_entry_target *t; 915 unsigned int entry_offset; 916 int off, i, ret; 917 918 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 919 entry_offset = (void *)e - base; 920 xt_ematch_foreach(ematch, e) 921 off += xt_compat_match_offset(ematch->u.kernel.match); 922 t = ip6t_get_target_c(e); 923 off += xt_compat_target_offset(t->u.kernel.target); 924 newinfo->size -= off; 925 ret = xt_compat_add_offset(AF_INET6, entry_offset, off); 926 if (ret) 927 return ret; 928 929 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 930 if (info->hook_entry[i] && 931 (e < (struct ip6t_entry *)(base + info->hook_entry[i]))) 932 newinfo->hook_entry[i] -= off; 933 if (info->underflow[i] && 934 (e < (struct ip6t_entry *)(base + info->underflow[i]))) 935 newinfo->underflow[i] -= off; 936 } 937 return 0; 938 } 939 940 static int compat_table_info(const struct xt_table_info *info, 941 struct xt_table_info *newinfo) 942 { 943 struct ip6t_entry *iter; 944 const void *loc_cpu_entry; 945 int ret; 946 947 if (!newinfo || !info) 948 return -EINVAL; 949 950 /* we dont care about newinfo->entries */ 951 memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); 952 newinfo->initial_entries = 0; 953 loc_cpu_entry = info->entries; 954 ret = xt_compat_init_offsets(AF_INET6, info->number); 955 if (ret) 956 return ret; 957 xt_entry_foreach(iter, loc_cpu_entry, info->size) { 958 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); 959 if (ret != 0) 960 return ret; 961 } 962 return 0; 963 } 964 #endif 965 966 static int get_info(struct net *net, void __user *user, 967 const int *len, int compat) 968 { 969 char name[XT_TABLE_MAXNAMELEN]; 970 struct xt_table *t; 971 int ret; 972 973 if (*len != sizeof(struct ip6t_getinfo)) 974 return -EINVAL; 975 976 if (copy_from_user(name, user, sizeof(name)) != 0) 977 return -EFAULT; 978 979 name[XT_TABLE_MAXNAMELEN-1] = '\0'; 980 #ifdef CONFIG_COMPAT 981 if (compat) 982 xt_compat_lock(AF_INET6); 983 #endif 984 t = xt_request_find_table_lock(net, AF_INET6, name); 985 if (!IS_ERR(t)) { 986 struct ip6t_getinfo info; 987 const struct xt_table_info *private = t->private; 988 #ifdef CONFIG_COMPAT 989 struct xt_table_info tmp; 990 991 if (compat) { 992 ret = compat_table_info(private, &tmp); 993 xt_compat_flush_offsets(AF_INET6); 994 private = &tmp; 995 } 996 #endif 997 memset(&info, 0, sizeof(info)); 998 info.valid_hooks = t->valid_hooks; 999 memcpy(info.hook_entry, private->hook_entry, 1000 sizeof(info.hook_entry)); 1001 memcpy(info.underflow, private->underflow, 1002 sizeof(info.underflow)); 1003 info.num_entries = private->number; 1004 info.size = private->size; 1005 strcpy(info.name, name); 1006 1007 if (copy_to_user(user, &info, *len) != 0) 1008 ret = -EFAULT; 1009 else 1010 ret = 0; 1011 1012 xt_table_unlock(t); 1013 module_put(t->me); 1014 } else 1015 ret = PTR_ERR(t); 1016 #ifdef CONFIG_COMPAT 1017 if (compat) 1018 xt_compat_unlock(AF_INET6); 1019 #endif 1020 return ret; 1021 } 1022 1023 static int 1024 get_entries(struct net *net, struct ip6t_get_entries __user *uptr, 1025 const int *len) 1026 { 1027 int ret; 1028 struct ip6t_get_entries get; 1029 struct xt_table *t; 1030 1031 if (*len < sizeof(get)) 1032 return -EINVAL; 1033 if (copy_from_user(&get, uptr, sizeof(get)) != 0) 1034 return -EFAULT; 1035 if (*len != sizeof(struct ip6t_get_entries) + get.size) 1036 return -EINVAL; 1037 1038 get.name[sizeof(get.name) - 1] = '\0'; 1039 1040 t = xt_find_table_lock(net, AF_INET6, get.name); 1041 if (!IS_ERR(t)) { 1042 struct xt_table_info *private = t->private; 1043 if (get.size == private->size) 1044 ret = copy_entries_to_user(private->size, 1045 t, uptr->entrytable); 1046 else 1047 ret = -EAGAIN; 1048 1049 module_put(t->me); 1050 xt_table_unlock(t); 1051 } else 1052 ret = PTR_ERR(t); 1053 1054 return ret; 1055 } 1056 1057 static int 1058 __do_replace(struct net *net, const char *name, unsigned int valid_hooks, 1059 struct xt_table_info *newinfo, unsigned int num_counters, 1060 void __user *counters_ptr) 1061 { 1062 int ret; 1063 struct xt_table *t; 1064 struct xt_table_info *oldinfo; 1065 struct xt_counters *counters; 1066 struct ip6t_entry *iter; 1067 1068 ret = 0; 1069 counters = xt_counters_alloc(num_counters); 1070 if (!counters) { 1071 ret = -ENOMEM; 1072 goto out; 1073 } 1074 1075 t = xt_request_find_table_lock(net, AF_INET6, name); 1076 if (IS_ERR(t)) { 1077 ret = PTR_ERR(t); 1078 goto free_newinfo_counters_untrans; 1079 } 1080 1081 /* You lied! */ 1082 if (valid_hooks != t->valid_hooks) { 1083 ret = -EINVAL; 1084 goto put_module; 1085 } 1086 1087 oldinfo = xt_replace_table(t, num_counters, newinfo, &ret); 1088 if (!oldinfo) 1089 goto put_module; 1090 1091 /* Update module usage count based on number of rules */ 1092 if ((oldinfo->number > oldinfo->initial_entries) || 1093 (newinfo->number <= oldinfo->initial_entries)) 1094 module_put(t->me); 1095 if ((oldinfo->number > oldinfo->initial_entries) && 1096 (newinfo->number <= oldinfo->initial_entries)) 1097 module_put(t->me); 1098 1099 xt_table_unlock(t); 1100 1101 get_old_counters(oldinfo, counters); 1102 1103 /* Decrease module usage counts and free resource */ 1104 xt_entry_foreach(iter, oldinfo->entries, oldinfo->size) 1105 cleanup_entry(iter, net); 1106 1107 xt_free_table_info(oldinfo); 1108 if (copy_to_user(counters_ptr, counters, 1109 sizeof(struct xt_counters) * num_counters) != 0) { 1110 /* Silent error, can't fail, new table is already in place */ 1111 net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n"); 1112 } 1113 vfree(counters); 1114 return ret; 1115 1116 put_module: 1117 module_put(t->me); 1118 xt_table_unlock(t); 1119 free_newinfo_counters_untrans: 1120 vfree(counters); 1121 out: 1122 return ret; 1123 } 1124 1125 static int 1126 do_replace(struct net *net, const void __user *user, unsigned int len) 1127 { 1128 int ret; 1129 struct ip6t_replace tmp; 1130 struct xt_table_info *newinfo; 1131 void *loc_cpu_entry; 1132 struct ip6t_entry *iter; 1133 1134 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1135 return -EFAULT; 1136 1137 /* overflow check */ 1138 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1139 return -ENOMEM; 1140 if (tmp.num_counters == 0) 1141 return -EINVAL; 1142 1143 tmp.name[sizeof(tmp.name)-1] = 0; 1144 1145 newinfo = xt_alloc_table_info(tmp.size); 1146 if (!newinfo) 1147 return -ENOMEM; 1148 1149 loc_cpu_entry = newinfo->entries; 1150 if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), 1151 tmp.size) != 0) { 1152 ret = -EFAULT; 1153 goto free_newinfo; 1154 } 1155 1156 ret = translate_table(net, newinfo, loc_cpu_entry, &tmp); 1157 if (ret != 0) 1158 goto free_newinfo; 1159 1160 ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, 1161 tmp.num_counters, tmp.counters); 1162 if (ret) 1163 goto free_newinfo_untrans; 1164 return 0; 1165 1166 free_newinfo_untrans: 1167 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1168 cleanup_entry(iter, net); 1169 free_newinfo: 1170 xt_free_table_info(newinfo); 1171 return ret; 1172 } 1173 1174 static int 1175 do_add_counters(struct net *net, const void __user *user, unsigned int len, 1176 int compat) 1177 { 1178 unsigned int i; 1179 struct xt_counters_info tmp; 1180 struct xt_counters *paddc; 1181 struct xt_table *t; 1182 const struct xt_table_info *private; 1183 int ret = 0; 1184 struct ip6t_entry *iter; 1185 unsigned int addend; 1186 1187 paddc = xt_copy_counters_from_user(user, len, &tmp, compat); 1188 if (IS_ERR(paddc)) 1189 return PTR_ERR(paddc); 1190 t = xt_find_table_lock(net, AF_INET6, tmp.name); 1191 if (IS_ERR(t)) { 1192 ret = PTR_ERR(t); 1193 goto free; 1194 } 1195 1196 local_bh_disable(); 1197 private = t->private; 1198 if (private->number != tmp.num_counters) { 1199 ret = -EINVAL; 1200 goto unlock_up_free; 1201 } 1202 1203 i = 0; 1204 addend = xt_write_recseq_begin(); 1205 xt_entry_foreach(iter, private->entries, private->size) { 1206 struct xt_counters *tmp; 1207 1208 tmp = xt_get_this_cpu_counter(&iter->counters); 1209 ADD_COUNTER(*tmp, paddc[i].bcnt, paddc[i].pcnt); 1210 ++i; 1211 } 1212 xt_write_recseq_end(addend); 1213 unlock_up_free: 1214 local_bh_enable(); 1215 xt_table_unlock(t); 1216 module_put(t->me); 1217 free: 1218 vfree(paddc); 1219 1220 return ret; 1221 } 1222 1223 #ifdef CONFIG_COMPAT 1224 struct compat_ip6t_replace { 1225 char name[XT_TABLE_MAXNAMELEN]; 1226 u32 valid_hooks; 1227 u32 num_entries; 1228 u32 size; 1229 u32 hook_entry[NF_INET_NUMHOOKS]; 1230 u32 underflow[NF_INET_NUMHOOKS]; 1231 u32 num_counters; 1232 compat_uptr_t counters; /* struct xt_counters * */ 1233 struct compat_ip6t_entry entries[0]; 1234 }; 1235 1236 static int 1237 compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, 1238 unsigned int *size, struct xt_counters *counters, 1239 unsigned int i) 1240 { 1241 struct xt_entry_target *t; 1242 struct compat_ip6t_entry __user *ce; 1243 u_int16_t target_offset, next_offset; 1244 compat_uint_t origsize; 1245 const struct xt_entry_match *ematch; 1246 int ret = 0; 1247 1248 origsize = *size; 1249 ce = *dstptr; 1250 if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 || 1251 copy_to_user(&ce->counters, &counters[i], 1252 sizeof(counters[i])) != 0) 1253 return -EFAULT; 1254 1255 *dstptr += sizeof(struct compat_ip6t_entry); 1256 *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1257 1258 xt_ematch_foreach(ematch, e) { 1259 ret = xt_compat_match_to_user(ematch, dstptr, size); 1260 if (ret != 0) 1261 return ret; 1262 } 1263 target_offset = e->target_offset - (origsize - *size); 1264 t = ip6t_get_target(e); 1265 ret = xt_compat_target_to_user(t, dstptr, size); 1266 if (ret) 1267 return ret; 1268 next_offset = e->next_offset - (origsize - *size); 1269 if (put_user(target_offset, &ce->target_offset) != 0 || 1270 put_user(next_offset, &ce->next_offset) != 0) 1271 return -EFAULT; 1272 return 0; 1273 } 1274 1275 static int 1276 compat_find_calc_match(struct xt_entry_match *m, 1277 const struct ip6t_ip6 *ipv6, 1278 int *size) 1279 { 1280 struct xt_match *match; 1281 1282 match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name, 1283 m->u.user.revision); 1284 if (IS_ERR(match)) 1285 return PTR_ERR(match); 1286 1287 m->u.kernel.match = match; 1288 *size += xt_compat_match_offset(match); 1289 return 0; 1290 } 1291 1292 static void compat_release_entry(struct compat_ip6t_entry *e) 1293 { 1294 struct xt_entry_target *t; 1295 struct xt_entry_match *ematch; 1296 1297 /* Cleanup all matches */ 1298 xt_ematch_foreach(ematch, e) 1299 module_put(ematch->u.kernel.match->me); 1300 t = compat_ip6t_get_target(e); 1301 module_put(t->u.kernel.target->me); 1302 } 1303 1304 static int 1305 check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, 1306 struct xt_table_info *newinfo, 1307 unsigned int *size, 1308 const unsigned char *base, 1309 const unsigned char *limit) 1310 { 1311 struct xt_entry_match *ematch; 1312 struct xt_entry_target *t; 1313 struct xt_target *target; 1314 unsigned int entry_offset; 1315 unsigned int j; 1316 int ret, off; 1317 1318 if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || 1319 (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || 1320 (unsigned char *)e + e->next_offset > limit) 1321 return -EINVAL; 1322 1323 if (e->next_offset < sizeof(struct compat_ip6t_entry) + 1324 sizeof(struct compat_xt_entry_target)) 1325 return -EINVAL; 1326 1327 if (!ip6_checkentry(&e->ipv6)) 1328 return -EINVAL; 1329 1330 ret = xt_compat_check_entry_offsets(e, e->elems, 1331 e->target_offset, e->next_offset); 1332 if (ret) 1333 return ret; 1334 1335 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1336 entry_offset = (void *)e - (void *)base; 1337 j = 0; 1338 xt_ematch_foreach(ematch, e) { 1339 ret = compat_find_calc_match(ematch, &e->ipv6, &off); 1340 if (ret != 0) 1341 goto release_matches; 1342 ++j; 1343 } 1344 1345 t = compat_ip6t_get_target(e); 1346 target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name, 1347 t->u.user.revision); 1348 if (IS_ERR(target)) { 1349 ret = PTR_ERR(target); 1350 goto release_matches; 1351 } 1352 t->u.kernel.target = target; 1353 1354 off += xt_compat_target_offset(target); 1355 *size += off; 1356 ret = xt_compat_add_offset(AF_INET6, entry_offset, off); 1357 if (ret) 1358 goto out; 1359 1360 return 0; 1361 1362 out: 1363 module_put(t->u.kernel.target->me); 1364 release_matches: 1365 xt_ematch_foreach(ematch, e) { 1366 if (j-- == 0) 1367 break; 1368 module_put(ematch->u.kernel.match->me); 1369 } 1370 return ret; 1371 } 1372 1373 static void 1374 compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, 1375 unsigned int *size, 1376 struct xt_table_info *newinfo, unsigned char *base) 1377 { 1378 struct xt_entry_target *t; 1379 struct ip6t_entry *de; 1380 unsigned int origsize; 1381 int h; 1382 struct xt_entry_match *ematch; 1383 1384 origsize = *size; 1385 de = *dstptr; 1386 memcpy(de, e, sizeof(struct ip6t_entry)); 1387 memcpy(&de->counters, &e->counters, sizeof(e->counters)); 1388 1389 *dstptr += sizeof(struct ip6t_entry); 1390 *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1391 1392 xt_ematch_foreach(ematch, e) 1393 xt_compat_match_from_user(ematch, dstptr, size); 1394 1395 de->target_offset = e->target_offset - (origsize - *size); 1396 t = compat_ip6t_get_target(e); 1397 xt_compat_target_from_user(t, dstptr, size); 1398 1399 de->next_offset = e->next_offset - (origsize - *size); 1400 for (h = 0; h < NF_INET_NUMHOOKS; h++) { 1401 if ((unsigned char *)de - base < newinfo->hook_entry[h]) 1402 newinfo->hook_entry[h] -= origsize - *size; 1403 if ((unsigned char *)de - base < newinfo->underflow[h]) 1404 newinfo->underflow[h] -= origsize - *size; 1405 } 1406 } 1407 1408 static int 1409 translate_compat_table(struct net *net, 1410 struct xt_table_info **pinfo, 1411 void **pentry0, 1412 const struct compat_ip6t_replace *compatr) 1413 { 1414 unsigned int i, j; 1415 struct xt_table_info *newinfo, *info; 1416 void *pos, *entry0, *entry1; 1417 struct compat_ip6t_entry *iter0; 1418 struct ip6t_replace repl; 1419 unsigned int size; 1420 int ret; 1421 1422 info = *pinfo; 1423 entry0 = *pentry0; 1424 size = compatr->size; 1425 info->number = compatr->num_entries; 1426 1427 j = 0; 1428 xt_compat_lock(AF_INET6); 1429 ret = xt_compat_init_offsets(AF_INET6, compatr->num_entries); 1430 if (ret) 1431 goto out_unlock; 1432 /* Walk through entries, checking offsets. */ 1433 xt_entry_foreach(iter0, entry0, compatr->size) { 1434 ret = check_compat_entry_size_and_hooks(iter0, info, &size, 1435 entry0, 1436 entry0 + compatr->size); 1437 if (ret != 0) 1438 goto out_unlock; 1439 ++j; 1440 } 1441 1442 ret = -EINVAL; 1443 if (j != compatr->num_entries) 1444 goto out_unlock; 1445 1446 ret = -ENOMEM; 1447 newinfo = xt_alloc_table_info(size); 1448 if (!newinfo) 1449 goto out_unlock; 1450 1451 newinfo->number = compatr->num_entries; 1452 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 1453 newinfo->hook_entry[i] = compatr->hook_entry[i]; 1454 newinfo->underflow[i] = compatr->underflow[i]; 1455 } 1456 entry1 = newinfo->entries; 1457 pos = entry1; 1458 size = compatr->size; 1459 xt_entry_foreach(iter0, entry0, compatr->size) 1460 compat_copy_entry_from_user(iter0, &pos, &size, 1461 newinfo, entry1); 1462 1463 /* all module references in entry0 are now gone. */ 1464 xt_compat_flush_offsets(AF_INET6); 1465 xt_compat_unlock(AF_INET6); 1466 1467 memcpy(&repl, compatr, sizeof(*compatr)); 1468 1469 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 1470 repl.hook_entry[i] = newinfo->hook_entry[i]; 1471 repl.underflow[i] = newinfo->underflow[i]; 1472 } 1473 1474 repl.num_counters = 0; 1475 repl.counters = NULL; 1476 repl.size = newinfo->size; 1477 ret = translate_table(net, newinfo, entry1, &repl); 1478 if (ret) 1479 goto free_newinfo; 1480 1481 *pinfo = newinfo; 1482 *pentry0 = entry1; 1483 xt_free_table_info(info); 1484 return 0; 1485 1486 free_newinfo: 1487 xt_free_table_info(newinfo); 1488 return ret; 1489 out_unlock: 1490 xt_compat_flush_offsets(AF_INET6); 1491 xt_compat_unlock(AF_INET6); 1492 xt_entry_foreach(iter0, entry0, compatr->size) { 1493 if (j-- == 0) 1494 break; 1495 compat_release_entry(iter0); 1496 } 1497 return ret; 1498 } 1499 1500 static int 1501 compat_do_replace(struct net *net, void __user *user, unsigned int len) 1502 { 1503 int ret; 1504 struct compat_ip6t_replace tmp; 1505 struct xt_table_info *newinfo; 1506 void *loc_cpu_entry; 1507 struct ip6t_entry *iter; 1508 1509 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1510 return -EFAULT; 1511 1512 /* overflow check */ 1513 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1514 return -ENOMEM; 1515 if (tmp.num_counters == 0) 1516 return -EINVAL; 1517 1518 tmp.name[sizeof(tmp.name)-1] = 0; 1519 1520 newinfo = xt_alloc_table_info(tmp.size); 1521 if (!newinfo) 1522 return -ENOMEM; 1523 1524 loc_cpu_entry = newinfo->entries; 1525 if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), 1526 tmp.size) != 0) { 1527 ret = -EFAULT; 1528 goto free_newinfo; 1529 } 1530 1531 ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp); 1532 if (ret != 0) 1533 goto free_newinfo; 1534 1535 ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, 1536 tmp.num_counters, compat_ptr(tmp.counters)); 1537 if (ret) 1538 goto free_newinfo_untrans; 1539 return 0; 1540 1541 free_newinfo_untrans: 1542 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1543 cleanup_entry(iter, net); 1544 free_newinfo: 1545 xt_free_table_info(newinfo); 1546 return ret; 1547 } 1548 1549 static int 1550 compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, 1551 unsigned int len) 1552 { 1553 int ret; 1554 1555 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) 1556 return -EPERM; 1557 1558 switch (cmd) { 1559 case IP6T_SO_SET_REPLACE: 1560 ret = compat_do_replace(sock_net(sk), user, len); 1561 break; 1562 1563 case IP6T_SO_SET_ADD_COUNTERS: 1564 ret = do_add_counters(sock_net(sk), user, len, 1); 1565 break; 1566 1567 default: 1568 ret = -EINVAL; 1569 } 1570 1571 return ret; 1572 } 1573 1574 struct compat_ip6t_get_entries { 1575 char name[XT_TABLE_MAXNAMELEN]; 1576 compat_uint_t size; 1577 struct compat_ip6t_entry entrytable[0]; 1578 }; 1579 1580 static int 1581 compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, 1582 void __user *userptr) 1583 { 1584 struct xt_counters *counters; 1585 const struct xt_table_info *private = table->private; 1586 void __user *pos; 1587 unsigned int size; 1588 int ret = 0; 1589 unsigned int i = 0; 1590 struct ip6t_entry *iter; 1591 1592 counters = alloc_counters(table); 1593 if (IS_ERR(counters)) 1594 return PTR_ERR(counters); 1595 1596 pos = userptr; 1597 size = total_size; 1598 xt_entry_foreach(iter, private->entries, total_size) { 1599 ret = compat_copy_entry_to_user(iter, &pos, 1600 &size, counters, i++); 1601 if (ret != 0) 1602 break; 1603 } 1604 1605 vfree(counters); 1606 return ret; 1607 } 1608 1609 static int 1610 compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, 1611 int *len) 1612 { 1613 int ret; 1614 struct compat_ip6t_get_entries get; 1615 struct xt_table *t; 1616 1617 if (*len < sizeof(get)) 1618 return -EINVAL; 1619 1620 if (copy_from_user(&get, uptr, sizeof(get)) != 0) 1621 return -EFAULT; 1622 1623 if (*len != sizeof(struct compat_ip6t_get_entries) + get.size) 1624 return -EINVAL; 1625 1626 get.name[sizeof(get.name) - 1] = '\0'; 1627 1628 xt_compat_lock(AF_INET6); 1629 t = xt_find_table_lock(net, AF_INET6, get.name); 1630 if (!IS_ERR(t)) { 1631 const struct xt_table_info *private = t->private; 1632 struct xt_table_info info; 1633 ret = compat_table_info(private, &info); 1634 if (!ret && get.size == info.size) 1635 ret = compat_copy_entries_to_user(private->size, 1636 t, uptr->entrytable); 1637 else if (!ret) 1638 ret = -EAGAIN; 1639 1640 xt_compat_flush_offsets(AF_INET6); 1641 module_put(t->me); 1642 xt_table_unlock(t); 1643 } else 1644 ret = PTR_ERR(t); 1645 1646 xt_compat_unlock(AF_INET6); 1647 return ret; 1648 } 1649 1650 static int do_ip6t_get_ctl(struct sock *, int, void __user *, int *); 1651 1652 static int 1653 compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) 1654 { 1655 int ret; 1656 1657 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) 1658 return -EPERM; 1659 1660 switch (cmd) { 1661 case IP6T_SO_GET_INFO: 1662 ret = get_info(sock_net(sk), user, len, 1); 1663 break; 1664 case IP6T_SO_GET_ENTRIES: 1665 ret = compat_get_entries(sock_net(sk), user, len); 1666 break; 1667 default: 1668 ret = do_ip6t_get_ctl(sk, cmd, user, len); 1669 } 1670 return ret; 1671 } 1672 #endif 1673 1674 static int 1675 do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) 1676 { 1677 int ret; 1678 1679 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) 1680 return -EPERM; 1681 1682 switch (cmd) { 1683 case IP6T_SO_SET_REPLACE: 1684 ret = do_replace(sock_net(sk), user, len); 1685 break; 1686 1687 case IP6T_SO_SET_ADD_COUNTERS: 1688 ret = do_add_counters(sock_net(sk), user, len, 0); 1689 break; 1690 1691 default: 1692 ret = -EINVAL; 1693 } 1694 1695 return ret; 1696 } 1697 1698 static int 1699 do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) 1700 { 1701 int ret; 1702 1703 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) 1704 return -EPERM; 1705 1706 switch (cmd) { 1707 case IP6T_SO_GET_INFO: 1708 ret = get_info(sock_net(sk), user, len, 0); 1709 break; 1710 1711 case IP6T_SO_GET_ENTRIES: 1712 ret = get_entries(sock_net(sk), user, len); 1713 break; 1714 1715 case IP6T_SO_GET_REVISION_MATCH: 1716 case IP6T_SO_GET_REVISION_TARGET: { 1717 struct xt_get_revision rev; 1718 int target; 1719 1720 if (*len != sizeof(rev)) { 1721 ret = -EINVAL; 1722 break; 1723 } 1724 if (copy_from_user(&rev, user, sizeof(rev)) != 0) { 1725 ret = -EFAULT; 1726 break; 1727 } 1728 rev.name[sizeof(rev.name)-1] = 0; 1729 1730 if (cmd == IP6T_SO_GET_REVISION_TARGET) 1731 target = 1; 1732 else 1733 target = 0; 1734 1735 try_then_request_module(xt_find_revision(AF_INET6, rev.name, 1736 rev.revision, 1737 target, &ret), 1738 "ip6t_%s", rev.name); 1739 break; 1740 } 1741 1742 default: 1743 ret = -EINVAL; 1744 } 1745 1746 return ret; 1747 } 1748 1749 static void __ip6t_unregister_table(struct net *net, struct xt_table *table) 1750 { 1751 struct xt_table_info *private; 1752 void *loc_cpu_entry; 1753 struct module *table_owner = table->me; 1754 struct ip6t_entry *iter; 1755 1756 private = xt_unregister_table(table); 1757 1758 /* Decrease module usage counts and free resources */ 1759 loc_cpu_entry = private->entries; 1760 xt_entry_foreach(iter, loc_cpu_entry, private->size) 1761 cleanup_entry(iter, net); 1762 if (private->number > private->initial_entries) 1763 module_put(table_owner); 1764 xt_free_table_info(private); 1765 } 1766 1767 int ip6t_register_table(struct net *net, const struct xt_table *table, 1768 const struct ip6t_replace *repl, 1769 const struct nf_hook_ops *ops, 1770 struct xt_table **res) 1771 { 1772 int ret; 1773 struct xt_table_info *newinfo; 1774 struct xt_table_info bootstrap = {0}; 1775 void *loc_cpu_entry; 1776 struct xt_table *new_table; 1777 1778 newinfo = xt_alloc_table_info(repl->size); 1779 if (!newinfo) 1780 return -ENOMEM; 1781 1782 loc_cpu_entry = newinfo->entries; 1783 memcpy(loc_cpu_entry, repl->entries, repl->size); 1784 1785 ret = translate_table(net, newinfo, loc_cpu_entry, repl); 1786 if (ret != 0) 1787 goto out_free; 1788 1789 new_table = xt_register_table(net, table, &bootstrap, newinfo); 1790 if (IS_ERR(new_table)) { 1791 ret = PTR_ERR(new_table); 1792 goto out_free; 1793 } 1794 1795 /* set res now, will see skbs right after nf_register_net_hooks */ 1796 WRITE_ONCE(*res, new_table); 1797 if (!ops) 1798 return 0; 1799 1800 ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks)); 1801 if (ret != 0) { 1802 __ip6t_unregister_table(net, new_table); 1803 *res = NULL; 1804 } 1805 1806 return ret; 1807 1808 out_free: 1809 xt_free_table_info(newinfo); 1810 return ret; 1811 } 1812 1813 void ip6t_unregister_table(struct net *net, struct xt_table *table, 1814 const struct nf_hook_ops *ops) 1815 { 1816 if (ops) 1817 nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks)); 1818 __ip6t_unregister_table(net, table); 1819 } 1820 1821 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ 1822 static inline bool 1823 icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, 1824 u_int8_t type, u_int8_t code, 1825 bool invert) 1826 { 1827 return (type == test_type && code >= min_code && code <= max_code) 1828 ^ invert; 1829 } 1830 1831 static bool 1832 icmp6_match(const struct sk_buff *skb, struct xt_action_param *par) 1833 { 1834 const struct icmp6hdr *ic; 1835 struct icmp6hdr _icmph; 1836 const struct ip6t_icmp *icmpinfo = par->matchinfo; 1837 1838 /* Must not be a fragment. */ 1839 if (par->fragoff != 0) 1840 return false; 1841 1842 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph); 1843 if (ic == NULL) { 1844 /* We've been asked to examine this packet, and we 1845 * can't. Hence, no choice but to drop. 1846 */ 1847 par->hotdrop = true; 1848 return false; 1849 } 1850 1851 return icmp6_type_code_match(icmpinfo->type, 1852 icmpinfo->code[0], 1853 icmpinfo->code[1], 1854 ic->icmp6_type, ic->icmp6_code, 1855 !!(icmpinfo->invflags&IP6T_ICMP_INV)); 1856 } 1857 1858 /* Called when user tries to insert an entry of this type. */ 1859 static int icmp6_checkentry(const struct xt_mtchk_param *par) 1860 { 1861 const struct ip6t_icmp *icmpinfo = par->matchinfo; 1862 1863 /* Must specify no unknown invflags */ 1864 return (icmpinfo->invflags & ~IP6T_ICMP_INV) ? -EINVAL : 0; 1865 } 1866 1867 /* The built-in targets: standard (NULL) and error. */ 1868 static struct xt_target ip6t_builtin_tg[] __read_mostly = { 1869 { 1870 .name = XT_STANDARD_TARGET, 1871 .targetsize = sizeof(int), 1872 .family = NFPROTO_IPV6, 1873 #ifdef CONFIG_COMPAT 1874 .compatsize = sizeof(compat_int_t), 1875 .compat_from_user = compat_standard_from_user, 1876 .compat_to_user = compat_standard_to_user, 1877 #endif 1878 }, 1879 { 1880 .name = XT_ERROR_TARGET, 1881 .target = ip6t_error, 1882 .targetsize = XT_FUNCTION_MAXNAMELEN, 1883 .family = NFPROTO_IPV6, 1884 }, 1885 }; 1886 1887 static struct nf_sockopt_ops ip6t_sockopts = { 1888 .pf = PF_INET6, 1889 .set_optmin = IP6T_BASE_CTL, 1890 .set_optmax = IP6T_SO_SET_MAX+1, 1891 .set = do_ip6t_set_ctl, 1892 #ifdef CONFIG_COMPAT 1893 .compat_set = compat_do_ip6t_set_ctl, 1894 #endif 1895 .get_optmin = IP6T_BASE_CTL, 1896 .get_optmax = IP6T_SO_GET_MAX+1, 1897 .get = do_ip6t_get_ctl, 1898 #ifdef CONFIG_COMPAT 1899 .compat_get = compat_do_ip6t_get_ctl, 1900 #endif 1901 .owner = THIS_MODULE, 1902 }; 1903 1904 static struct xt_match ip6t_builtin_mt[] __read_mostly = { 1905 { 1906 .name = "icmp6", 1907 .match = icmp6_match, 1908 .matchsize = sizeof(struct ip6t_icmp), 1909 .checkentry = icmp6_checkentry, 1910 .proto = IPPROTO_ICMPV6, 1911 .family = NFPROTO_IPV6, 1912 }, 1913 }; 1914 1915 static int __net_init ip6_tables_net_init(struct net *net) 1916 { 1917 return xt_proto_init(net, NFPROTO_IPV6); 1918 } 1919 1920 static void __net_exit ip6_tables_net_exit(struct net *net) 1921 { 1922 xt_proto_fini(net, NFPROTO_IPV6); 1923 } 1924 1925 static struct pernet_operations ip6_tables_net_ops = { 1926 .init = ip6_tables_net_init, 1927 .exit = ip6_tables_net_exit, 1928 }; 1929 1930 static int __init ip6_tables_init(void) 1931 { 1932 int ret; 1933 1934 ret = register_pernet_subsys(&ip6_tables_net_ops); 1935 if (ret < 0) 1936 goto err1; 1937 1938 /* No one else will be downing sem now, so we won't sleep */ 1939 ret = xt_register_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg)); 1940 if (ret < 0) 1941 goto err2; 1942 ret = xt_register_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt)); 1943 if (ret < 0) 1944 goto err4; 1945 1946 /* Register setsockopt */ 1947 ret = nf_register_sockopt(&ip6t_sockopts); 1948 if (ret < 0) 1949 goto err5; 1950 1951 return 0; 1952 1953 err5: 1954 xt_unregister_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt)); 1955 err4: 1956 xt_unregister_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg)); 1957 err2: 1958 unregister_pernet_subsys(&ip6_tables_net_ops); 1959 err1: 1960 return ret; 1961 } 1962 1963 static void __exit ip6_tables_fini(void) 1964 { 1965 nf_unregister_sockopt(&ip6t_sockopts); 1966 1967 xt_unregister_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt)); 1968 xt_unregister_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg)); 1969 unregister_pernet_subsys(&ip6_tables_net_ops); 1970 } 1971 1972 EXPORT_SYMBOL(ip6t_register_table); 1973 EXPORT_SYMBOL(ip6t_unregister_table); 1974 EXPORT_SYMBOL(ip6t_do_table); 1975 1976 module_init(ip6_tables_init); 1977 module_exit(ip6_tables_fini); 1978