Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/sa: Fix sa_local_svc_timeout_ms read race

When computing the delta, the sa_local_svc_timeout_ms is read without
ib_nl_request_lock held. Though unlikely in practice, this can cause
a race condition if multiple local service threads are managing the
timeout.

Fixes: 2ca546b92a02 ("IB/sa: Route SA pathrecord query through netlink")
Signed-off-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
Reviewed-by: Mark Zhang <markzhang@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20250916163112.98414-1-edwards@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Vlad Dumitrescu and committed by
Leon Romanovsky
1428cd76 42f993d3

+4 -2
+4 -2
drivers/infiniband/core/sa_query.c
··· 1074 1074 if (timeout > IB_SA_LOCAL_SVC_TIMEOUT_MAX) 1075 1075 timeout = IB_SA_LOCAL_SVC_TIMEOUT_MAX; 1076 1076 1077 + spin_lock_irqsave(&ib_nl_request_lock, flags); 1078 + 1077 1079 delta = timeout - sa_local_svc_timeout_ms; 1078 1080 if (delta < 0) 1079 1081 abs_delta = -delta; ··· 1083 1081 abs_delta = delta; 1084 1082 1085 1083 if (delta != 0) { 1086 - spin_lock_irqsave(&ib_nl_request_lock, flags); 1087 1084 sa_local_svc_timeout_ms = timeout; 1088 1085 list_for_each_entry(query, &ib_nl_request_list, list) { 1089 1086 if (delta < 0 && abs_delta > query->timeout) ··· 1100 1099 if (delay) 1101 1100 mod_delayed_work(ib_nl_wq, &ib_nl_timed_work, 1102 1101 (unsigned long)delay); 1103 - spin_unlock_irqrestore(&ib_nl_request_lock, flags); 1104 1102 } 1103 + 1104 + spin_unlock_irqrestore(&ib_nl_request_lock, flags); 1105 1105 1106 1106 settimeout_out: 1107 1107 return 0;