Skip to content

Commit 928f353

Browse files
TaeheeYooPaolo Abeni
authored andcommitted
amt: use READ_ONCE() in amt module
There are some data races in the amt module. amt->ready4, amt->ready6, and amt->status can be accessed concurrently without locks. So, it uses READ_ONCE() and WRITE_ONCE(). Fixes: cbc21dc ("amt: add data plane of amt interface") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 9c343ea commit 928f353

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

drivers/net/amt.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
584584
return;
585585
netdev_dbg(amt->dev, "Update GW status %s -> %s",
586586
status_str[amt->status], status_str[status]);
587-
amt->status = status;
587+
WRITE_ONCE(amt->status, status);
588588
}
589589

590590
static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
@@ -958,8 +958,8 @@ static void amt_event_send_request(struct amt_dev *amt)
958958
if (amt->req_cnt > AMT_MAX_REQ_COUNT) {
959959
netdev_dbg(amt->dev, "Gateway is not ready");
960960
amt->qi = AMT_INIT_REQ_TIMEOUT;
961-
amt->ready4 = false;
962-
amt->ready6 = false;
961+
WRITE_ONCE(amt->ready4, false);
962+
WRITE_ONCE(amt->ready6, false);
963963
amt->remote_ip = 0;
964964
amt_update_gw_status(amt, AMT_STATUS_INIT, false);
965965
amt->req_cnt = 0;
@@ -1239,7 +1239,8 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
12391239
/* Gateway only passes IGMP/MLD packets */
12401240
if (!report)
12411241
goto free;
1242-
if ((!v6 && !amt->ready4) || (v6 && !amt->ready6))
1242+
if ((!v6 && !READ_ONCE(amt->ready4)) ||
1243+
(v6 && !READ_ONCE(amt->ready6)))
12431244
goto free;
12441245
if (amt_send_membership_update(amt, skb, v6))
12451246
goto free;
@@ -2368,7 +2369,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
23682369
ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
23692370
skb_reset_transport_header(skb);
23702371
skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
2371-
amt->ready4 = true;
2372+
WRITE_ONCE(amt->ready4, true);
23722373
amt->mac = amtmq->response_mac;
23732374
amt->req_cnt = 0;
23742375
amt->qi = ihv3->qqic;
@@ -2391,7 +2392,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
23912392
mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
23922393
skb_reset_transport_header(skb);
23932394
skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
2394-
amt->ready6 = true;
2395+
WRITE_ONCE(amt->ready6, true);
23952396
amt->mac = amtmq->response_mac;
23962397
amt->req_cnt = 0;
23972398
amt->qi = mld2q->mld2q_qqic;
@@ -2898,7 +2899,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
28982899
break;
28992900
case AMT_MSG_REQUEST:
29002901
case AMT_MSG_MEMBERSHIP_UPDATE:
2901-
if (amt->status >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
2902+
if (READ_ONCE(amt->status) >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
29022903
mod_delayed_work(amt_wq, &amt->req_wq, 0);
29032904
break;
29042905
default:

0 commit comments

Comments
 (0)