Thread (3 messages) 3 messages, 3 authors, 6h ago

Re: [PATCH net-next] tun: no longer rely on RTNL in tun_fill_info()

From: Kuniyuki Iwashima <kuniyu@google.com>
Date: 2026-07-02 03:09:34

On Wed, Jul 1, 2026 at 5:51 AM Eric Dumazet [off-list ref] wrote:
Update tun_fill_info() to read device configuration fields (flags, owner,
group, numqueues, numdisabled) locklessly using READ_ONCE().

Annotate all writes to these fields in the control paths with WRITE_ONCE()
to prevent data races, as these fields can be modified concurrently via
ioctls (TUNSETPERSIST, TUNSETOWNER, TUNSETGROUP, TUNSETIFF) or queue
attaching/detaching.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>

I left comments but maybe it's just my preference, not sure
if it's worth a respin :)

quoted hunk ↗ jump to hunk
@@ -943,8 +943,8 @@ static int tun_net_init(struct net_device *dev)
                               NETIF_F_HW_VLAN_STAG_TX);
        dev->lltx = true;

-       tun->flags = (tun->flags & ~TUN_FEATURES) |
-                     (ifr->ifr_flags & TUN_FEATURES);
+       WRITE_ONCE(tun->flags, (tun->flags & ~TUN_FEATURES) |
+                              (ifr->ifr_flags & TUN_FEATURES));
WRITE_ONCE() is not needed here as the dev is not yet published.

[...]
quoted hunk ↗ jump to hunk
@@ -2814,8 +2818,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                        return 0;
                }

-               tun->flags = (tun->flags & ~TUN_FEATURES) |
-                             (ifr->ifr_flags & TUN_FEATURES);
+               WRITE_ONCE(tun->flags, (READ_ONCE(tun->flags) & ~TUN_FEATURES) |
+                                      (ifr->ifr_flags & TUN_FEATURES));
READ_ONCE() is not a must here and __tun_chr_ioctl() as all writers
are under RTNL.
quoted hunk ↗ jump to hunk
@@ -3213,13 +3217,13 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
                /* Disable/Enable persist mode. Keep an extra reference to the
                 * module to prevent the module being unprobed.
                 */
-               if (arg && !(tun->flags & IFF_PERSIST)) {
-                       tun->flags |= IFF_PERSIST;
+               if (arg && !(READ_ONCE(tun->flags) & IFF_PERSIST)) {
+                       WRITE_ONCE(tun->flags, READ_ONCE(tun->flags) | IFF_PERSIST);
                        __module_get(THIS_MODULE);
                        do_notify = true;
                }
-               if (!arg && (tun->flags & IFF_PERSIST)) {
-                       tun->flags &= ~IFF_PERSIST;
+               if (!arg && (READ_ONCE(tun->flags) & IFF_PERSIST)) {
+                       WRITE_ONCE(tun->flags, READ_ONCE(tun->flags) & ~IFF_PERSIST);
                        module_put(THIS_MODULE);
                        do_notify = true;
                }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help