From: Colin King <hidden> Date: 2021-06-24 19:57:30
From: Colin Ian King <redacted>
In the case where chain->flags & NFT_CHAIN_HW_OFFLOAD is false then
nft_flow_rule_create is not called and flow is NULL. The subsequent
error handling execution via label err_destroy_flow_rule will lead
to a null pointer dereference on flow when calling nft_flow_rule_destroy.
Since the error path to err_destroy_flow_rule has to cater for null
and non-null flows, only call nft_flow_rule_destroy if flow is non-null
to fix this issue.
Addresses-Coverity: ("Explicity null dereference")
Fixes: 3c5e44622011 ("netfilter: nf_tables: memleak in hw offload abort path")
Signed-off-by: Colin Ian King <redacted>
---
net/netfilter/nf_tables_api.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Dan Carpenter <hidden> Date: 2021-06-25 09:59:35
Btw, why is there no clean up if nft_table_validate() fails?
net/netfilter/nf_tables_api.c
3432 list_add_tail_rcu(&rule->list, &old_rule->list);
3433 else
3434 list_add_rcu(&rule->list, &chain->rules);
3435 }
3436 }
3437 kvfree(expr_info);
3438 chain->use++;
3439
3440 if (flow)
3441 nft_trans_flow_rule(trans) = flow;
3442
3443 if (nft_net->validate_state == NFT_VALIDATE_DO)
3444 return nft_table_validate(net, table);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The cleanup for this would be quite involved unfortunately... Not
necessarily something to attempt without being able to test the code.
3445
3446 return 0;
3447
3448 err_destroy_flow_rule:
3449 nft_flow_rule_destroy(flow);
3450 err_release_rule:
3451 nf_tables_rule_release(&ctx, rule);
3452 err_release_expr:
3453 for (i = 0; i < n; i++) {
3454 if (expr_info[i].ops) {
3455 module_put(expr_info[i].ops->type->owner);
3456 if (expr_info[i].ops->type->release_ops)
3457 expr_info[i].ops->type->release_ops(expr_info[i].ops);
3458 }
3459 }
3460 kvfree(expr_info);
3461
3462 return err;
3463 }
regards,
dan carpenter
From: Walter Harms <hidden> Date: 2021-06-25 10:14:59
hi Colin,
most free_something_functions accept NULL
these days, perhaps it would be more efficient
to add a check in nft_flow_rule_destroy().
There is a chance that this will catch the same
mistake in future also.
jm2c,
re,
wh
________________________________________
Von: Colin King [off-list ref]
Gesendet: Donnerstag, 24. Juni 2021 21:57:18
An: Pablo Neira Ayuso; Jozsef Kadlecsik; Florian Westphal; David S . Miller; Jakub Kicinski; netfilter-devel@vger.kernel.org; coreteam@netfilter.org; netdev@vger.kernel.org
Cc: kernel-janitors@vger.kernel.org; linux-kernel@vger.kernel.org
Betreff: [PATCH][next] netfilter: nf_tables: Fix dereference of null pointer flow
WARNUNG: Diese E-Mail kam von außerhalb der Organisation. Klicken Sie nicht auf Links oder öffnen Sie keine Anhänge, es sei denn, Sie kennen den/die Absender*in und wissen, dass der Inhalt sicher ist.
From: Colin Ian King <redacted>
In the case where chain->flags & NFT_CHAIN_HW_OFFLOAD is false then
nft_flow_rule_create is not called and flow is NULL. The subsequent
error handling execution via label err_destroy_flow_rule will lead
to a null pointer dereference on flow when calling nft_flow_rule_destroy.
Since the error path to err_destroy_flow_rule has to cater for null
and non-null flows, only call nft_flow_rule_destroy if flow is non-null
to fix this issue.
Addresses-Coverity: ("Explicity null dereference")
Fixes: 3c5e44622011 ("netfilter: nf_tables: memleak in hw offload abort path")
Signed-off-by: Colin Ian King <redacted>
---
net/netfilter/nf_tables_api.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-06-25 10:20:34
Hi,
On Fri, Jun 25, 2021 at 12:59:01PM +0300, Dan Carpenter wrote:
Btw, why is there no clean up if nft_table_validate() fails?
See below.
net/netfilter/nf_tables_api.c
3432 list_add_tail_rcu(&rule->list, &old_rule->list);
3433 else
3434 list_add_rcu(&rule->list, &chain->rules);
3435 }
3436 }
3437 kvfree(expr_info);
3438 chain->use++;
3439
3440 if (flow)
3441 nft_trans_flow_rule(trans) = flow;
3442
3443 if (nft_net->validate_state == NFT_VALIDATE_DO)
3444 return nft_table_validate(net, table);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The cleanup for this would be quite involved unfortunately... Not
necessarily something to attempt without being able to test the code.
At this stage, the transaction has been already registered in the
list, and the nf_tables_abort() path takes care of undoing what has
been updated in the preparation phase.
Having said this, Colin patch is correct, it's fixing up the error
path.
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-06-25 10:21:23
On Fri, Jun 25, 2021 at 10:06:26AM +0000, Walter Harms wrote:
hi Colin,
most free_something_functions accept NULL
these days, perhaps it would be more efficient
to add a check in nft_flow_rule_destroy().
There is a chance that this will catch the same
mistake in future also.
From: Dan Carpenter <hidden> Date: 2021-06-25 10:33:44
On Fri, Jun 25, 2021 at 12:20:21PM +0200, Pablo Neira Ayuso wrote:
Hi,
On Fri, Jun 25, 2021 at 12:59:01PM +0300, Dan Carpenter wrote:
quoted
Btw, why is there no clean up if nft_table_validate() fails?
See below.
quoted
net/netfilter/nf_tables_api.c
3432 list_add_tail_rcu(&rule->list, &old_rule->list);
3433 else
3434 list_add_rcu(&rule->list, &chain->rules);
3435 }
3436 }
3437 kvfree(expr_info);
3438 chain->use++;
3439
3440 if (flow)
3441 nft_trans_flow_rule(trans) = flow;
3442
3443 if (nft_net->validate_state == NFT_VALIDATE_DO)
3444 return nft_table_validate(net, table);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The cleanup for this would be quite involved unfortunately... Not
necessarily something to attempt without being able to test the code.
At this stage, the transaction has been already registered in the
list, and the nf_tables_abort() path takes care of undoing what has
been updated in the preparation phase.
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-02 00:56:54
On Thu, Jun 24, 2021 at 08:57:18PM +0100, Colin King wrote:
From: Colin Ian King <redacted>
In the case where chain->flags & NFT_CHAIN_HW_OFFLOAD is false then
nft_flow_rule_create is not called and flow is NULL. The subsequent
error handling execution via label err_destroy_flow_rule will lead
to a null pointer dereference on flow when calling nft_flow_rule_destroy.
Since the error path to err_destroy_flow_rule has to cater for null
and non-null flows, only call nft_flow_rule_destroy if flow is non-null
to fix this issue.