device: do not allow get to run while set runs

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2021-01-28 15:26:22 +01:00
parent 34c047c762
commit 6a128dde71
2 changed files with 7 additions and 3 deletions

View file

@ -23,7 +23,6 @@ type Device struct {
isUp AtomicBool // device is (going) up isUp AtomicBool // device is (going) up
isClosed AtomicBool // device is closed? (acting as guard) isClosed AtomicBool // device is closed? (acting as guard)
log *Logger log *Logger
ipcSetMu sync.Mutex // serializes UAPI set operations
// synchronized resources (locks acquired in order) // synchronized resources (locks acquired in order)
@ -89,6 +88,8 @@ type Device struct {
device tun.Device device tun.Device
mtu int32 mtu int32
} }
ipcMutex sync.RWMutex
} }
// An encryptionQueue is a channel of QueueOutboundElements awaiting encryption. // An encryptionQueue is a channel of QueueOutboundElements awaiting encryption.

View file

@ -50,6 +50,9 @@ var byteBufferPool = &sync.Pool{
// IpcGetOperation implements the WireGuard configuration protocol "get" operation. // IpcGetOperation implements the WireGuard configuration protocol "get" operation.
// See https://www.wireguard.com/xplatform/#configuration-protocol for details. // See https://www.wireguard.com/xplatform/#configuration-protocol for details.
func (device *Device) IpcGetOperation(w io.Writer) error { func (device *Device) IpcGetOperation(w io.Writer) error {
device.ipcMutex.RLock()
defer device.ipcMutex.RUnlock()
buf := byteBufferPool.Get().(*bytes.Buffer) buf := byteBufferPool.Get().(*bytes.Buffer)
buf.Reset() buf.Reset()
defer byteBufferPool.Put(buf) defer byteBufferPool.Put(buf)
@ -137,8 +140,8 @@ func (device *Device) IpcGetOperation(w io.Writer) error {
// IpcSetOperation implements the WireGuard configuration protocol "set" operation. // IpcSetOperation implements the WireGuard configuration protocol "set" operation.
// See https://www.wireguard.com/xplatform/#configuration-protocol for details. // See https://www.wireguard.com/xplatform/#configuration-protocol for details.
func (device *Device) IpcSetOperation(r io.Reader) (err error) { func (device *Device) IpcSetOperation(r io.Reader) (err error) {
device.ipcSetMu.Lock() device.ipcMutex.Lock()
defer device.ipcSetMu.Unlock() defer device.ipcMutex.Unlock()
defer func() { defer func() {
if err != nil { if err != nil {