mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
Seems that GNU tar extraction has been broken in gVisor since 75b03fd (11/15/2025), which started using openat2(2) to address CVE-2025-45582. tar uses openat2(2) for the RESOLVE_BENEATH flag which allows scoping the path resolution underneath the specified dirfd. This commit implements openat2(2) in gVisor, with support for all flags supported by Linux: RESOLVE_BENEATH, RESOLVE_IN_ROOT, RESOLVE_CACHED, RESOLVE_NO_MAGICLINKS, RESOLVE_NO_SYMLINKS, and RESOLVE_NO_XDEV. This commit also introduces VirtualFilesystem.renameSeq, a global sequence counter that along with mountSeq detects mount or rename operations that race with scoped traversals. A final "resolved-path-is-under-dirfd" check is performed after the traversal. This is for two reasons: (1) in case of a bug in any of the above logic, or (2) in case of an (extremely unlikely) attack where mountSeq overflows by exactly 2^32 during a path resolution. Unfortunately, due to the way path traversal in gVisor is tightly coupled to the operation being performed by a VFS method, using scoped traversals in an operation that *mutates* anything will be difficult, since without major refactoring, the check must happen after the side effect has taken place. Currently, Linux only exposes scoped traversals through openat2(2), so destroying the created fd is all we need to do if the final check fails. (As a result of this limitation, most VFS functions have been modified to reject scoped traversals "just-in-case".) The RESOLVE_NO_XDEV implementation has a slight divergence from Linux. It is a bit looser, permitting absolute symlinks in any case where the root dentry's mount matches the mount the traversal is locked to. Linux's behavior here is likely a bug, and since we can safely be *more* permissive, there's not much reason to match it. This commit also adds syscall tests and an strace formatter for openat2(2).
560 lines
14 KiB
Go
560 lines
14 KiB
Go
// Copyright 2018 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package linux
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"structs"
|
|
|
|
"gvisor.dev/gvisor/pkg/abi"
|
|
)
|
|
|
|
// Constants for open(2).
|
|
const (
|
|
O_ACCMODE = 000000003
|
|
O_RDONLY = 000000000
|
|
O_WRONLY = 000000001
|
|
O_RDWR = 000000002
|
|
O_CREAT = 000000100
|
|
O_EXCL = 000000200
|
|
O_NOCTTY = 000000400
|
|
O_TRUNC = 000001000
|
|
O_APPEND = 000002000
|
|
O_NONBLOCK = 000004000
|
|
O_DSYNC = 000010000
|
|
O_ASYNC = 000020000
|
|
O_NOATIME = 001000000
|
|
O_CLOEXEC = 002000000
|
|
O_SYNC = 004000000 // __O_SYNC in Linux
|
|
O_PATH = 010000000
|
|
O_TMPFILE = 020000000 // __O_TMPFILE in Linux
|
|
)
|
|
|
|
// Constants for file mode (struct file::f_mode in Linux).
|
|
const (
|
|
// FMODE_READ indicates the file is open for reading.
|
|
// It is set when MayReadFileWithOpenFlags(flags) is true.
|
|
FMODE_READ = 0x1
|
|
// FMODE_WRITE indicates the file is open for writing.
|
|
// It is set when MayWriteFileWithOpenFlags(flags) is true. When set,
|
|
// the FileDescription holds a write count on vd.mount.
|
|
FMODE_WRITE = 0x2
|
|
// FMODE_CREATED is set when a file is newly created by an open
|
|
// operation (O_CREAT and the file did not already exist).
|
|
FMODE_CREATED = 0x100000
|
|
)
|
|
|
|
// Constants for openat2(2).
|
|
const (
|
|
RESOLVE_NO_XDEV = 0x1
|
|
RESOLVE_NO_MAGICLINKS = 0x2
|
|
RESOLVE_NO_SYMLINKS = 0x4
|
|
RESOLVE_BENEATH = 0x8
|
|
RESOLVE_IN_ROOT = 0x10
|
|
RESOLVE_CACHED = 0x20
|
|
)
|
|
|
|
// OpenHow represents struct open_how, which specifies
|
|
// how openat2(2) should resolve the specified path.
|
|
//
|
|
// +marshal
|
|
type OpenHow struct {
|
|
_ structs.HostLayout
|
|
Flags uint64
|
|
Mode uint64
|
|
Resolve uint64
|
|
}
|
|
|
|
// Sizes for various versions of the kernel OpenHow structure.
|
|
const (
|
|
OPEN_HOW_SIZE_VER0 = 24
|
|
OPEN_HOW_SIZE_LATEST = OPEN_HOW_SIZE_VER0
|
|
)
|
|
|
|
// ValidOpenFlags represent all valid flags for the open(2) family.
|
|
const ValidOpenFlags = O_ACCMODE | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | O_APPEND | O_NONBLOCK | O_DSYNC | O_ASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | O_NOATIME | O_SYNC | O_PATH | O_TMPFILE | O_CLOEXEC
|
|
|
|
// ValidOPathFlags represent all flags that are valid alongside O_PATH for the open(2) family.
|
|
const ValidOPathFlags = O_DIRECTORY | O_NOFOLLOW | O_PATH | O_CLOEXEC
|
|
|
|
// Constants for fstatat(2).
|
|
const (
|
|
AT_SYMLINK_NOFOLLOW = 0x100
|
|
)
|
|
|
|
// Constants for mount(2).
|
|
const (
|
|
MS_RDONLY = 0x1
|
|
MS_NOSUID = 0x2
|
|
MS_NODEV = 0x4
|
|
MS_NOEXEC = 0x8
|
|
MS_SYNCHRONOUS = 0x10
|
|
MS_REMOUNT = 0x20
|
|
MS_MANDLOCK = 0x40
|
|
MS_DIRSYNC = 0x80
|
|
MS_NOATIME = 0x400
|
|
MS_NODIRATIME = 0x800
|
|
MS_BIND = 0x1000
|
|
MS_MOVE = 0x2000
|
|
MS_REC = 0x4000
|
|
|
|
MS_POSIXACL = 0x10000
|
|
MS_UNBINDABLE = 0x20000
|
|
MS_PRIVATE = 0x40000
|
|
MS_SLAVE = 0x80000
|
|
MS_SHARED = 0x100000
|
|
MS_RELATIME = 0x200000
|
|
MS_KERNMOUNT = 0x400000
|
|
MS_I_VERSION = 0x800000
|
|
MS_STRICTATIME = 0x1000000
|
|
|
|
MS_MGC_VAL = 0xC0ED0000
|
|
MS_MGC_MSK = 0xffff0000
|
|
)
|
|
|
|
// Constants for umount2(2).
|
|
const (
|
|
MNT_FORCE = 0x1
|
|
MNT_DETACH = 0x2
|
|
MNT_EXPIRE = 0x4
|
|
UMOUNT_NOFOLLOW = 0x8
|
|
)
|
|
|
|
// Constants for fsopen(2).
|
|
const (
|
|
FSOPEN_CLOEXEC = 0x1
|
|
)
|
|
|
|
// Constants for fsconfig(2).
|
|
const (
|
|
FSCONFIG_SET_FLAG = 0x0
|
|
FSCONFIG_SET_STRING = 0x1
|
|
FSCONFIG_SET_BINARY = 0x2
|
|
FSCONFIG_SET_PATH = 0x3
|
|
FSCONFIG_SET_PATH_EMPTY = 0x4
|
|
FSCONFIG_SET_FD = 0x5
|
|
FSCONFIG_CMD_CREATE = 0x6
|
|
FSCONFIG_CMD_RECONFIGURE = 0x7
|
|
FSCONFIG_CMD_CREATE_EXCL = 0x8
|
|
)
|
|
|
|
// Constants for fsmount(2).
|
|
const (
|
|
FSMOUNT_CLOEXEC = 0x1
|
|
)
|
|
|
|
// Constants for move_mount(2).
|
|
const (
|
|
MOVE_MOUNT_F_SYMLINKS = 0x00000001
|
|
MOVE_MOUNT_F_AUTOMOUNTS = 0x00000002
|
|
MOVE_MOUNT_F_EMPTY_PATH = 0x00000004
|
|
MOVE_MOUNT_T_SYMLINKS = 0x00000010
|
|
MOVE_MOUNT_T_AUTOMOUNTS = 0x00000020
|
|
MOVE_MOUNT_T_EMPTY_PATH = 0x00000040
|
|
MOVE_MOUNT_SET_GROUP = 0x00000100
|
|
MOVE_MOUNT_BENEATH = 0x00000200
|
|
)
|
|
|
|
// Constants for mount_setattr(2).
|
|
const (
|
|
MOUNT_ATTR_RDONLY = 0x00000001
|
|
MOUNT_ATTR_NOSUID = 0x00000002
|
|
MOUNT_ATTR_NODEV = 0x00000004
|
|
MOUNT_ATTR_NOEXEC = 0x00000008
|
|
MOUNT_ATTR__ATIME = 0x00000070
|
|
MOUNT_ATTR_RELATIME = 0x00000000
|
|
MOUNT_ATTR_NOATIME = 0x00000010
|
|
MOUNT_ATTR_STRICTATIME = 0x00000020
|
|
MOUNT_ATTR_NODIRATIME = 0x00000080
|
|
MOUNT_ATTR_IDMAP = 0x00100000
|
|
MOUNT_ATTR_NOSYMFOLLOW = 0x00200000
|
|
AT_RECURSIVE = 0x8000
|
|
)
|
|
|
|
// Constants for open_tree(2).
|
|
const (
|
|
OPEN_TREE_CLONE = (1 << 0)
|
|
OPEN_TREE_NAMESPACE = (1 << 1)
|
|
OPEN_TREE_CLOEXEC = O_CLOEXEC
|
|
)
|
|
|
|
// Constants for unlinkat(2).
|
|
const (
|
|
AT_REMOVEDIR = 0x200
|
|
)
|
|
|
|
// Constants for linkat(2) and fchownat(2).
|
|
const (
|
|
AT_SYMLINK_FOLLOW = 0x400
|
|
AT_EMPTY_PATH = 0x1000
|
|
)
|
|
|
|
// Constants for faccessat2(2).
|
|
const (
|
|
AT_EACCESS = 0x200
|
|
)
|
|
|
|
// Constants for all file-related ...at(2) syscalls.
|
|
const (
|
|
AT_FDCWD = -100
|
|
)
|
|
|
|
// Special values for the ns field in utimensat(2).
|
|
const (
|
|
UTIME_NOW = ((1 << 30) - 1)
|
|
UTIME_OMIT = ((1 << 30) - 2)
|
|
)
|
|
|
|
// MaxSymlinkTraversals is the maximum number of links that will be followed by
|
|
// the kernel to resolve a symlink.
|
|
const MaxSymlinkTraversals = 40
|
|
|
|
// Constants for flock(2).
|
|
const (
|
|
LOCK_SH = 1 // shared lock
|
|
LOCK_EX = 2 // exclusive lock
|
|
LOCK_NB = 4 // or'd with one of the above to prevent blocking
|
|
LOCK_UN = 8 // remove lock
|
|
)
|
|
|
|
// Values for mode_t.
|
|
const (
|
|
S_IFMT = 0170000
|
|
S_IFSOCK = 0140000
|
|
S_IFLNK = 0120000
|
|
S_IFREG = 0100000
|
|
S_IFBLK = 060000
|
|
S_IFDIR = 040000
|
|
S_IFCHR = 020000
|
|
S_IFIFO = 010000
|
|
|
|
FileTypeMask = S_IFMT
|
|
ModeSocket = S_IFSOCK
|
|
ModeSymlink = S_IFLNK
|
|
ModeRegular = S_IFREG
|
|
ModeBlockDevice = S_IFBLK
|
|
ModeDirectory = S_IFDIR
|
|
ModeCharacterDevice = S_IFCHR
|
|
ModeNamedPipe = S_IFIFO
|
|
|
|
S_ISUID = 04000
|
|
S_ISGID = 02000
|
|
S_ISVTX = 01000
|
|
|
|
ModeSetUID = S_ISUID
|
|
ModeSetGID = S_ISGID
|
|
ModeSticky = S_ISVTX
|
|
|
|
ModeUserAll = 0700
|
|
ModeUserRead = 0400
|
|
ModeUserWrite = 0200
|
|
ModeUserExec = 0100
|
|
ModeGroupAll = 0070
|
|
ModeGroupRead = 0040
|
|
ModeGroupWrite = 0020
|
|
ModeGroupExec = 0010
|
|
ModeOtherAll = 0007
|
|
ModeOtherRead = 0004
|
|
ModeOtherWrite = 0002
|
|
ModeOtherExec = 0001
|
|
PermissionsMask = 0777
|
|
)
|
|
|
|
// Values for linux_dirent64.d_type.
|
|
const (
|
|
DT_UNKNOWN = 0
|
|
DT_FIFO = 1
|
|
DT_CHR = 2
|
|
DT_DIR = 4
|
|
DT_BLK = 6
|
|
DT_REG = 8
|
|
DT_LNK = 10
|
|
DT_SOCK = 12
|
|
DT_WHT = 14
|
|
)
|
|
|
|
// DirentType are the friendly strings for linux_dirent64.d_type.
|
|
var DirentType = abi.ValueSet{
|
|
DT_UNKNOWN: "DT_UNKNOWN",
|
|
DT_FIFO: "DT_FIFO",
|
|
DT_CHR: "DT_CHR",
|
|
DT_DIR: "DT_DIR",
|
|
DT_BLK: "DT_BLK",
|
|
DT_REG: "DT_REG",
|
|
DT_LNK: "DT_LNK",
|
|
DT_SOCK: "DT_SOCK",
|
|
DT_WHT: "DT_WHT",
|
|
}
|
|
|
|
// Values for fs on-disk file types.
|
|
const (
|
|
FT_UNKNOWN = 0
|
|
FT_REG_FILE = 1
|
|
FT_DIR = 2
|
|
FT_CHRDEV = 3
|
|
FT_BLKDEV = 4
|
|
FT_FIFO = 5
|
|
FT_SOCK = 6
|
|
FT_SYMLINK = 7
|
|
FT_MAX = 8
|
|
)
|
|
|
|
// Conversion from fs on-disk file type to dirent type.
|
|
var direntTypeByFileType = [FT_MAX]uint8{
|
|
FT_UNKNOWN: DT_UNKNOWN,
|
|
FT_REG_FILE: DT_REG,
|
|
FT_DIR: DT_DIR,
|
|
FT_CHRDEV: DT_CHR,
|
|
FT_BLKDEV: DT_BLK,
|
|
FT_FIFO: DT_FIFO,
|
|
FT_SOCK: DT_SOCK,
|
|
FT_SYMLINK: DT_LNK,
|
|
}
|
|
|
|
// FileTypeToDirentType converts the on-disk file type (FT_*) to the directory
|
|
// entry type (DT_*).
|
|
func FileTypeToDirentType(filetype uint8) uint8 {
|
|
if filetype >= FT_MAX {
|
|
return DT_UNKNOWN
|
|
}
|
|
return direntTypeByFileType[filetype]
|
|
}
|
|
|
|
// Values for preadv2/pwritev2.
|
|
const (
|
|
// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
|
|
// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
|
|
// silently ignored.
|
|
RWF_HIPRI = 0x00000001
|
|
RWF_DSYNC = 0x00000002
|
|
RWF_SYNC = 0x00000004
|
|
RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
|
|
)
|
|
|
|
// SizeOfStat is the size of a Stat struct.
|
|
var SizeOfStat = (*Stat)(nil).SizeBytes()
|
|
|
|
// Flags for statx.
|
|
const (
|
|
AT_NO_AUTOMOUNT = 0x800
|
|
AT_STATX_SYNC_TYPE = 0x6000
|
|
AT_STATX_SYNC_AS_STAT = 0x0000
|
|
AT_STATX_FORCE_SYNC = 0x2000
|
|
AT_STATX_DONT_SYNC = 0x4000
|
|
)
|
|
|
|
// Mask values for statx.
|
|
const (
|
|
STATX_TYPE = 0x00000001
|
|
STATX_MODE = 0x00000002
|
|
STATX_NLINK = 0x00000004
|
|
STATX_UID = 0x00000008
|
|
STATX_GID = 0x00000010
|
|
STATX_ATIME = 0x00000020
|
|
STATX_MTIME = 0x00000040
|
|
STATX_CTIME = 0x00000080
|
|
STATX_INO = 0x00000100
|
|
STATX_SIZE = 0x00000200
|
|
STATX_BLOCKS = 0x00000400
|
|
STATX_BASIC_STATS = 0x000007ff
|
|
STATX_BTIME = 0x00000800
|
|
STATX_MNT_ID = 0x00001000
|
|
STATX_ALL = 0x00000fff
|
|
STATX__RESERVED = 0x80000000
|
|
)
|
|
|
|
// Bitmasks for Statx.Attributes and Statx.AttributesMask, from
|
|
// include/uapi/linux/stat.h.
|
|
const (
|
|
STATX_ATTR_COMPRESSED = 0x00000004
|
|
STATX_ATTR_IMMUTABLE = 0x00000010
|
|
STATX_ATTR_APPEND = 0x00000020
|
|
STATX_ATTR_NODUMP = 0x00000040
|
|
STATX_ATTR_ENCRYPTED = 0x00000800
|
|
STATX_ATTR_AUTOMOUNT = 0x00001000
|
|
)
|
|
|
|
// Statx represents struct statx.
|
|
//
|
|
// +marshal boundCheck slice:StatxSlice
|
|
type Statx struct {
|
|
_ structs.HostLayout
|
|
Mask uint32
|
|
Blksize uint32
|
|
Attributes uint64
|
|
Nlink uint32
|
|
UID uint32
|
|
GID uint32
|
|
Mode uint16
|
|
_ uint16
|
|
Ino uint64
|
|
Size uint64
|
|
Blocks uint64
|
|
AttributesMask uint64
|
|
Atime StatxTimestamp
|
|
Btime StatxTimestamp
|
|
Ctime StatxTimestamp
|
|
Mtime StatxTimestamp
|
|
RdevMajor uint32
|
|
RdevMinor uint32
|
|
DevMajor uint32
|
|
DevMinor uint32
|
|
MntID uint64
|
|
}
|
|
|
|
// String implements fmt.Stringer.String.
|
|
func (s *Statx) String() string {
|
|
return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d, MntId: %d}",
|
|
s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor, s.MntID)
|
|
}
|
|
|
|
// SizeOfStatx is the size of a Statx struct.
|
|
var SizeOfStatx = (*Statx)(nil).SizeBytes()
|
|
|
|
// FileMode represents a mode_t.
|
|
//
|
|
// +marshal
|
|
type FileMode uint16
|
|
|
|
// Permissions returns just the permission bits.
|
|
func (m FileMode) Permissions() FileMode {
|
|
return m & PermissionsMask
|
|
}
|
|
|
|
// FileType returns just the file type bits.
|
|
func (m FileMode) FileType() FileMode {
|
|
return m & FileTypeMask
|
|
}
|
|
|
|
// ExtraBits returns everything but the file type and permission bits.
|
|
func (m FileMode) ExtraBits() FileMode {
|
|
return m &^ (PermissionsMask | FileTypeMask)
|
|
}
|
|
|
|
// IsDir returns true if file type represents a directory.
|
|
func (m FileMode) IsDir() bool {
|
|
return m.FileType() == S_IFDIR
|
|
}
|
|
|
|
// IsSpecialFile returns true if m is the mode of a "special file": a character
|
|
// or block device, FIFO, or socket.
|
|
//
|
|
// Analogous to include/linux/fs.h:special_file().
|
|
func (m FileMode) IsSpecialFile() bool {
|
|
switch m.FileType() {
|
|
case ModeCharacterDevice, ModeBlockDevice, ModeNamedPipe, ModeSocket:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// String returns a string representation of m.
|
|
func (m FileMode) String() string {
|
|
var s []string
|
|
if ft := m.FileType(); ft != 0 {
|
|
s = append(s, fileType.Parse(uint64(ft)))
|
|
}
|
|
if eb := m.ExtraBits(); eb != 0 {
|
|
s = append(s, modeExtraBits.Parse(uint64(eb)))
|
|
}
|
|
s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
|
|
return strings.Join(s, "|")
|
|
}
|
|
|
|
// DirentType maps file types to dirent types appropriate for (struct
|
|
// dirent)::d_type.
|
|
func (m FileMode) DirentType() uint8 {
|
|
switch m.FileType() {
|
|
case ModeSocket:
|
|
return DT_SOCK
|
|
case ModeSymlink:
|
|
return DT_LNK
|
|
case ModeRegular:
|
|
return DT_REG
|
|
case ModeBlockDevice:
|
|
return DT_BLK
|
|
case ModeDirectory:
|
|
return DT_DIR
|
|
case ModeCharacterDevice:
|
|
return DT_CHR
|
|
case ModeNamedPipe:
|
|
return DT_FIFO
|
|
default:
|
|
return DT_UNKNOWN
|
|
}
|
|
}
|
|
|
|
var modeExtraBits = abi.FlagSet{
|
|
{
|
|
Flag: ModeSetUID,
|
|
Name: "S_ISUID",
|
|
},
|
|
{
|
|
Flag: ModeSetGID,
|
|
Name: "S_ISGID",
|
|
},
|
|
{
|
|
Flag: ModeSticky,
|
|
Name: "S_ISVTX",
|
|
},
|
|
}
|
|
|
|
var fileType = abi.ValueSet{
|
|
ModeSocket: "S_IFSOCK",
|
|
ModeSymlink: "S_IFLINK",
|
|
ModeRegular: "S_IFREG",
|
|
ModeBlockDevice: "S_IFBLK",
|
|
ModeDirectory: "S_IFDIR",
|
|
ModeCharacterDevice: "S_IFCHR",
|
|
ModeNamedPipe: "S_IFIFO",
|
|
}
|
|
|
|
// Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
|
|
const (
|
|
MFD_CLOEXEC = 0x0001
|
|
MFD_ALLOW_SEALING = 0x0002
|
|
)
|
|
|
|
// Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
|
|
const (
|
|
F_LINUX_SPECIFIC_BASE = 1024
|
|
F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9
|
|
F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10
|
|
|
|
F_SEAL_SEAL = 0x0001 // Prevent further seals from being set.
|
|
F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
|
|
F_SEAL_GROW = 0x0004 // Prevent file from growing.
|
|
F_SEAL_WRITE = 0x0008 // Prevent writes.
|
|
)
|
|
|
|
// Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
|
|
const (
|
|
FALLOC_FL_KEEP_SIZE = 0x01
|
|
FALLOC_FL_PUNCH_HOLE = 0x02
|
|
FALLOC_FL_NO_HIDE_STALE = 0x04
|
|
FALLOC_FL_COLLAPSE_RANGE = 0x08
|
|
FALLOC_FL_ZERO_RANGE = 0x10
|
|
FALLOC_FL_INSERT_RANGE = 0x20
|
|
FALLOC_FL_UNSHARE_RANGE = 0x40
|
|
)
|
|
|
|
// Constants related to close_range(2). Source: /include/uapi/linux/close_range.h
|
|
const (
|
|
CLOSE_RANGE_UNSHARE = uint32(1 << 1)
|
|
CLOSE_RANGE_CLOEXEC = uint32(1 << 2)
|
|
)
|