Skip to content

Commit 20452a2

Browse files
ayushr2gvisor-bot
authored andcommitted
net/tun: Do not DecRef a closed TUN endpoint when un-persisting it.
This requires coordinating tunEndpoint.closed and tunEndpoint.persistent. Earlier these were independent atomic bools. This change moves them under the protection of tunEndpoint.mu. Fixes 81d7f66 ("netstack/tuntap: implement the TUNSETPERSIST ioctl") Reported-by: [email protected] PiperOrigin-RevId: 807748254
1 parent 0bb00ae commit 20452a2

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

pkg/tcpip/link/tun/device.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package tun
1717
import (
1818
"fmt"
1919

20-
"gvisor.dev/gvisor/pkg/atomicbitops"
2120
"gvisor.dev/gvisor/pkg/buffer"
2221
"gvisor.dev/gvisor/pkg/context"
2322
"gvisor.dev/gvisor/pkg/errors/linuxerr"
@@ -362,22 +361,26 @@ type tunEndpoint struct {
362361
tunEndpointRefs
363362
*channel.Endpoint
364363

365-
stack *stack.Stack
366-
nicID tcpip.NICID
367-
name string
368-
isTap bool
369-
persistent atomicbitops.Bool
370-
closed atomicbitops.Bool
364+
stack *stack.Stack
365+
nicID tcpip.NICID
366+
name string
367+
isTap bool
371368

372369
mu endpointMutex `state:"nosave"`
373370
onCloseAction func() `state:"nosave"`
371+
persistent bool
372+
closed bool
374373
}
375374

376375
func (e *tunEndpoint) setPersistent(v bool) {
377-
old := e.persistent.Swap(v)
378-
if old == v {
376+
e.mu.Lock()
377+
if e.persistent == v || e.closed {
378+
e.mu.Unlock()
379379
return
380380
}
381+
e.persistent = v
382+
e.mu.Unlock()
383+
// Update refs without holding the lock.
381384
if v {
382385
e.IncRef()
383386
} else {
@@ -386,17 +389,19 @@ func (e *tunEndpoint) setPersistent(v bool) {
386389
}
387390

388391
func (e *tunEndpoint) Close() {
389-
if e.closed.Swap(true) {
392+
e.mu.Lock()
393+
if e.closed {
394+
e.mu.Unlock()
390395
return
391396
}
392-
393-
if e.persistent.Load() {
394-
e.DecRef(context.Background())
395-
}
396-
e.mu.Lock()
397+
e.closed = true
398+
decref := e.persistent
397399
action := e.onCloseAction
398400
e.onCloseAction = nil
399401
e.mu.Unlock()
402+
if decref {
403+
e.DecRef(context.Background())
404+
}
400405
if action != nil {
401406
action()
402407
}

0 commit comments

Comments
 (0)