static int nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { void *info = nft_expr_priv(expr); struct xt_target *target = expr->ops->data; struct xt_tgchk_param par; size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); u16 proto = 0; bool inv = false; union nft_entry e = {}; int ret; target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); if (ctx->nla[NFTA_RULE_COMPAT]) { ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); if (ret < 0) return ret; } nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); ret = xt_check_target(&par, size, proto, inv); if (ret < 0) return ret; /* The standard target cannot be used */ if (!target->target) return -EINVAL; return 0; }
static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) { struct xt_tgchk_param par; struct xt_target *target; int ret = 0; target = xt_request_find_target(AF_INET, t->u.user.name, t->u.user.revision); if (IS_ERR(target)) return PTR_ERR(target); t->u.kernel.target = target; par.table = table; par.entryinfo = NULL; par.target = target; par.targinfo = t->data; par.hook_mask = hook; par.family = NFPROTO_IPV4; ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); if (ret < 0) { module_put(t->u.kernel.target->me); return ret; } return 0; }
static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) { struct xt_target *target; int ret = 0; target = xt_request_find_target(AF_INET, t->u.user.name, t->u.user.revision); if (!target) return -ENOENT; t->u.kernel.target = target; ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), table, hook, 0, 0); if (ret) { module_put(t->u.kernel.target->me); return ret; } if (t->u.kernel.target->checkentry && !t->u.kernel.target->checkentry(table, NULL, t->u.kernel.target, t->data, hook)) { module_put(t->u.kernel.target->me); ret = -EINVAL; } return ret; }
static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) { struct ipt_target *target; int ret = 0; target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision); if (!target) return -ENOENT; DPRINTK("ipt_init_target: found %s\n", target->name); t->u.kernel.target = target; ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), table, hook, 0, 0); if (ret) return ret; if (t->u.kernel.target->checkentry && !t->u.kernel.target->checkentry(table, NULL, t->u.kernel.target, t->data, t->u.target_size - sizeof(*t), hook)) { DPRINTK("ipt_init_target: check failed for `%s'.\n", t->u.kernel.target->name); module_put(t->u.kernel.target->me); ret = -EINVAL; } return ret; }
static int nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { void *info = nft_expr_priv(expr); struct xt_target *target = expr->ops->data; struct xt_tgchk_param par; size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); u8 proto = 0; bool inv = false; union nft_entry e = {}; int ret; ret = nft_compat_chain_validate_dependency(target->table, ctx->chain); if (ret < 0) goto err; target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); if (ctx->nla[NFTA_RULE_COMPAT]) { ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); if (ret < 0) goto err; } nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); ret = xt_check_target(&par, size, proto, inv); if (ret < 0) goto err; /* The standard target cannot be used */ if (target->target == NULL) { ret = -EINVAL; goto err; } return 0; err: module_put(target->me); return ret; }