Skip to content

Commit fc21f08

Browse files
Edward CreePaolo Abeni
authored andcommitted
sfc: handle error pointers returned by rhashtable_lookup_get_insert_fast()
Several places in TC offload code assumed that the return from rhashtable_lookup_get_insert_fast() was always either NULL or a valid pointer to an existing entry, but in fact that function can return an error pointer. In that case, perform the usual cleanup of the newly created entry, then pass up the error, rather than attempting to take a reference on the old entry. Fixes: d902e1a ("sfc: bare bones TC offload on EF100") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Edward Cree <ecree.xilinx@gmail.com> Link: https://lore.kernel.org/r/20230919183949.59392-1-edward.cree@amd.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 1703b2e commit fc21f08

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

drivers/net/ethernet/sfc/tc.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ static struct efx_tc_mac_pedit_action *efx_tc_flower_get_mac(struct efx_nic *efx
136136
if (old) {
137137
/* don't need our new entry */
138138
kfree(ped);
139+
if (IS_ERR(old)) /* oh dear, it's actually an error */
140+
return ERR_CAST(old);
139141
if (!refcount_inc_not_zero(&old->ref))
140142
return ERR_PTR(-EAGAIN);
141143
/* existing entry found, ref taken */
@@ -602,6 +604,8 @@ static int efx_tc_flower_record_encap_match(struct efx_nic *efx,
602604
kfree(encap);
603605
if (pseudo) /* don't need our new pseudo either */
604606
efx_tc_flower_release_encap_match(efx, pseudo);
607+
if (IS_ERR(old)) /* oh dear, it's actually an error */
608+
return PTR_ERR(old);
605609
/* check old and new em_types are compatible */
606610
switch (old->type) {
607611
case EFX_TC_EM_DIRECT:
@@ -700,6 +704,8 @@ static struct efx_tc_recirc_id *efx_tc_get_recirc_id(struct efx_nic *efx,
700704
if (old) {
701705
/* don't need our new entry */
702706
kfree(rid);
707+
if (IS_ERR(old)) /* oh dear, it's actually an error */
708+
return ERR_CAST(old);
703709
if (!refcount_inc_not_zero(&old->ref))
704710
return ERR_PTR(-EAGAIN);
705711
/* existing entry found */
@@ -1482,7 +1488,10 @@ static int efx_tc_flower_replace_foreign(struct efx_nic *efx,
14821488
old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht,
14831489
&rule->linkage,
14841490
efx_tc_match_action_ht_params);
1485-
if (old) {
1491+
if (IS_ERR(old)) {
1492+
rc = PTR_ERR(old);
1493+
goto release;
1494+
} else if (old) {
14861495
netif_dbg(efx, drv, efx->net_dev,
14871496
"Ignoring already-offloaded rule (cookie %lx)\n",
14881497
tc->cookie);
@@ -1697,7 +1706,10 @@ static int efx_tc_flower_replace_lhs(struct efx_nic *efx,
16971706
old = rhashtable_lookup_get_insert_fast(&efx->tc->lhs_rule_ht,
16981707
&rule->linkage,
16991708
efx_tc_lhs_rule_ht_params);
1700-
if (old) {
1709+
if (IS_ERR(old)) {
1710+
rc = PTR_ERR(old);
1711+
goto release;
1712+
} else if (old) {
17011713
netif_dbg(efx, drv, efx->net_dev,
17021714
"Already offloaded rule (cookie %lx)\n", tc->cookie);
17031715
rc = -EEXIST;
@@ -1858,7 +1870,10 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
18581870
old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht,
18591871
&rule->linkage,
18601872
efx_tc_match_action_ht_params);
1861-
if (old) {
1873+
if (IS_ERR(old)) {
1874+
rc = PTR_ERR(old);
1875+
goto release;
1876+
} else if (old) {
18621877
netif_dbg(efx, drv, efx->net_dev,
18631878
"Already offloaded rule (cookie %lx)\n", tc->cookie);
18641879
NL_SET_ERR_MSG_MOD(extack, "Rule already offloaded");

drivers/net/ethernet/sfc/tc_conntrack.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,10 @@ static int efx_tc_ct_replace(struct efx_tc_ct_zone *ct_zone,
298298
old = rhashtable_lookup_get_insert_fast(&efx->tc->ct_ht,
299299
&conn->linkage,
300300
efx_tc_ct_ht_params);
301-
if (old) {
301+
if (IS_ERR(old)) {
302+
rc = PTR_ERR(old);
303+
goto release;
304+
} else if (old) {
302305
netif_dbg(efx, drv, efx->net_dev,
303306
"Already offloaded conntrack (cookie %lx)\n", tc->cookie);
304307
rc = -EEXIST;
@@ -482,6 +485,8 @@ struct efx_tc_ct_zone *efx_tc_ct_register_zone(struct efx_nic *efx, u16 zone,
482485
if (old) {
483486
/* don't need our new entry */
484487
kfree(ct_zone);
488+
if (IS_ERR(old)) /* oh dear, it's actually an error */
489+
return ERR_CAST(old);
485490
if (!refcount_inc_not_zero(&old->ref))
486491
return ERR_PTR(-EAGAIN);
487492
/* existing entry found */

drivers/net/ethernet/sfc/tc_counters.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ struct efx_tc_counter_index *efx_tc_flower_get_counter_index(
236236
if (old) {
237237
/* don't need our new entry */
238238
kfree(ctr);
239+
if (IS_ERR(old)) /* oh dear, it's actually an error */
240+
return ERR_CAST(old);
239241
if (!refcount_inc_not_zero(&old->ref))
240242
return ERR_PTR(-EAGAIN);
241243
/* existing entry found */

drivers/net/ethernet/sfc/tc_encap_actions.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ static int efx_bind_neigh(struct efx_nic *efx,
132132
/* don't need our new entry */
133133
put_net_track(neigh->net, &neigh->ns_tracker);
134134
kfree(neigh);
135+
if (IS_ERR(old)) /* oh dear, it's actually an error */
136+
return PTR_ERR(old);
135137
if (!refcount_inc_not_zero(&old->ref))
136138
return -EAGAIN;
137139
/* existing entry found, ref taken */
@@ -640,6 +642,8 @@ struct efx_tc_encap_action *efx_tc_flower_create_encap_md(
640642
if (old) {
641643
/* don't need our new entry */
642644
kfree(encap);
645+
if (IS_ERR(old)) /* oh dear, it's actually an error */
646+
return ERR_CAST(old);
643647
if (!refcount_inc_not_zero(&old->ref))
644648
return ERR_PTR(-EAGAIN);
645649
/* existing entry found, ref taken */

0 commit comments

Comments
 (0)