[PATCH net-next 02/14] inet: frags: annotate data-races around fqdir->timeout and fqdir->max_dist
From: Jiayuan Chen
Date: Sun Nov 08 2026 - 22:00:45 EST
fqdir->timeout and fqdir->max_dist are read without any lock while their
sysctl handlers update them with WRITE_ONCE(). Add READ_ONCE() to the
readers.
Signed-off-by: Jiayuan Chen <jiayuan.chen@xxxxxxxxx>
---
net/ipv4/inet_fragment.c | 2 +-
net/ipv4/ip_fragment.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 0b8d22ffafca6..ba10aec88cc9b 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -415,7 +415,7 @@ static struct inet_frag_queue *inet_frag_create(struct fqdir *fqdir,
inet_frag_putn(q, 2);
return NULL;
}
- mod_timer(&q->timer, jiffies + fqdir->timeout);
+ mod_timer(&q->timer, jiffies + READ_ONCE(fqdir->timeout));
spin_unlock_bh(&q->lock);
return q;
}
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 36105dd192823..e70ef3fe5e331 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -89,7 +89,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
q->key.v4 = *key;
qp->ecn = 0;
- if (q->fqdir->max_dist) {
+ if (READ_ONCE(q->fqdir->max_dist)) {
rcu_read_lock();
p = inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif);
if (p && !refcount_inc_not_zero(&p->refcnt))
@@ -220,7 +220,7 @@ static struct ipq *ip_find(struct net *net, struct iphdr *iph,
static int ip_frag_too_far(struct ipq *qp)
{
struct inet_peer *peer = qp->peer;
- unsigned int max = qp->q.fqdir->max_dist;
+ unsigned int max = READ_ONCE(qp->q.fqdir->max_dist);
unsigned int start, end;
int rc;
@@ -242,7 +242,7 @@ static int ip_frag_too_far(struct ipq *qp)
static int ip_frag_reinit(struct ipq *qp)
{
- if (!mod_timer_pending(&qp->q.timer, jiffies + qp->q.fqdir->timeout))
+ if (!mod_timer_pending(&qp->q.timer, jiffies + READ_ONCE(qp->q.fqdir->timeout)))
return -ETIMEDOUT;
inet_frag_queue_flush(&qp->q, SKB_DROP_REASON_FRAG_TOO_FAR);
--
2.43.0