mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Don't use other process's scratch buffer.
If we use the remote process's scratch buffer in process_vm_readv|writev calls, we will get data races. Use the local task's scratch buffer always. PiperOrigin-RevId: 491468904
This commit is contained in:
committed by
gVisor bot
parent
85a2ede174
commit
ae731e0394
@@ -26,10 +26,9 @@ import (
|
||||
type vmReadWriteOp int
|
||||
|
||||
const (
|
||||
localReader vmReadWriteOp = iota
|
||||
localWriter
|
||||
remoteReader
|
||||
remoteWriter
|
||||
localReadLocalWrite vmReadWriteOp = iota
|
||||
remoteReadLocalWrite
|
||||
localReadRemoteWrite
|
||||
)
|
||||
|
||||
// ProcessVMReadv implements process_vm_readv(2).
|
||||
@@ -76,17 +75,16 @@ func processVMRW(t *kernel.Task, args arch.SyscallArguments, isWrite bool) (uint
|
||||
isRemote := localProcess == remoteProcess
|
||||
|
||||
// For the write case, we read from the local process and write to the remote process.
|
||||
op := localReadLocalWrite
|
||||
if isWrite {
|
||||
op := localReader
|
||||
if isRemote {
|
||||
op = remoteReader
|
||||
op = remoteReadLocalWrite
|
||||
}
|
||||
return doProcessVMReadWrite(localProcess, remoteProcess, lvec, rvec, liovcnt, riovcnt, op)
|
||||
}
|
||||
// For the read case, we read from the remote process and write to the local process.
|
||||
op := localWriter
|
||||
if isRemote {
|
||||
op = remoteWriter
|
||||
op = localReadRemoteWrite
|
||||
}
|
||||
return doProcessVMReadWrite(remoteProcess, localProcess, rvec, lvec, riovcnt, liovcnt, op)
|
||||
}
|
||||
@@ -113,7 +111,16 @@ func doProcessVMReadWrite(rProcess, wProcess *kernel.Task, rAddr, wAddr hostarch
|
||||
}
|
||||
}
|
||||
|
||||
buf := rCtx.CopyScratchBuffer(bufSize)
|
||||
var buf []byte
|
||||
// We need to copy the called task's scratch buffer so we don't get a data race. If we are
|
||||
// reading a remote process's memory, then we are on the writer's task goroutine, so use
|
||||
// the write context's scratch buffer.
|
||||
if op == remoteReadLocalWrite {
|
||||
buf = wCtx.CopyScratchBuffer(bufSize)
|
||||
} else {
|
||||
buf = rCtx.CopyScratchBuffer(bufSize)
|
||||
}
|
||||
|
||||
for _, rIovec := range rIovecs {
|
||||
if len(wIovecs) <= 0 {
|
||||
break
|
||||
@@ -163,12 +170,12 @@ func doProcessVMReadWrite(rProcess, wProcess *kernel.Task, rAddr, wAddr hostarch
|
||||
var err error
|
||||
|
||||
switch op {
|
||||
case remoteReader:
|
||||
case remoteReadLocalWrite:
|
||||
err = rCtx.WithTaskMutexLocked(doProcessVMReadWriteMaybeLocked)
|
||||
case remoteWriter:
|
||||
case localReadRemoteWrite:
|
||||
err = wCtx.WithTaskMutexLocked(doProcessVMReadWriteMaybeLocked)
|
||||
|
||||
case localReader, localWriter:
|
||||
case localReadLocalWrite:
|
||||
// in the case of local reads/writes, we don't have to lock the task mutex, because we are
|
||||
// running on the top of the task's goroutine already.
|
||||
err = doProcessVMReadWriteMaybeLocked()
|
||||
|
||||
Reference in New Issue
Block a user