From patchwork Sun Apr 29 14:56:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taehee Yoo X-Patchwork-Id: 906362 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="lok3Bo6q"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40YrNT6sWSz9ry1 for ; Mon, 30 Apr 2018 00:56:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753586AbeD2O4k (ORCPT ); Sun, 29 Apr 2018 10:56:40 -0400 Received: from mail-pg0-f66.google.com ([74.125.83.66]:46854 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753580AbeD2O4j (ORCPT ); Sun, 29 Apr 2018 10:56:39 -0400 Received: by mail-pg0-f66.google.com with SMTP id z4-v6so4674906pgu.13 for ; Sun, 29 Apr 2018 07:56:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=fgPIPGlv+FyR5AcsIvBkqyZXG0IQ1IZnRL7Iquj9CpU=; b=lok3Bo6qy6T0wcZNuprbezJeQ0F2hu016sxhI0DVzyCz6ojE0Yz2PHKQTsD2O/qBzs AOVDRMHm8N3lDus7ruJh5/H2W53H00v8U+2zR/CPbLAFbOzDAhmYcQ2VCS/Nguky0oeq 4uZNkRteeRxq42chekbcYmY3gYluIU+J0i5Qw8xmSVrXQpJ4rDCKgUmJJyws0Sptp2BW 8D3Q8nT9GBOGwIkRrq5BjU1zcrasnvawohxfNjK6y6duAmKoELgobV13wOyxWnJI8fUl j0bygXQeDYSsPAaIH2ksxDg9Ktcj2HjspJPgXDhRLi2Um65PdgD15EQ93E3QKdVERspG 6HoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=fgPIPGlv+FyR5AcsIvBkqyZXG0IQ1IZnRL7Iquj9CpU=; b=okI5GLzagHQ0XpdPDdb3A1Ds+B2RJtxqmvdEfLuq/cfJ4VC80QFrfsPQ1/cE8sjsGj 9U1ywW+VPQHem6Fcq+bT4l2tjUKmp3fdef8K5Xh/iHXitpUtW3DwFKRfP02Cf483O7G+ ByN5M1iaM14+1VTulK13aPvrNh26m4f0HqWrev5rFghuQ+9OlSYJ8RP+F4rZ7FCbZUBk D/5V0vBPmyOi++HSZ0d7h9zxe7NWtXPzCJvkmcFF73TpZbMduUNHUDNLMcTJIbWOoWfH 5g2CjImlQZ7Yw3eEsUlNdXU0LjU29vYlBOOBq8Zlc3/xe8ZxWjW5yolk55oETEvEX20g zGQw== X-Gm-Message-State: ALQs6tAwBawHYlnksUdFlRNZeuBHhZlZ8L45nfy2aIvVRyG+dsNHw2X5 7r9RNR6viPWuj5H2hbpCITg= X-Google-Smtp-Source: AB8JxZo03gE6fZeQF7HNE0Gn7LOWUxIx6MU5uQFi7ATH7V3ozVOq3mYxuygVsJCLpXWFxOYKm8ZYYw== X-Received: by 2002:a17:902:b2c8:: with SMTP id x8-v6mr9638137plw.3.1525013799426; Sun, 29 Apr 2018 07:56:39 -0700 (PDT) Received: from ap-To-be-filled-by-O-E-M.8.8.8.8 ([125.130.197.10]) by smtp.gmail.com with ESMTPSA id u68sm10437842pfu.167.2018.04.29.07.56.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 29 Apr 2018 07:56:38 -0700 (PDT) From: Taehee Yoo To: pablo@netfilter.org, netfilter-devel@vger.kernel.org Cc: ap420073@gmail.com Subject: [PATCH 1/3 nf-next] netfilter: nf_tables: add release callback in nft_expr_type Date: Sun, 29 Apr 2018 23:56:33 +0900 Message-Id: <20180429145633.12807-1-ap420073@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch adds the new release callback to release resources allocated in nft_expr_type->select_ops. This release callback can be used by error path in the nf_tables_newrule routine. Only the select_ops of the nft_compat.c allocates memory and holds modules so far. Signed-off-by: Taehee Yoo Reported-by: Taehee Yoo Signed-off-by: Florian Westphal --- include/net/netfilter/nf_tables.h | 2 ++ net/netfilter/nft_compat.c | 52 +++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index cd368d1..2e71dc7 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -688,6 +688,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, * struct nft_expr_type - nf_tables expression type * * @select_ops: function to select nft_expr_ops + * @release : function to release * @ops: default ops, used when no select_ops functions is present * @list: used internally * @name: Identifier @@ -700,6 +701,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, struct nft_expr_type { const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, const struct nlattr * const tb[]); + void (*release)(const struct nft_expr_ops *ops); const struct nft_expr_ops *ops; struct list_head list; const char *name; diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 8e23726..31ffe27 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -236,25 +236,20 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, if (ctx->nla[NFTA_RULE_COMPAT]) { ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); if (ret < 0) - goto err; + 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) - goto err; + return ret; /* The standard target cannot be used */ - if (target->target == NULL) { - ret = -EINVAL; - goto err; - } + if (!target->target) + return -EINVAL; return 0; -err: - module_put(target->me); - return ret; } static void @@ -268,11 +263,8 @@ nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) par.target = target; par.targinfo = info; par.family = ctx->family; - if (par.target->destroy != NULL) + if (par.target->destroy) par.target->destroy(&par); - - nft_xt_put(container_of(expr->ops, struct nft_xt, ops)); - module_put(target->me); } static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr) @@ -421,19 +413,16 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, if (ctx->nla[NFTA_RULE_COMPAT]) { ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); if (ret < 0) - goto err; + return ret; } nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); ret = xt_check_match(&par, size, proto, inv); if (ret < 0) - goto err; + return ret; return 0; -err: - module_put(match->me); - return ret; } static void @@ -447,11 +436,8 @@ nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) par.match = match; par.matchinfo = info; par.family = ctx->family; - if (par.match->destroy != NULL) + if (par.match->destroy) par.match->destroy(&par); - - nft_xt_put(container_of(expr->ops, struct nft_xt, ops)); - module_put(match->me); } static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr) @@ -674,7 +660,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, /* This is the first time we use this match, allocate operations */ nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); - if (nft_match == NULL) { + if (!nft_match) { err = -ENOMEM; goto err; } @@ -697,9 +683,18 @@ nft_match_select_ops(const struct nft_ctx *ctx, return ERR_PTR(err); } +static void nft_match_release(const struct nft_expr_ops *ops) +{ + struct xt_match *match = ops->data; + + nft_xt_put(container_of(ops, struct nft_xt, ops)); + module_put(match->me); +} + static struct nft_expr_type nft_match_type __read_mostly = { .name = "match", .select_ops = nft_match_select_ops, + .release = nft_match_release, .policy = nft_match_policy, .maxattr = NFTA_MATCH_MAX, .owner = THIS_MODULE, @@ -759,7 +754,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, /* This is the first time we use this target, allocate operations */ nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); - if (nft_target == NULL) { + if (!nft_target) { err = -ENOMEM; goto err; } @@ -786,9 +781,18 @@ nft_target_select_ops(const struct nft_ctx *ctx, return ERR_PTR(err); } +static void nft_target_release(const struct nft_expr_ops *ops) +{ + struct xt_target *target = ops->data; + + nft_xt_put(container_of(ops, struct nft_xt, ops)); + module_put(target->me); +} + static struct nft_expr_type nft_target_type __read_mostly = { .name = "target", .select_ops = nft_target_select_ops, + .release = nft_target_release, .policy = nft_target_policy, .maxattr = NFTA_TARGET_MAX, .owner = THIS_MODULE, From patchwork Sun Apr 29 14:56:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taehee Yoo X-Patchwork-Id: 906363 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oSAWBJD/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40YrNr1Vfvz9ry1 for ; Mon, 30 Apr 2018 00:57:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753582AbeD2O47 (ORCPT ); Sun, 29 Apr 2018 10:56:59 -0400 Received: from mail-pg0-f67.google.com ([74.125.83.67]:37513 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753197AbeD2O47 (ORCPT ); Sun, 29 Apr 2018 10:56:59 -0400 Received: by mail-pg0-f67.google.com with SMTP id a13-v6so4694186pgu.4 for ; Sun, 29 Apr 2018 07:56:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=AfjPQw9FpOH6rXOzyFwtQXBpLosz0x9MLjBxlyCbmbI=; b=oSAWBJD/Mq3ozYW6BbZXWLk2JEWI5CZS+mlmMpFdWkclDiSpvANXpBbOdE5XlDC7Dk Va0Ub+CWlwonDth+7bZKdsbk6W+rgQ+s/GsEvzbIqFf1OdPS6Gk4OEb6IWKEwTAOlwn6 aioMnzMg+S+3KeIN7vYp5bMhSOm7kO84ysOwqPQUMI3uOd2/z+yY/UHBiisfDcJbL4Va AFMf1bdUdeQdFmffLnEj7n5n/L2zTswtA4JtOojWfTKtRWeBKDdVekdCOcgb8kkbWibm lOJRYirtwyZct02FUE8SnfbSkHZYzhqt3wXbZKLpEYVhjbTIHq7tOyElPWa3CvWpxE7y O8vA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=AfjPQw9FpOH6rXOzyFwtQXBpLosz0x9MLjBxlyCbmbI=; b=CZlo5s5KOY/Vdz/gH2w3BieIL0b6Tn1cTbJ/LlaoQ8TcW66GQc+Ko5DCepaHMKf9t/ limrkNnYtrC5wO9W+RZvaFxQl8si9vRvWU2aKyJ6fEFqldG6MnHnJxh8zHsxUj94S63l Te9mnd+I8YzsfRHsYC/c0kYJGka15XHlTdcjwq7phCMMa+Hc3scqzH+EustdpzTIC4AL Rh5CBfIxGNASR94ZbrEr/k32jeeYc3XHCU2P8GwZy2oZrRTanFgVlsDYDWh2g41eRUeN IkK2uGydmErx3TpZ3bPIhpvE8JcL94azoQvvlL/94vo74/bRc51nb4GO3ijBI83svy74 y/vQ== X-Gm-Message-State: ALQs6tDMnBMn8Ajzh6I0Ep6Z2aBEioLGFZQQnIs3S/eOBJZVp/9ZppNS p0nai1t1yYgq2XQJx0Xcido= X-Google-Smtp-Source: AB8JxZojeMfj21b9JbUZ1Q0DjE8IibU97XYPYU/NBdeUkOZBLvnYmQwcYKlaKM7Q6EChVsPyMqvtRw== X-Received: by 2002:a65:558c:: with SMTP id j12-v6mr7916398pgs.262.1525013818480; Sun, 29 Apr 2018 07:56:58 -0700 (PDT) Received: from ap-To-be-filled-by-O-E-M.8.8.8.8 ([125.130.197.10]) by smtp.gmail.com with ESMTPSA id h130sm11527059pfc.98.2018.04.29.07.56.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 29 Apr 2018 07:56:57 -0700 (PDT) From: Taehee Yoo To: pablo@netfilter.org, netfilter-devel@vger.kernel.org Cc: ap420073@gmail.com Subject: [PATCH 2/3 nf-next] netfilter: fix error path of the nf_tables_newrule Date: Sun, 29 Apr 2018 23:56:52 +0900 Message-Id: <20180429145652.12936-1-ap420073@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org There is module leak in the error path of the nf_tables_newrule. In order to solve this, a member nft_expr_type *type is added into the nft_expr_info. so that, we can make separated error path of the nft_expr_ops and the nft_expr_type. So that, the nf_tables_rule_destroy is not used in the error path of the nf_tables_newrule anymore. Steps to reproduce: $iptables-compat -I OUTPUT -m cpu --cpu 0 $iptables-compat -F $lsmod Module Size Used by xt_cpu 16384 1 Signed-off-by: Taehee Yoo --- net/netfilter/nf_tables_api.c | 46 +++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 9134cc4..981f35e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1814,6 +1814,7 @@ int nft_expr_dump(struct sk_buff *skb, unsigned int attr, struct nft_expr_info { const struct nft_expr_ops *ops; + const struct nft_expr_type *type; struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; }; @@ -1853,6 +1854,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx, ops = type->ops; info->ops = ops; + info->type = type; return 0; err1: @@ -1895,9 +1897,14 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx, static void nf_tables_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr) { + struct module *module = expr->ops->type->owner; + if (expr->ops->destroy) expr->ops->destroy(ctx, expr); - module_put(expr->ops->type->owner); + if (expr->ops->type->release) + expr->ops->type->release(expr->ops); + + module_put(module); } struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, @@ -1922,9 +1929,11 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, return expr; err3: + if (info.type->release) + info.type->release(info.ops); kfree(expr); err2: - module_put(info.ops->type->owner); + module_put(info.type->owner); err1: return ERR_PTR(err); } @@ -2258,7 +2267,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, struct nft_expr *expr; struct nft_ctx ctx; struct nlattr *tmp; - unsigned int size, i, n, ulen = 0, usize = 0; + unsigned int size, i, n_type, n_ops, ulen = 0, usize = 0; int err, rem; bool create; u64 handle, pos_handle; @@ -2307,20 +2316,20 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); - n = 0; + n_type = 0; size = 0; if (nla[NFTA_RULE_EXPRESSIONS]) { nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) { err = -EINVAL; if (nla_type(tmp) != NFTA_LIST_ELEM) goto err1; - if (n == NFT_RULE_MAXEXPRS) + if (n_type == NFT_RULE_MAXEXPRS) goto err1; - err = nf_tables_expr_parse(&ctx, tmp, &info[n]); + err = nf_tables_expr_parse(&ctx, tmp, &info[n_type]); if (err < 0) goto err1; - size += info[n].ops->size; - n++; + size += info[n_type].ops->size; + n_type++; } } /* Check for overflow of dlen field */ @@ -2352,11 +2361,10 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, } expr = nft_expr_first(rule); - for (i = 0; i < n; i++) { - err = nf_tables_newexpr(&ctx, &info[i], expr); + for (n_ops = 0; n_ops < n_type; n_ops++) { + err = nf_tables_newexpr(&ctx, &info[n_ops], expr); if (err < 0) goto err2; - info[i].ops = NULL; expr = nft_expr_next(expr); } @@ -2397,11 +2405,19 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, err3: list_del_rcu(&rule->list); err2: - nf_tables_rule_destroy(&ctx, rule); + expr = nft_expr_first(rule); + for (i = 0; i < n_ops; i++) { + if (expr->ops && expr->ops->destroy) + expr->ops->destroy(&ctx, expr); + expr = nft_expr_next(expr); + } + kfree(rule); + err1: - for (i = 0; i < n; i++) { - if (info[i].ops != NULL) - module_put(info[i].ops->type->owner); + for (i = 0; i < n_type; i++) { + if (info[i].type->release) + info[i].type->release(info[i].ops); + module_put(info[i].type->owner); } return err; } From patchwork Sun Apr 29 14:57:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taehee Yoo X-Patchwork-Id: 906364 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="DLWP3ZGa"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40YrPC0cpyz9ry1 for ; Mon, 30 Apr 2018 00:57:19 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753599AbeD2O5S (ORCPT ); Sun, 29 Apr 2018 10:57:18 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:42021 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753533AbeD2O5S (ORCPT ); Sun, 29 Apr 2018 10:57:18 -0400 Received: by mail-pf0-f196.google.com with SMTP id a11so4863442pfn.9 for ; Sun, 29 Apr 2018 07:57:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=7iLmMMFmYavpOj4y3nDSGOCAl5XqFxPRAJI3rHQiUWE=; b=DLWP3ZGaZ5BIKHvemiWmamULj1cCnONTf4QBKfPHy4BFDQxgTOR4nx/CImjDZCVvFr iGKZcdW9gk5VKxhrY0W5P0jlHA6COQmT1aF9doA2oToWpE40peI6j1FoNTRfSuFoBDjz WTsZED+pCNUYzK2swputGQgokkQXPl4W0YRIJgGWEFFt3L+D2IErpB8oTEZV8nuuaofy 09lX+Yk5rxIj+HlCUJ1HEaTqj+3oIROS2YfqYVQZkPt1TnRxS2xP8sVPLXEs5q4iMI9U wmLU7PQX7SlIWHZCbmXeU2epAqg/pdYzI7uSBCUHZAa+0zmvCLoT5oDFyUCP9cHT1or+ rxIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=7iLmMMFmYavpOj4y3nDSGOCAl5XqFxPRAJI3rHQiUWE=; b=hrrf4bRQ7kjv3mW1KWvGvzUyt58BQyp/OzRrcoZ5CckUaNdwlggWGmSHm4yi8/z2eR 74iWzbOT/6ie3Ew2YGtN0Eu5L5P1aMRZFqkRx4XWQ3czjCdi++XuTVUWvyU1wAxQF/KP 6kiBT2dGNzhBkl2mSY/WImkLEb19iAFbfRZkce044SZNqW8a5req8nD+hvo64LYe5cSA clPNaF7nVBl8m25TRDOMxgfBmHuI4yd5SsnUgZbNymgg7K1Naznj5CTWEaFDaiIpWHTV MAyi6kL8v91bo9fvo/NRLu5T6FlAlmfkqmJl09HywMHzhKpBrxJhlZmJs8S7yOuuU9cq dVAQ== X-Gm-Message-State: ALQs6tCHwVwOVe1hHzWqgTFYqzNSLoUWoZASYz1Z3ocqVVWrrEZJTiiq B2NZ05DS8u/EiGN7Od1MaNk= X-Google-Smtp-Source: AB8JxZpgoBbOvAOxFUe7mLjH8EMy5asI5lGNjI4xvEPLFl/sLq65UKjL6Hjq6ZNGiAZCc8K69Ig5Bg== X-Received: by 2002:a63:9711:: with SMTP id n17-v6mr7554841pge.171.1525013837720; Sun, 29 Apr 2018 07:57:17 -0700 (PDT) Received: from ap-To-be-filled-by-O-E-M.8.8.8.8 ([125.130.197.10]) by smtp.gmail.com with ESMTPSA id v23sm9984585pfe.166.2018.04.29.07.57.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 29 Apr 2018 07:57:17 -0700 (PDT) From: Taehee Yoo To: pablo@netfilter.org, netfilter-devel@vger.kernel.org Cc: ap420073@gmail.com Subject: [PATCH 3/3 nf-next] netfilter: nf_tables: fix use-after-free in nf_tables_rule_destroy Date: Sun, 29 Apr 2018 23:57:11 +0900 Message-Id: <20180429145711.13091-1-ap420073@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The nft_expr_ops might be freed in the nf_tables_expr_destroy but after this, a member of nft_expr_ops is used. Steps to reproduce: $iptables-compat -I OUTPUT -m cpu --cpu 0 $iptables-compat -F Signed-off-by: Taehee Yoo --- net/netfilter/nf_tables_api.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 981f35e..2ab23e3 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1873,7 +1873,7 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx, if (ops->init) { err = ops->init(ctx, expr, (const struct nlattr **)info->tb); if (err < 0) - goto err1; + return err; } if (ops->validate) { @@ -1881,16 +1881,14 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx, err = ops->validate(ctx, expr, &data); if (err < 0) - goto err2; + goto err; } return 0; -err2: +err: if (ops->destroy) ops->destroy(ctx, expr); -err1: - expr->ops = NULL; return err; } @@ -2233,16 +2231,13 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, static void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule) { - struct nft_expr *expr; + struct nft_expr *expr, *next; - /* - * Careful: some expressions might not be initialized in case this - * is called on error from nf_tables_newrule(). - */ expr = nft_expr_first(rule); - while (expr != nft_expr_last(rule) && expr->ops) { + while (expr != nft_expr_last(rule)) { + next = nft_expr_next(expr); nf_tables_expr_destroy(ctx, expr); - expr = nft_expr_next(expr); + expr = next; } kfree(rule); }