Skip to content

Commit 8e13cd7

Browse files
w1ldptrSaeed Mahameed
authored andcommitted
net/mlx5e: fix double free of encap_header
Cited commit introduced potential double free since encap_header can be destroyed twice in some cases - once by error cleanup sequence in mlx5e_tc_tun_{create|update}_header_ipv{4|6}(), once by generic mlx5e_encap_put() that user calls as a result of getting an error from tunnel create|update. At the same time the point where e->encap_header is assigned can't be delayed because the function can still return non-error code 0 as a result of checking for NUD_VALID flag, which will cause neighbor update to dereference NULL encap_header. Fix the issue by: - Nulling local encap_header variables in mlx5e_tc_tun_{create|update}_header_ipv{4|6}() to make kfree(encap_header) call in error cleanup sequence noop after that point. - Assigning reformat_params.data from e->encap_header instead of local variable encap_header that was set to NULL pointer by previous step. Also assign reformat_params.size from e->encap_size for uniformity and in order to make the code less error-prone in the future. Fixes: d589e78 ("net/mlx5e: Allow concurrent creation of encap entries") Reported-by: Dust Li <[email protected]> Reported-by: Cruz Zhao <[email protected]> Reported-by: Tianchen Ding <[email protected]> Signed-off-by: Vlad Buslov <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 5d08968 commit 8e13cd7

File tree

1 file changed

+12
-8
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core/en

1 file changed

+12
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
302302

303303
e->encap_size = ipv4_encap_size;
304304
e->encap_header = encap_header;
305+
encap_header = NULL;
305306

306307
if (!(nud_state & NUD_VALID)) {
307308
neigh_event_send(attr.n, NULL);
@@ -313,8 +314,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
313314

314315
memset(&reformat_params, 0, sizeof(reformat_params));
315316
reformat_params.type = e->reformat_type;
316-
reformat_params.size = ipv4_encap_size;
317-
reformat_params.data = encap_header;
317+
reformat_params.size = e->encap_size;
318+
reformat_params.data = e->encap_header;
318319
e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
319320
MLX5_FLOW_NAMESPACE_FDB);
320321
if (IS_ERR(e->pkt_reformat)) {
@@ -407,6 +408,7 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv,
407408
e->encap_size = ipv4_encap_size;
408409
kfree(e->encap_header);
409410
e->encap_header = encap_header;
411+
encap_header = NULL;
410412

411413
if (!(nud_state & NUD_VALID)) {
412414
neigh_event_send(attr.n, NULL);
@@ -418,8 +420,8 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv,
418420

419421
memset(&reformat_params, 0, sizeof(reformat_params));
420422
reformat_params.type = e->reformat_type;
421-
reformat_params.size = ipv4_encap_size;
422-
reformat_params.data = encap_header;
423+
reformat_params.size = e->encap_size;
424+
reformat_params.data = e->encap_header;
423425
e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
424426
MLX5_FLOW_NAMESPACE_FDB);
425427
if (IS_ERR(e->pkt_reformat)) {
@@ -570,6 +572,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
570572

571573
e->encap_size = ipv6_encap_size;
572574
e->encap_header = encap_header;
575+
encap_header = NULL;
573576

574577
if (!(nud_state & NUD_VALID)) {
575578
neigh_event_send(attr.n, NULL);
@@ -581,8 +584,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
581584

582585
memset(&reformat_params, 0, sizeof(reformat_params));
583586
reformat_params.type = e->reformat_type;
584-
reformat_params.size = ipv6_encap_size;
585-
reformat_params.data = encap_header;
587+
reformat_params.size = e->encap_size;
588+
reformat_params.data = e->encap_header;
586589
e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
587590
MLX5_FLOW_NAMESPACE_FDB);
588591
if (IS_ERR(e->pkt_reformat)) {
@@ -674,6 +677,7 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv,
674677
e->encap_size = ipv6_encap_size;
675678
kfree(e->encap_header);
676679
e->encap_header = encap_header;
680+
encap_header = NULL;
677681

678682
if (!(nud_state & NUD_VALID)) {
679683
neigh_event_send(attr.n, NULL);
@@ -685,8 +689,8 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv,
685689

686690
memset(&reformat_params, 0, sizeof(reformat_params));
687691
reformat_params.type = e->reformat_type;
688-
reformat_params.size = ipv6_encap_size;
689-
reformat_params.data = encap_header;
692+
reformat_params.size = e->encap_size;
693+
reformat_params.data = e->encap_header;
690694
e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
691695
MLX5_FLOW_NAMESPACE_FDB);
692696
if (IS_ERR(e->pkt_reformat)) {

0 commit comments

Comments
 (0)