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

Configure Feed

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

at v5.0-rc8 1078 lines 27 kB view raw
1/* 2 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This software has been sponsored by Sophos Astaro <http://www.sophos.com> 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/netlink.h> 15#include <linux/netfilter.h> 16#include <linux/netfilter/nfnetlink.h> 17#include <linux/netfilter/nf_tables.h> 18#include <linux/netfilter/nf_tables_compat.h> 19#include <linux/netfilter/x_tables.h> 20#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv6/ip6_tables.h> 22#include <linux/netfilter_bridge/ebtables.h> 23#include <linux/netfilter_arp/arp_tables.h> 24#include <net/netfilter/nf_tables.h> 25#include <net/netns/generic.h> 26 27struct nft_xt { 28 struct list_head head; 29 struct nft_expr_ops ops; 30 refcount_t refcnt; 31 32 /* used only when transaction mutex is locked */ 33 unsigned int listcnt; 34 35 /* Unlike other expressions, ops doesn't have static storage duration. 36 * nft core assumes they do. We use kfree_rcu so that nft core can 37 * can check expr->ops->size even after nft_compat->destroy() frees 38 * the nft_xt struct that holds the ops structure. 39 */ 40 struct rcu_head rcu_head; 41}; 42 43/* Used for matches where *info is larger than X byte */ 44#define NFT_MATCH_LARGE_THRESH 192 45 46struct nft_xt_match_priv { 47 void *info; 48}; 49 50struct nft_compat_net { 51 struct list_head nft_target_list; 52 struct list_head nft_match_list; 53}; 54 55static unsigned int nft_compat_net_id __read_mostly; 56static struct nft_expr_type nft_match_type; 57static struct nft_expr_type nft_target_type; 58 59static struct nft_compat_net *nft_compat_pernet(struct net *net) 60{ 61 return net_generic(net, nft_compat_net_id); 62} 63 64static void nft_xt_get(struct nft_xt *xt) 65{ 66 /* refcount_inc() warns on 0 -> 1 transition, but we can't 67 * init the reference count to 1 in .select_ops -- we can't 68 * undo such an increase when another expression inside the same 69 * rule fails afterwards. 70 */ 71 if (xt->listcnt == 0) 72 refcount_set(&xt->refcnt, 1); 73 else 74 refcount_inc(&xt->refcnt); 75 76 xt->listcnt++; 77} 78 79static bool nft_xt_put(struct nft_xt *xt) 80{ 81 if (refcount_dec_and_test(&xt->refcnt)) { 82 WARN_ON_ONCE(!list_empty(&xt->head)); 83 kfree_rcu(xt, rcu_head); 84 return true; 85 } 86 87 return false; 88} 89 90static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx, 91 const char *tablename) 92{ 93 enum nft_chain_types type = NFT_CHAIN_T_DEFAULT; 94 const struct nft_chain *chain = ctx->chain; 95 const struct nft_base_chain *basechain; 96 97 if (!tablename || 98 !nft_is_base_chain(chain)) 99 return 0; 100 101 basechain = nft_base_chain(chain); 102 if (strcmp(tablename, "nat") == 0) { 103 if (ctx->family != NFPROTO_BRIDGE) 104 type = NFT_CHAIN_T_NAT; 105 if (basechain->type->type != type) 106 return -EINVAL; 107 } 108 109 return 0; 110} 111 112union nft_entry { 113 struct ipt_entry e4; 114 struct ip6t_entry e6; 115 struct ebt_entry ebt; 116 struct arpt_entry arp; 117}; 118 119static inline void 120nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info) 121{ 122 par->target = xt; 123 par->targinfo = xt_info; 124 par->hotdrop = false; 125} 126 127static void nft_target_eval_xt(const struct nft_expr *expr, 128 struct nft_regs *regs, 129 const struct nft_pktinfo *pkt) 130{ 131 void *info = nft_expr_priv(expr); 132 struct xt_target *target = expr->ops->data; 133 struct sk_buff *skb = pkt->skb; 134 int ret; 135 136 nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info); 137 138 ret = target->target(skb, &pkt->xt); 139 140 if (pkt->xt.hotdrop) 141 ret = NF_DROP; 142 143 switch (ret) { 144 case XT_CONTINUE: 145 regs->verdict.code = NFT_CONTINUE; 146 break; 147 default: 148 regs->verdict.code = ret; 149 break; 150 } 151} 152 153static void nft_target_eval_bridge(const struct nft_expr *expr, 154 struct nft_regs *regs, 155 const struct nft_pktinfo *pkt) 156{ 157 void *info = nft_expr_priv(expr); 158 struct xt_target *target = expr->ops->data; 159 struct sk_buff *skb = pkt->skb; 160 int ret; 161 162 nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info); 163 164 ret = target->target(skb, &pkt->xt); 165 166 if (pkt->xt.hotdrop) 167 ret = NF_DROP; 168 169 switch (ret) { 170 case EBT_ACCEPT: 171 regs->verdict.code = NF_ACCEPT; 172 break; 173 case EBT_DROP: 174 regs->verdict.code = NF_DROP; 175 break; 176 case EBT_CONTINUE: 177 regs->verdict.code = NFT_CONTINUE; 178 break; 179 case EBT_RETURN: 180 regs->verdict.code = NFT_RETURN; 181 break; 182 default: 183 regs->verdict.code = ret; 184 break; 185 } 186} 187 188static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = { 189 [NFTA_TARGET_NAME] = { .type = NLA_NUL_STRING }, 190 [NFTA_TARGET_REV] = { .type = NLA_U32 }, 191 [NFTA_TARGET_INFO] = { .type = NLA_BINARY }, 192}; 193 194static void 195nft_target_set_tgchk_param(struct xt_tgchk_param *par, 196 const struct nft_ctx *ctx, 197 struct xt_target *target, void *info, 198 union nft_entry *entry, u16 proto, bool inv) 199{ 200 par->net = ctx->net; 201 par->table = ctx->table->name; 202 switch (ctx->family) { 203 case AF_INET: 204 entry->e4.ip.proto = proto; 205 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; 206 break; 207 case AF_INET6: 208 if (proto) 209 entry->e6.ipv6.flags |= IP6T_F_PROTO; 210 211 entry->e6.ipv6.proto = proto; 212 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; 213 break; 214 case NFPROTO_BRIDGE: 215 entry->ebt.ethproto = (__force __be16)proto; 216 entry->ebt.invflags = inv ? EBT_IPROTO : 0; 217 break; 218 case NFPROTO_ARP: 219 break; 220 } 221 par->entryinfo = entry; 222 par->target = target; 223 par->targinfo = info; 224 if (nft_is_base_chain(ctx->chain)) { 225 const struct nft_base_chain *basechain = 226 nft_base_chain(ctx->chain); 227 const struct nf_hook_ops *ops = &basechain->ops; 228 229 par->hook_mask = 1 << ops->hooknum; 230 } else { 231 par->hook_mask = 0; 232 } 233 par->family = ctx->family; 234 par->nft_compat = true; 235} 236 237static void target_compat_from_user(struct xt_target *t, void *in, void *out) 238{ 239 int pad; 240 241 memcpy(out, in, t->targetsize); 242 pad = XT_ALIGN(t->targetsize) - t->targetsize; 243 if (pad > 0) 244 memset(out + t->targetsize, 0, pad); 245} 246 247static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = { 248 [NFTA_RULE_COMPAT_PROTO] = { .type = NLA_U32 }, 249 [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, 250}; 251 252static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) 253{ 254 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; 255 u32 flags; 256 int err; 257 258 err = nla_parse_nested(tb, NFTA_RULE_COMPAT_MAX, attr, 259 nft_rule_compat_policy, NULL); 260 if (err < 0) 261 return err; 262 263 if (!tb[NFTA_RULE_COMPAT_PROTO] || !tb[NFTA_RULE_COMPAT_FLAGS]) 264 return -EINVAL; 265 266 flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS])); 267 if (flags & ~NFT_RULE_COMPAT_F_MASK) 268 return -EINVAL; 269 if (flags & NFT_RULE_COMPAT_F_INV) 270 *inv = true; 271 272 *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); 273 return 0; 274} 275 276static int 277nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 278 const struct nlattr * const tb[]) 279{ 280 void *info = nft_expr_priv(expr); 281 struct xt_target *target = expr->ops->data; 282 struct xt_tgchk_param par; 283 size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); 284 struct nft_xt *nft_xt; 285 u16 proto = 0; 286 bool inv = false; 287 union nft_entry e = {}; 288 int ret; 289 290 target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); 291 292 if (ctx->nla[NFTA_RULE_COMPAT]) { 293 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); 294 if (ret < 0) 295 return ret; 296 } 297 298 nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); 299 300 ret = xt_check_target(&par, size, proto, inv); 301 if (ret < 0) 302 return ret; 303 304 /* The standard target cannot be used */ 305 if (!target->target) 306 return -EINVAL; 307 308 nft_xt = container_of(expr->ops, struct nft_xt, ops); 309 nft_xt_get(nft_xt); 310 return 0; 311} 312 313static void 314nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 315{ 316 struct xt_target *target = expr->ops->data; 317 void *info = nft_expr_priv(expr); 318 struct module *me = target->me; 319 struct xt_tgdtor_param par; 320 321 par.net = ctx->net; 322 par.target = target; 323 par.targinfo = info; 324 par.family = ctx->family; 325 if (par.target->destroy != NULL) 326 par.target->destroy(&par); 327 328 if (nft_xt_put(container_of(expr->ops, struct nft_xt, ops))) 329 module_put(me); 330} 331 332static int nft_extension_dump_info(struct sk_buff *skb, int attr, 333 const void *info, 334 unsigned int size, unsigned int user_size) 335{ 336 unsigned int info_size, aligned_size = XT_ALIGN(size); 337 struct nlattr *nla; 338 339 nla = nla_reserve(skb, attr, aligned_size); 340 if (!nla) 341 return -1; 342 343 info_size = user_size ? : size; 344 memcpy(nla_data(nla), info, info_size); 345 memset(nla_data(nla) + info_size, 0, aligned_size - info_size); 346 347 return 0; 348} 349 350static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr) 351{ 352 const struct xt_target *target = expr->ops->data; 353 void *info = nft_expr_priv(expr); 354 355 if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) || 356 nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) || 357 nft_extension_dump_info(skb, NFTA_TARGET_INFO, info, 358 target->targetsize, target->usersize)) 359 goto nla_put_failure; 360 361 return 0; 362 363nla_put_failure: 364 return -1; 365} 366 367static int nft_target_validate(const struct nft_ctx *ctx, 368 const struct nft_expr *expr, 369 const struct nft_data **data) 370{ 371 struct xt_target *target = expr->ops->data; 372 unsigned int hook_mask = 0; 373 int ret; 374 375 if (nft_is_base_chain(ctx->chain)) { 376 const struct nft_base_chain *basechain = 377 nft_base_chain(ctx->chain); 378 const struct nf_hook_ops *ops = &basechain->ops; 379 380 hook_mask = 1 << ops->hooknum; 381 if (target->hooks && !(hook_mask & target->hooks)) 382 return -EINVAL; 383 384 ret = nft_compat_chain_validate_dependency(ctx, target->table); 385 if (ret < 0) 386 return ret; 387 } 388 return 0; 389} 390 391static void __nft_match_eval(const struct nft_expr *expr, 392 struct nft_regs *regs, 393 const struct nft_pktinfo *pkt, 394 void *info) 395{ 396 struct xt_match *match = expr->ops->data; 397 struct sk_buff *skb = pkt->skb; 398 bool ret; 399 400 nft_compat_set_par((struct xt_action_param *)&pkt->xt, match, info); 401 402 ret = match->match(skb, (struct xt_action_param *)&pkt->xt); 403 404 if (pkt->xt.hotdrop) { 405 regs->verdict.code = NF_DROP; 406 return; 407 } 408 409 switch (ret ? 1 : 0) { 410 case 1: 411 regs->verdict.code = NFT_CONTINUE; 412 break; 413 case 0: 414 regs->verdict.code = NFT_BREAK; 415 break; 416 } 417} 418 419static void nft_match_large_eval(const struct nft_expr *expr, 420 struct nft_regs *regs, 421 const struct nft_pktinfo *pkt) 422{ 423 struct nft_xt_match_priv *priv = nft_expr_priv(expr); 424 425 __nft_match_eval(expr, regs, pkt, priv->info); 426} 427 428static void nft_match_eval(const struct nft_expr *expr, 429 struct nft_regs *regs, 430 const struct nft_pktinfo *pkt) 431{ 432 __nft_match_eval(expr, regs, pkt, nft_expr_priv(expr)); 433} 434 435static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { 436 [NFTA_MATCH_NAME] = { .type = NLA_NUL_STRING }, 437 [NFTA_MATCH_REV] = { .type = NLA_U32 }, 438 [NFTA_MATCH_INFO] = { .type = NLA_BINARY }, 439}; 440 441/* struct xt_mtchk_param and xt_tgchk_param look very similar */ 442static void 443nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, 444 struct xt_match *match, void *info, 445 union nft_entry *entry, u16 proto, bool inv) 446{ 447 par->net = ctx->net; 448 par->table = ctx->table->name; 449 switch (ctx->family) { 450 case AF_INET: 451 entry->e4.ip.proto = proto; 452 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; 453 break; 454 case AF_INET6: 455 if (proto) 456 entry->e6.ipv6.flags |= IP6T_F_PROTO; 457 458 entry->e6.ipv6.proto = proto; 459 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; 460 break; 461 case NFPROTO_BRIDGE: 462 entry->ebt.ethproto = (__force __be16)proto; 463 entry->ebt.invflags = inv ? EBT_IPROTO : 0; 464 break; 465 case NFPROTO_ARP: 466 break; 467 } 468 par->entryinfo = entry; 469 par->match = match; 470 par->matchinfo = info; 471 if (nft_is_base_chain(ctx->chain)) { 472 const struct nft_base_chain *basechain = 473 nft_base_chain(ctx->chain); 474 const struct nf_hook_ops *ops = &basechain->ops; 475 476 par->hook_mask = 1 << ops->hooknum; 477 } else { 478 par->hook_mask = 0; 479 } 480 par->family = ctx->family; 481 par->nft_compat = true; 482} 483 484static void match_compat_from_user(struct xt_match *m, void *in, void *out) 485{ 486 int pad; 487 488 memcpy(out, in, m->matchsize); 489 pad = XT_ALIGN(m->matchsize) - m->matchsize; 490 if (pad > 0) 491 memset(out + m->matchsize, 0, pad); 492} 493 494static int 495__nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 496 const struct nlattr * const tb[], 497 void *info) 498{ 499 struct xt_match *match = expr->ops->data; 500 struct xt_mtchk_param par; 501 size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); 502 struct nft_xt *nft_xt; 503 u16 proto = 0; 504 bool inv = false; 505 union nft_entry e = {}; 506 int ret; 507 508 match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info); 509 510 if (ctx->nla[NFTA_RULE_COMPAT]) { 511 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); 512 if (ret < 0) 513 return ret; 514 } 515 516 nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); 517 518 ret = xt_check_match(&par, size, proto, inv); 519 if (ret < 0) 520 return ret; 521 522 nft_xt = container_of(expr->ops, struct nft_xt, ops); 523 nft_xt_get(nft_xt); 524 return 0; 525} 526 527static int 528nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 529 const struct nlattr * const tb[]) 530{ 531 return __nft_match_init(ctx, expr, tb, nft_expr_priv(expr)); 532} 533 534static int 535nft_match_large_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 536 const struct nlattr * const tb[]) 537{ 538 struct nft_xt_match_priv *priv = nft_expr_priv(expr); 539 struct xt_match *m = expr->ops->data; 540 int ret; 541 542 priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL); 543 if (!priv->info) 544 return -ENOMEM; 545 546 ret = __nft_match_init(ctx, expr, tb, priv->info); 547 if (ret) 548 kfree(priv->info); 549 return ret; 550} 551 552static void 553__nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr, 554 void *info) 555{ 556 struct xt_match *match = expr->ops->data; 557 struct module *me = match->me; 558 struct xt_mtdtor_param par; 559 560 par.net = ctx->net; 561 par.match = match; 562 par.matchinfo = info; 563 par.family = ctx->family; 564 if (par.match->destroy != NULL) 565 par.match->destroy(&par); 566 567 if (nft_xt_put(container_of(expr->ops, struct nft_xt, ops))) 568 module_put(me); 569} 570 571static void 572nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 573{ 574 __nft_match_destroy(ctx, expr, nft_expr_priv(expr)); 575} 576 577static void nft_compat_deactivate(const struct nft_ctx *ctx, 578 const struct nft_expr *expr, 579 enum nft_trans_phase phase) 580{ 581 struct nft_xt *xt = container_of(expr->ops, struct nft_xt, ops); 582 583 if (phase == NFT_TRANS_ABORT || phase == NFT_TRANS_COMMIT) { 584 if (--xt->listcnt == 0) 585 list_del_init(&xt->head); 586 } 587} 588 589static void 590nft_match_large_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 591{ 592 struct nft_xt_match_priv *priv = nft_expr_priv(expr); 593 594 __nft_match_destroy(ctx, expr, priv->info); 595 kfree(priv->info); 596} 597 598static int __nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr, 599 void *info) 600{ 601 struct xt_match *match = expr->ops->data; 602 603 if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) || 604 nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) || 605 nft_extension_dump_info(skb, NFTA_MATCH_INFO, info, 606 match->matchsize, match->usersize)) 607 goto nla_put_failure; 608 609 return 0; 610 611nla_put_failure: 612 return -1; 613} 614 615static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr) 616{ 617 return __nft_match_dump(skb, expr, nft_expr_priv(expr)); 618} 619 620static int nft_match_large_dump(struct sk_buff *skb, const struct nft_expr *e) 621{ 622 struct nft_xt_match_priv *priv = nft_expr_priv(e); 623 624 return __nft_match_dump(skb, e, priv->info); 625} 626 627static int nft_match_validate(const struct nft_ctx *ctx, 628 const struct nft_expr *expr, 629 const struct nft_data **data) 630{ 631 struct xt_match *match = expr->ops->data; 632 unsigned int hook_mask = 0; 633 int ret; 634 635 if (nft_is_base_chain(ctx->chain)) { 636 const struct nft_base_chain *basechain = 637 nft_base_chain(ctx->chain); 638 const struct nf_hook_ops *ops = &basechain->ops; 639 640 hook_mask = 1 << ops->hooknum; 641 if (match->hooks && !(hook_mask & match->hooks)) 642 return -EINVAL; 643 644 ret = nft_compat_chain_validate_dependency(ctx, match->table); 645 if (ret < 0) 646 return ret; 647 } 648 return 0; 649} 650 651static int 652nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, 653 int event, u16 family, const char *name, 654 int rev, int target) 655{ 656 struct nlmsghdr *nlh; 657 struct nfgenmsg *nfmsg; 658 unsigned int flags = portid ? NLM_F_MULTI : 0; 659 660 event = nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT, event); 661 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); 662 if (nlh == NULL) 663 goto nlmsg_failure; 664 665 nfmsg = nlmsg_data(nlh); 666 nfmsg->nfgen_family = family; 667 nfmsg->version = NFNETLINK_V0; 668 nfmsg->res_id = 0; 669 670 if (nla_put_string(skb, NFTA_COMPAT_NAME, name) || 671 nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) || 672 nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target))) 673 goto nla_put_failure; 674 675 nlmsg_end(skb, nlh); 676 return skb->len; 677 678nlmsg_failure: 679nla_put_failure: 680 nlmsg_cancel(skb, nlh); 681 return -1; 682} 683 684static int nfnl_compat_get_rcu(struct net *net, struct sock *nfnl, 685 struct sk_buff *skb, const struct nlmsghdr *nlh, 686 const struct nlattr * const tb[], 687 struct netlink_ext_ack *extack) 688{ 689 int ret = 0, target; 690 struct nfgenmsg *nfmsg; 691 const char *fmt; 692 const char *name; 693 u32 rev; 694 struct sk_buff *skb2; 695 696 if (tb[NFTA_COMPAT_NAME] == NULL || 697 tb[NFTA_COMPAT_REV] == NULL || 698 tb[NFTA_COMPAT_TYPE] == NULL) 699 return -EINVAL; 700 701 name = nla_data(tb[NFTA_COMPAT_NAME]); 702 rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV])); 703 target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE])); 704 705 nfmsg = nlmsg_data(nlh); 706 707 switch(nfmsg->nfgen_family) { 708 case AF_INET: 709 fmt = "ipt_%s"; 710 break; 711 case AF_INET6: 712 fmt = "ip6t_%s"; 713 break; 714 case NFPROTO_BRIDGE: 715 fmt = "ebt_%s"; 716 break; 717 case NFPROTO_ARP: 718 fmt = "arpt_%s"; 719 break; 720 default: 721 pr_err("nft_compat: unsupported protocol %d\n", 722 nfmsg->nfgen_family); 723 return -EINVAL; 724 } 725 726 if (!try_module_get(THIS_MODULE)) 727 return -EINVAL; 728 729 rcu_read_unlock(); 730 try_then_request_module(xt_find_revision(nfmsg->nfgen_family, name, 731 rev, target, &ret), 732 fmt, name); 733 if (ret < 0) 734 goto out_put; 735 736 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 737 if (skb2 == NULL) { 738 ret = -ENOMEM; 739 goto out_put; 740 } 741 742 /* include the best revision for this extension in the message */ 743 if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid, 744 nlh->nlmsg_seq, 745 NFNL_MSG_TYPE(nlh->nlmsg_type), 746 NFNL_MSG_COMPAT_GET, 747 nfmsg->nfgen_family, 748 name, ret, target) <= 0) { 749 kfree_skb(skb2); 750 goto out_put; 751 } 752 753 ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid, 754 MSG_DONTWAIT); 755 if (ret > 0) 756 ret = 0; 757out_put: 758 rcu_read_lock(); 759 module_put(THIS_MODULE); 760 return ret == -EAGAIN ? -ENOBUFS : ret; 761} 762 763static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = { 764 [NFTA_COMPAT_NAME] = { .type = NLA_NUL_STRING, 765 .len = NFT_COMPAT_NAME_MAX-1 }, 766 [NFTA_COMPAT_REV] = { .type = NLA_U32 }, 767 [NFTA_COMPAT_TYPE] = { .type = NLA_U32 }, 768}; 769 770static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = { 771 [NFNL_MSG_COMPAT_GET] = { .call_rcu = nfnl_compat_get_rcu, 772 .attr_count = NFTA_COMPAT_MAX, 773 .policy = nfnl_compat_policy_get }, 774}; 775 776static const struct nfnetlink_subsystem nfnl_compat_subsys = { 777 .name = "nft-compat", 778 .subsys_id = NFNL_SUBSYS_NFT_COMPAT, 779 .cb_count = NFNL_MSG_COMPAT_MAX, 780 .cb = nfnl_nft_compat_cb, 781}; 782 783static bool nft_match_cmp(const struct xt_match *match, 784 const char *name, u32 rev, u32 family) 785{ 786 return strcmp(match->name, name) == 0 && match->revision == rev && 787 (match->family == NFPROTO_UNSPEC || match->family == family); 788} 789 790static const struct nft_expr_ops * 791nft_match_select_ops(const struct nft_ctx *ctx, 792 const struct nlattr * const tb[]) 793{ 794 struct nft_compat_net *cn; 795 struct nft_xt *nft_match; 796 struct xt_match *match; 797 unsigned int matchsize; 798 char *mt_name; 799 u32 rev, family; 800 int err; 801 802 if (tb[NFTA_MATCH_NAME] == NULL || 803 tb[NFTA_MATCH_REV] == NULL || 804 tb[NFTA_MATCH_INFO] == NULL) 805 return ERR_PTR(-EINVAL); 806 807 mt_name = nla_data(tb[NFTA_MATCH_NAME]); 808 rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV])); 809 family = ctx->family; 810 811 cn = nft_compat_pernet(ctx->net); 812 813 /* Re-use the existing match if it's already loaded. */ 814 list_for_each_entry(nft_match, &cn->nft_match_list, head) { 815 struct xt_match *match = nft_match->ops.data; 816 817 if (nft_match_cmp(match, mt_name, rev, family)) 818 return &nft_match->ops; 819 } 820 821 match = xt_request_find_match(family, mt_name, rev); 822 if (IS_ERR(match)) 823 return ERR_PTR(-ENOENT); 824 825 if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) { 826 err = -EINVAL; 827 goto err; 828 } 829 830 /* This is the first time we use this match, allocate operations */ 831 nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 832 if (nft_match == NULL) { 833 err = -ENOMEM; 834 goto err; 835 } 836 837 refcount_set(&nft_match->refcnt, 0); 838 nft_match->ops.type = &nft_match_type; 839 nft_match->ops.eval = nft_match_eval; 840 nft_match->ops.init = nft_match_init; 841 nft_match->ops.destroy = nft_match_destroy; 842 nft_match->ops.deactivate = nft_compat_deactivate; 843 nft_match->ops.dump = nft_match_dump; 844 nft_match->ops.validate = nft_match_validate; 845 nft_match->ops.data = match; 846 847 matchsize = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize)); 848 if (matchsize > NFT_MATCH_LARGE_THRESH) { 849 matchsize = NFT_EXPR_SIZE(sizeof(struct nft_xt_match_priv)); 850 851 nft_match->ops.eval = nft_match_large_eval; 852 nft_match->ops.init = nft_match_large_init; 853 nft_match->ops.destroy = nft_match_large_destroy; 854 nft_match->ops.dump = nft_match_large_dump; 855 } 856 857 nft_match->ops.size = matchsize; 858 859 nft_match->listcnt = 0; 860 list_add(&nft_match->head, &cn->nft_match_list); 861 862 return &nft_match->ops; 863err: 864 module_put(match->me); 865 return ERR_PTR(err); 866} 867 868static struct nft_expr_type nft_match_type __read_mostly = { 869 .name = "match", 870 .select_ops = nft_match_select_ops, 871 .policy = nft_match_policy, 872 .maxattr = NFTA_MATCH_MAX, 873 .owner = THIS_MODULE, 874}; 875 876static bool nft_target_cmp(const struct xt_target *tg, 877 const char *name, u32 rev, u32 family) 878{ 879 return strcmp(tg->name, name) == 0 && tg->revision == rev && 880 (tg->family == NFPROTO_UNSPEC || tg->family == family); 881} 882 883static const struct nft_expr_ops * 884nft_target_select_ops(const struct nft_ctx *ctx, 885 const struct nlattr * const tb[]) 886{ 887 struct nft_compat_net *cn; 888 struct nft_xt *nft_target; 889 struct xt_target *target; 890 char *tg_name; 891 u32 rev, family; 892 int err; 893 894 if (tb[NFTA_TARGET_NAME] == NULL || 895 tb[NFTA_TARGET_REV] == NULL || 896 tb[NFTA_TARGET_INFO] == NULL) 897 return ERR_PTR(-EINVAL); 898 899 tg_name = nla_data(tb[NFTA_TARGET_NAME]); 900 rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV])); 901 family = ctx->family; 902 903 if (strcmp(tg_name, XT_ERROR_TARGET) == 0 || 904 strcmp(tg_name, XT_STANDARD_TARGET) == 0 || 905 strcmp(tg_name, "standard") == 0) 906 return ERR_PTR(-EINVAL); 907 908 cn = nft_compat_pernet(ctx->net); 909 /* Re-use the existing target if it's already loaded. */ 910 list_for_each_entry(nft_target, &cn->nft_target_list, head) { 911 struct xt_target *target = nft_target->ops.data; 912 913 if (!target->target) 914 continue; 915 916 if (nft_target_cmp(target, tg_name, rev, family)) 917 return &nft_target->ops; 918 } 919 920 target = xt_request_find_target(family, tg_name, rev); 921 if (IS_ERR(target)) 922 return ERR_PTR(-ENOENT); 923 924 if (!target->target) { 925 err = -EINVAL; 926 goto err; 927 } 928 929 if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) { 930 err = -EINVAL; 931 goto err; 932 } 933 934 /* This is the first time we use this target, allocate operations */ 935 nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 936 if (nft_target == NULL) { 937 err = -ENOMEM; 938 goto err; 939 } 940 941 refcount_set(&nft_target->refcnt, 0); 942 nft_target->ops.type = &nft_target_type; 943 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); 944 nft_target->ops.init = nft_target_init; 945 nft_target->ops.destroy = nft_target_destroy; 946 nft_target->ops.deactivate = nft_compat_deactivate; 947 nft_target->ops.dump = nft_target_dump; 948 nft_target->ops.validate = nft_target_validate; 949 nft_target->ops.data = target; 950 951 if (family == NFPROTO_BRIDGE) 952 nft_target->ops.eval = nft_target_eval_bridge; 953 else 954 nft_target->ops.eval = nft_target_eval_xt; 955 956 nft_target->listcnt = 0; 957 list_add(&nft_target->head, &cn->nft_target_list); 958 959 return &nft_target->ops; 960err: 961 module_put(target->me); 962 return ERR_PTR(err); 963} 964 965static struct nft_expr_type nft_target_type __read_mostly = { 966 .name = "target", 967 .select_ops = nft_target_select_ops, 968 .policy = nft_target_policy, 969 .maxattr = NFTA_TARGET_MAX, 970 .owner = THIS_MODULE, 971}; 972 973static int __net_init nft_compat_init_net(struct net *net) 974{ 975 struct nft_compat_net *cn = nft_compat_pernet(net); 976 977 INIT_LIST_HEAD(&cn->nft_target_list); 978 INIT_LIST_HEAD(&cn->nft_match_list); 979 980 return 0; 981} 982 983static void __net_exit nft_compat_exit_net(struct net *net) 984{ 985 struct nft_compat_net *cn = nft_compat_pernet(net); 986 struct nft_xt *xt, *next; 987 988 if (list_empty(&cn->nft_match_list) && 989 list_empty(&cn->nft_target_list)) 990 return; 991 992 /* If there was an error that caused nft_xt expr to not be initialized 993 * fully and noone else requested the same expression later, the lists 994 * contain 0-refcount entries that still hold module reference. 995 * 996 * Clean them here. 997 */ 998 mutex_lock(&net->nft.commit_mutex); 999 list_for_each_entry_safe(xt, next, &cn->nft_target_list, head) { 1000 struct xt_target *target = xt->ops.data; 1001 1002 list_del_init(&xt->head); 1003 1004 if (refcount_read(&xt->refcnt)) 1005 continue; 1006 module_put(target->me); 1007 kfree(xt); 1008 } 1009 1010 list_for_each_entry_safe(xt, next, &cn->nft_match_list, head) { 1011 struct xt_match *match = xt->ops.data; 1012 1013 list_del_init(&xt->head); 1014 1015 if (refcount_read(&xt->refcnt)) 1016 continue; 1017 module_put(match->me); 1018 kfree(xt); 1019 } 1020 mutex_unlock(&net->nft.commit_mutex); 1021} 1022 1023static struct pernet_operations nft_compat_net_ops = { 1024 .init = nft_compat_init_net, 1025 .exit = nft_compat_exit_net, 1026 .id = &nft_compat_net_id, 1027 .size = sizeof(struct nft_compat_net), 1028}; 1029 1030static int __init nft_compat_module_init(void) 1031{ 1032 int ret; 1033 1034 ret = register_pernet_subsys(&nft_compat_net_ops); 1035 if (ret < 0) 1036 goto err_target; 1037 1038 ret = nft_register_expr(&nft_match_type); 1039 if (ret < 0) 1040 goto err_pernet; 1041 1042 ret = nft_register_expr(&nft_target_type); 1043 if (ret < 0) 1044 goto err_match; 1045 1046 ret = nfnetlink_subsys_register(&nfnl_compat_subsys); 1047 if (ret < 0) { 1048 pr_err("nft_compat: cannot register with nfnetlink.\n"); 1049 goto err_target; 1050 } 1051 1052 return ret; 1053err_target: 1054 nft_unregister_expr(&nft_target_type); 1055err_match: 1056 nft_unregister_expr(&nft_match_type); 1057err_pernet: 1058 unregister_pernet_subsys(&nft_compat_net_ops); 1059 return ret; 1060} 1061 1062static void __exit nft_compat_module_exit(void) 1063{ 1064 nfnetlink_subsys_unregister(&nfnl_compat_subsys); 1065 nft_unregister_expr(&nft_target_type); 1066 nft_unregister_expr(&nft_match_type); 1067 unregister_pernet_subsys(&nft_compat_net_ops); 1068} 1069 1070MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT); 1071 1072module_init(nft_compat_module_init); 1073module_exit(nft_compat_module_exit); 1074 1075MODULE_LICENSE("GPL"); 1076MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); 1077MODULE_ALIAS_NFT_EXPR("match"); 1078MODULE_ALIAS_NFT_EXPR("target");