From 2793f7ac5f96b474decfff68cfde86bb5c2ed0a4 Mon Sep 17 00:00:00 2001 From: Justine Olshan Date: Fri, 27 Jul 2018 12:26:42 -0700 Subject: [PATCH] Added the O_LARGEFILE flag. This flag will always be true for gVisor files. PiperOrigin-RevId: 206355963 Change-Id: I2f03d2412e2609042df43b06d1318cba674574d0 --- pkg/abi/linux/fcntl.go | 5 +++ pkg/abi/linux/file.go | 16 ++++++-- pkg/sentry/fs/flags.go | 6 +++ pkg/sentry/syscalls/linux/flags.go | 59 ++++++++++++++------------- pkg/sentry/syscalls/linux/sys_file.go | 2 + 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index f5dbe5199..2a5ad6ed7 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -27,3 +27,8 @@ const ( F_SETLKW = 7 F_SETOWN = 8 ) + +// Flags for fcntl. +const ( + FD_CLOEXEC = 00000001 +) diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 44672647b..f2b7e26ca 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -23,9 +23,19 @@ import ( // Constants for open(2). const ( - O_NONBLOCK = 00004000 - O_CLOEXEC = 02000000 - O_PATH = 010000000 + O_ACCMODE = 00000003 + O_RDONLY = 00000000 + O_WRONLY = 00000001 + O_RDWR = 00000002 + O_APPEND = 00002000 + O_NONBLOCK = 00004000 + O_ASYNC = 00020000 + O_DIRECT = 00040000 + O_LARGEFILE = 00100000 + O_DIRECTORY = 00200000 + O_CLOEXEC = 02000000 + O_SYNC = 04010000 + O_PATH = 010000000 ) // Constants for fstatat(2). diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index 7a8eefd02..810452584 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -45,6 +45,12 @@ type FileFlags struct { // Async indicates that this file sends signals on IO events. Async bool + + // LargeFile indicates that this file should be opened even if it has + // size greater than linux's off_t. When running in 64-bit mode, + // Linux sets this flag for all files. Since gVisor is only compatible + // with 64-bit Linux, it also sets this flag for all files. + LargeFile bool } // SettableFileFlags is a subset of FileFlags above that can be changed diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index 3d39a20f4..b2e173f3e 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -15,8 +15,7 @@ package linux import ( - "syscall" - + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" ) @@ -24,13 +23,13 @@ import ( // flagsToPermissions returns a Permissions object from Linux flags. // This includes truncate permission if O_TRUNC is set in the mask. func flagsToPermissions(mask uint) (p fs.PermMask) { - switch mask & syscall.O_ACCMODE { - case syscall.O_WRONLY: + switch mask & linux.O_ACCMODE { + case linux.O_WRONLY: p.Write = true - case syscall.O_RDWR: + case linux.O_RDWR: p.Write = true p.Read = true - case syscall.O_RDONLY: + case linux.O_RDONLY: p.Read = true } return @@ -39,7 +38,7 @@ func flagsToPermissions(mask uint) (p fs.PermMask) { // fdFlagsToLinux converts a kernel.FDFlags object to a Linux representation. func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) { if flags.CloseOnExec { - mask |= syscall.FD_CLOEXEC + mask |= linux.FD_CLOEXEC } return } @@ -47,30 +46,33 @@ func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) { // flagsToLinux converts a FileFlags object to a Linux representation. func flagsToLinux(flags fs.FileFlags) (mask uint) { if flags.Direct { - mask |= syscall.O_DIRECT + mask |= linux.O_DIRECT } if flags.NonBlocking { - mask |= syscall.O_NONBLOCK + mask |= linux.O_NONBLOCK } if flags.Sync { - mask |= syscall.O_SYNC + mask |= linux.O_SYNC } if flags.Append { - mask |= syscall.O_APPEND + mask |= linux.O_APPEND } if flags.Directory { - mask |= syscall.O_DIRECTORY + mask |= linux.O_DIRECTORY } if flags.Async { - mask |= syscall.O_ASYNC + mask |= linux.O_ASYNC + } + if flags.LargeFile { + mask |= linux.O_LARGEFILE } switch { case flags.Read && flags.Write: - mask |= syscall.O_RDWR + mask |= linux.O_RDWR case flags.Write: - mask |= syscall.O_WRONLY + mask |= linux.O_WRONLY case flags.Read: - mask |= syscall.O_RDONLY + mask |= linux.O_RDONLY } return } @@ -78,23 +80,24 @@ func flagsToLinux(flags fs.FileFlags) (mask uint) { // linuxToFlags converts linux file flags to a FileFlags object. func linuxToFlags(mask uint) (flags fs.FileFlags) { return fs.FileFlags{ - Direct: mask&syscall.O_DIRECT != 0, - Sync: mask&syscall.O_SYNC != 0, - NonBlocking: mask&syscall.O_NONBLOCK != 0, - Read: (mask & syscall.O_ACCMODE) != syscall.O_WRONLY, - Write: (mask & syscall.O_ACCMODE) != syscall.O_RDONLY, - Append: mask&syscall.O_APPEND != 0, - Directory: mask&syscall.O_DIRECTORY != 0, - Async: mask&syscall.O_ASYNC != 0, + Direct: mask&linux.O_DIRECT != 0, + Sync: mask&linux.O_SYNC != 0, + NonBlocking: mask&linux.O_NONBLOCK != 0, + Read: (mask & linux.O_ACCMODE) != linux.O_WRONLY, + Write: (mask & linux.O_ACCMODE) != linux.O_RDONLY, + Append: mask&linux.O_APPEND != 0, + Directory: mask&linux.O_DIRECTORY != 0, + Async: mask&linux.O_ASYNC != 0, + LargeFile: mask&linux.O_LARGEFILE != 0, } } // linuxToSettableFlags converts linux file flags to a SettableFileFlags object. func linuxToSettableFlags(mask uint) fs.SettableFileFlags { return fs.SettableFileFlags{ - Direct: mask&syscall.O_DIRECT != 0, - NonBlocking: mask&syscall.O_NONBLOCK != 0, - Append: mask&syscall.O_APPEND != 0, - Async: mask&syscall.O_ASYNC != 0, + Direct: mask&linux.O_DIRECT != 0, + NonBlocking: mask&linux.O_NONBLOCK != 0, + Append: mask&linux.O_APPEND != 0, + Async: mask&linux.O_ASYNC != 0, } } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 66e6fd9d4..2f28fbea6 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -148,6 +148,8 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u } fileFlags := linuxToFlags(flags) + // Linux always adds the O_LARGEFILE flag when running in 64-bit mode. + fileFlags.LargeFile = true if fs.IsDir(d.Inode.StableAttr) { // Don't allow directories to be opened writable. if fileFlags.Write {