Skip to content

Commit 31cc578

Browse files
Saeed Mirzamohammadiummakynes
authored andcommitted
netfilter: nftables_offload: KASAN slab-out-of-bounds Read in nft_flow_rule_create
This patch fixes the issue due to: BUG: KASAN: slab-out-of-bounds in nft_flow_rule_create+0x622/0x6a2 net/netfilter/nf_tables_offload.c:40 Read of size 8 at addr ffff888103910b58 by task syz-executor227/16244 The error happens when expr->ops is accessed early on before performing the boundary check and after nft_expr_next() moves the expr to go out-of-bounds. This patch checks the boundary condition before expr->ops that fixes the slab-out-of-bounds Read issue. Add nft_expr_more() and use it to fix this problem. Signed-off-by: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 64747d5 commit 31cc578

3 files changed

Lines changed: 11 additions & 5 deletions

File tree

include/net/netfilter/nf_tables.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,12 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
891891
return (struct nft_expr *)&rule->data[rule->dlen];
892892
}
893893

894+
static inline bool nft_expr_more(const struct nft_rule *rule,
895+
const struct nft_expr *expr)
896+
{
897+
return expr != nft_expr_last(rule) && expr->ops;
898+
}
899+
894900
static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
895901
{
896902
return (void *)&rule->data[rule->dlen];

net/netfilter/nf_tables_api.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ static void nft_rule_expr_activate(const struct nft_ctx *ctx,
302302
struct nft_expr *expr;
303303

304304
expr = nft_expr_first(rule);
305-
while (expr != nft_expr_last(rule) && expr->ops) {
305+
while (nft_expr_more(rule, expr)) {
306306
if (expr->ops->activate)
307307
expr->ops->activate(ctx, expr);
308308

@@ -317,7 +317,7 @@ static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
317317
struct nft_expr *expr;
318318

319319
expr = nft_expr_first(rule);
320-
while (expr != nft_expr_last(rule) && expr->ops) {
320+
while (nft_expr_more(rule, expr)) {
321321
if (expr->ops->deactivate)
322322
expr->ops->deactivate(ctx, expr, phase);
323323

@@ -3080,7 +3080,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
30803080
* is called on error from nf_tables_newrule().
30813081
*/
30823082
expr = nft_expr_first(rule);
3083-
while (expr != nft_expr_last(rule) && expr->ops) {
3083+
while (nft_expr_more(rule, expr)) {
30843084
next = nft_expr_next(expr);
30853085
nf_tables_expr_destroy(ctx, expr);
30863086
expr = next;

net/netfilter/nf_tables_offload.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
3737
struct nft_expr *expr;
3838

3939
expr = nft_expr_first(rule);
40-
while (expr->ops && expr != nft_expr_last(rule)) {
40+
while (nft_expr_more(rule, expr)) {
4141
if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
4242
num_actions++;
4343

@@ -61,7 +61,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
6161
ctx->net = net;
6262
ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
6363

64-
while (expr->ops && expr != nft_expr_last(rule)) {
64+
while (nft_expr_more(rule, expr)) {
6565
if (!expr->ops->offload) {
6666
err = -EOPNOTSUPP;
6767
goto err_out;

0 commit comments

Comments
 (0)