summaryrefslogtreecommitdiffhomepage
path: root/runsc/fsgofer/fsgofer_unsafe.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-10-31 11:27:10 -0700
committerShentubot <shentubot@google.com>2018-10-31 11:28:27 -0700
commitccc3d7ca11a2a623587c651a6690aaa46d2c2665 (patch)
treebaa04e2e5ebe4a1ee638dbfbbd86dbcbc613696c /runsc/fsgofer/fsgofer_unsafe.go
parente9dbd5ab67bc31e59910930e6c1b551c0fd05ee6 (diff)
Make lazy open the mode of operation for fsgofer
With recent changes to 9P server, path walks are now safe inside open, create, rename and setattr calls. To simplify the code, remove the lazyopen=false mode that was used for bind mounts, and converge all mounts to using lazy open. PiperOrigin-RevId: 219508628 Change-Id: I073e7e1e2e9a9972d150eaf4cb29e553997a9b76
Diffstat (limited to 'runsc/fsgofer/fsgofer_unsafe.go')
-rw-r--r--runsc/fsgofer/fsgofer_unsafe.go71
1 files changed, 60 insertions, 11 deletions
diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go
index 99bc25ec1..94413db86 100644
--- a/runsc/fsgofer/fsgofer_unsafe.go
+++ b/runsc/fsgofer/fsgofer_unsafe.go
@@ -19,20 +19,29 @@ import (
"unsafe"
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
+ "gvisor.googlesource.com/gvisor/pkg/syserr"
)
func statAt(dirFd int, name string) (syscall.Stat_t, error) {
nameBytes, err := syscall.BytePtrFromString(name)
if err != nil {
- return syscall.Stat_t{}, extractErrno(err)
+ return syscall.Stat_t{}, err
}
- namePtr := uintptr(unsafe.Pointer(nameBytes))
+ namePtr := unsafe.Pointer(nameBytes)
var stat syscall.Stat_t
- statPtr := uintptr(unsafe.Pointer(&stat))
+ statPtr := unsafe.Pointer(&stat)
- if _, _, err := syscall.Syscall6(syscall.SYS_NEWFSTATAT, uintptr(dirFd), namePtr, statPtr, linux.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 {
- return syscall.Stat_t{}, err
+ if _, _, errno := syscall.Syscall6(
+ syscall.SYS_NEWFSTATAT,
+ uintptr(dirFd),
+ uintptr(namePtr),
+ uintptr(statPtr),
+ linux.AT_SYMLINK_NOFOLLOW,
+ 0,
+ 0); errno != 0 {
+
+ return syscall.Stat_t{}, syserr.FromHost(errno).ToError()
}
return stat, nil
}
@@ -40,19 +49,59 @@ func statAt(dirFd int, name string) (syscall.Stat_t, error) {
func utimensat(dirFd int, name string, times [2]syscall.Timespec, flags int) error {
// utimensat(2) doesn't accept empty name, instead name must be nil to make it
// operate directly on 'dirFd' unlike other *at syscalls.
- var namePtr uintptr
+ var namePtr unsafe.Pointer
if name != "" {
nameBytes, err := syscall.BytePtrFromString(name)
if err != nil {
- return extractErrno(err)
+ return err
+ }
+ namePtr = unsafe.Pointer(nameBytes)
+ }
+
+ timesPtr := unsafe.Pointer(&times[0])
+
+ if _, _, errno := syscall.Syscall6(
+ syscall.SYS_UTIMENSAT,
+ uintptr(dirFd),
+ uintptr(namePtr),
+ uintptr(timesPtr),
+ uintptr(flags),
+ 0,
+ 0); errno != 0 {
+
+ return syserr.FromHost(errno).ToError()
+ }
+ return nil
+}
+
+func renameat(oldDirFD int, oldName string, newDirFD int, newName string) error {
+ var oldNamePtr unsafe.Pointer
+ if oldName != "" {
+ nameBytes, err := syscall.BytePtrFromString(oldName)
+ if err != nil {
+ return err
+ }
+ oldNamePtr = unsafe.Pointer(nameBytes)
+ }
+ var newNamePtr unsafe.Pointer
+ if newName != "" {
+ nameBytes, err := syscall.BytePtrFromString(newName)
+ if err != nil {
+ return err
}
- namePtr = uintptr(unsafe.Pointer(nameBytes))
+ newNamePtr = unsafe.Pointer(nameBytes)
}
- timesPtr := uintptr(unsafe.Pointer(&times[0]))
+ if _, _, errno := syscall.Syscall6(
+ syscall.SYS_RENAMEAT,
+ uintptr(oldDirFD),
+ uintptr(oldNamePtr),
+ uintptr(newDirFD),
+ uintptr(newNamePtr),
+ 0,
+ 0); errno != 0 {
- if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirFd), namePtr, timesPtr, uintptr(flags), 0, 0); err != 0 {
- return err
+ return syserr.FromHost(errno).ToError()
}
return nil
}