github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/abi/linux/file.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package linux
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/SagerNet/gvisor/pkg/abi"
    22  )
    23  
    24  // Constants for open(2).
    25  const (
    26  	O_ACCMODE  = 000000003
    27  	O_RDONLY   = 000000000
    28  	O_WRONLY   = 000000001
    29  	O_RDWR     = 000000002
    30  	O_CREAT    = 000000100
    31  	O_EXCL     = 000000200
    32  	O_NOCTTY   = 000000400
    33  	O_TRUNC    = 000001000
    34  	O_APPEND   = 000002000
    35  	O_NONBLOCK = 000004000
    36  	O_DSYNC    = 000010000
    37  	O_ASYNC    = 000020000
    38  	O_NOATIME  = 001000000
    39  	O_CLOEXEC  = 002000000
    40  	O_SYNC     = 004000000 // __O_SYNC in Linux
    41  	O_PATH     = 010000000
    42  	O_TMPFILE  = 020000000 // __O_TMPFILE in Linux
    43  )
    44  
    45  // Constants for fstatat(2).
    46  const (
    47  	AT_SYMLINK_NOFOLLOW = 0x100
    48  )
    49  
    50  // Constants for mount(2).
    51  const (
    52  	MS_RDONLY      = 0x1
    53  	MS_NOSUID      = 0x2
    54  	MS_NODEV       = 0x4
    55  	MS_NOEXEC      = 0x8
    56  	MS_SYNCHRONOUS = 0x10
    57  	MS_REMOUNT     = 0x20
    58  	MS_MANDLOCK    = 0x40
    59  	MS_DIRSYNC     = 0x80
    60  	MS_NOATIME     = 0x400
    61  	MS_NODIRATIME  = 0x800
    62  	MS_BIND        = 0x1000
    63  	MS_MOVE        = 0x2000
    64  	MS_REC         = 0x4000
    65  
    66  	MS_POSIXACL    = 0x10000
    67  	MS_UNBINDABLE  = 0x20000
    68  	MS_PRIVATE     = 0x40000
    69  	MS_SLAVE       = 0x80000
    70  	MS_SHARED      = 0x100000
    71  	MS_RELATIME    = 0x200000
    72  	MS_KERNMOUNT   = 0x400000
    73  	MS_I_VERSION   = 0x800000
    74  	MS_STRICTATIME = 0x1000000
    75  
    76  	MS_MGC_VAL = 0xC0ED0000
    77  	MS_MGC_MSK = 0xffff0000
    78  )
    79  
    80  // Constants for umount2(2).
    81  const (
    82  	MNT_FORCE       = 0x1
    83  	MNT_DETACH      = 0x2
    84  	MNT_EXPIRE      = 0x4
    85  	UMOUNT_NOFOLLOW = 0x8
    86  )
    87  
    88  // Constants for unlinkat(2).
    89  const (
    90  	AT_REMOVEDIR = 0x200
    91  )
    92  
    93  // Constants for linkat(2) and fchownat(2).
    94  const (
    95  	AT_SYMLINK_FOLLOW = 0x400
    96  	AT_EMPTY_PATH     = 0x1000
    97  )
    98  
    99  // Constants for all file-related ...at(2) syscalls.
   100  const (
   101  	AT_FDCWD = -100
   102  )
   103  
   104  // Special values for the ns field in utimensat(2).
   105  const (
   106  	UTIME_NOW  = ((1 << 30) - 1)
   107  	UTIME_OMIT = ((1 << 30) - 2)
   108  )
   109  
   110  // MaxSymlinkTraversals is the maximum number of links that will be followed by
   111  // the kernel to resolve a symlink.
   112  const MaxSymlinkTraversals = 40
   113  
   114  // Constants for flock(2).
   115  const (
   116  	LOCK_SH = 1 // shared lock
   117  	LOCK_EX = 2 // exclusive lock
   118  	LOCK_NB = 4 // or'd with one of the above to prevent blocking
   119  	LOCK_UN = 8 // remove lock
   120  )
   121  
   122  // Values for mode_t.
   123  const (
   124  	S_IFMT   = 0170000
   125  	S_IFSOCK = 0140000
   126  	S_IFLNK  = 0120000
   127  	S_IFREG  = 0100000
   128  	S_IFBLK  = 060000
   129  	S_IFDIR  = 040000
   130  	S_IFCHR  = 020000
   131  	S_IFIFO  = 010000
   132  
   133  	FileTypeMask        = S_IFMT
   134  	ModeSocket          = S_IFSOCK
   135  	ModeSymlink         = S_IFLNK
   136  	ModeRegular         = S_IFREG
   137  	ModeBlockDevice     = S_IFBLK
   138  	ModeDirectory       = S_IFDIR
   139  	ModeCharacterDevice = S_IFCHR
   140  	ModeNamedPipe       = S_IFIFO
   141  
   142  	S_ISUID = 04000
   143  	S_ISGID = 02000
   144  	S_ISVTX = 01000
   145  
   146  	ModeSetUID = S_ISUID
   147  	ModeSetGID = S_ISGID
   148  	ModeSticky = S_ISVTX
   149  
   150  	ModeUserAll     = 0700
   151  	ModeUserRead    = 0400
   152  	ModeUserWrite   = 0200
   153  	ModeUserExec    = 0100
   154  	ModeGroupAll    = 0070
   155  	ModeGroupRead   = 0040
   156  	ModeGroupWrite  = 0020
   157  	ModeGroupExec   = 0010
   158  	ModeOtherAll    = 0007
   159  	ModeOtherRead   = 0004
   160  	ModeOtherWrite  = 0002
   161  	ModeOtherExec   = 0001
   162  	PermissionsMask = 0777
   163  )
   164  
   165  // Values for linux_dirent64.d_type.
   166  const (
   167  	DT_UNKNOWN = 0
   168  	DT_FIFO    = 1
   169  	DT_CHR     = 2
   170  	DT_DIR     = 4
   171  	DT_BLK     = 6
   172  	DT_REG     = 8
   173  	DT_LNK     = 10
   174  	DT_SOCK    = 12
   175  	DT_WHT     = 14
   176  )
   177  
   178  // DirentType are the friendly strings for linux_dirent64.d_type.
   179  var DirentType = abi.ValueSet{
   180  	DT_UNKNOWN: "DT_UNKNOWN",
   181  	DT_FIFO:    "DT_FIFO",
   182  	DT_CHR:     "DT_CHR",
   183  	DT_DIR:     "DT_DIR",
   184  	DT_BLK:     "DT_BLK",
   185  	DT_REG:     "DT_REG",
   186  	DT_LNK:     "DT_LNK",
   187  	DT_SOCK:    "DT_SOCK",
   188  	DT_WHT:     "DT_WHT",
   189  }
   190  
   191  // Values for preadv2/pwritev2.
   192  const (
   193  	// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
   194  	// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
   195  	// silently ignored.
   196  	RWF_HIPRI = 0x00000001
   197  	RWF_DSYNC = 0x00000002
   198  	RWF_SYNC  = 0x00000004
   199  	RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
   200  )
   201  
   202  // SizeOfStat is the size of a Stat struct.
   203  var SizeOfStat = (*Stat)(nil).SizeBytes()
   204  
   205  // Flags for statx.
   206  const (
   207  	AT_STATX_SYNC_TYPE    = 0x6000
   208  	AT_STATX_SYNC_AS_STAT = 0x0000
   209  	AT_STATX_FORCE_SYNC   = 0x2000
   210  	AT_STATX_DONT_SYNC    = 0x4000
   211  )
   212  
   213  // Mask values for statx.
   214  const (
   215  	STATX_TYPE        = 0x00000001
   216  	STATX_MODE        = 0x00000002
   217  	STATX_NLINK       = 0x00000004
   218  	STATX_UID         = 0x00000008
   219  	STATX_GID         = 0x00000010
   220  	STATX_ATIME       = 0x00000020
   221  	STATX_MTIME       = 0x00000040
   222  	STATX_CTIME       = 0x00000080
   223  	STATX_INO         = 0x00000100
   224  	STATX_SIZE        = 0x00000200
   225  	STATX_BLOCKS      = 0x00000400
   226  	STATX_BASIC_STATS = 0x000007ff
   227  	STATX_BTIME       = 0x00000800
   228  	STATX_ALL         = 0x00000fff
   229  	STATX__RESERVED   = 0x80000000
   230  )
   231  
   232  // Bitmasks for Statx.Attributes and Statx.AttributesMask, from
   233  // include/uapi/linux/stat.h.
   234  const (
   235  	STATX_ATTR_COMPRESSED = 0x00000004
   236  	STATX_ATTR_IMMUTABLE  = 0x00000010
   237  	STATX_ATTR_APPEND     = 0x00000020
   238  	STATX_ATTR_NODUMP     = 0x00000040
   239  	STATX_ATTR_ENCRYPTED  = 0x00000800
   240  	STATX_ATTR_AUTOMOUNT  = 0x00001000
   241  )
   242  
   243  // Statx represents struct statx.
   244  //
   245  // +marshal
   246  type Statx struct {
   247  	Mask           uint32
   248  	Blksize        uint32
   249  	Attributes     uint64
   250  	Nlink          uint32
   251  	UID            uint32
   252  	GID            uint32
   253  	Mode           uint16
   254  	_              uint16
   255  	Ino            uint64
   256  	Size           uint64
   257  	Blocks         uint64
   258  	AttributesMask uint64
   259  	Atime          StatxTimestamp
   260  	Btime          StatxTimestamp
   261  	Ctime          StatxTimestamp
   262  	Mtime          StatxTimestamp
   263  	RdevMajor      uint32
   264  	RdevMinor      uint32
   265  	DevMajor       uint32
   266  	DevMinor       uint32
   267  }
   268  
   269  // SizeOfStatx is the size of a Statx struct.
   270  var SizeOfStatx = (*Statx)(nil).SizeBytes()
   271  
   272  // FileMode represents a mode_t.
   273  type FileMode uint16
   274  
   275  // Permissions returns just the permission bits.
   276  func (m FileMode) Permissions() FileMode {
   277  	return m & PermissionsMask
   278  }
   279  
   280  // FileType returns just the file type bits.
   281  func (m FileMode) FileType() FileMode {
   282  	return m & FileTypeMask
   283  }
   284  
   285  // ExtraBits returns everything but the file type and permission bits.
   286  func (m FileMode) ExtraBits() FileMode {
   287  	return m &^ (PermissionsMask | FileTypeMask)
   288  }
   289  
   290  // IsDir returns true if file type represents a directory.
   291  func (m FileMode) IsDir() bool {
   292  	return m.FileType() == S_IFDIR
   293  }
   294  
   295  // String returns a string representation of m.
   296  func (m FileMode) String() string {
   297  	var s []string
   298  	if ft := m.FileType(); ft != 0 {
   299  		s = append(s, fileType.Parse(uint64(ft)))
   300  	}
   301  	if eb := m.ExtraBits(); eb != 0 {
   302  		s = append(s, modeExtraBits.Parse(uint64(eb)))
   303  	}
   304  	s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
   305  	return strings.Join(s, "|")
   306  }
   307  
   308  // DirentType maps file types to dirent types appropriate for (struct
   309  // dirent)::d_type.
   310  func (m FileMode) DirentType() uint8 {
   311  	switch m.FileType() {
   312  	case ModeSocket:
   313  		return DT_SOCK
   314  	case ModeSymlink:
   315  		return DT_LNK
   316  	case ModeRegular:
   317  		return DT_REG
   318  	case ModeBlockDevice:
   319  		return DT_BLK
   320  	case ModeDirectory:
   321  		return DT_DIR
   322  	case ModeCharacterDevice:
   323  		return DT_CHR
   324  	case ModeNamedPipe:
   325  		return DT_FIFO
   326  	default:
   327  		return DT_UNKNOWN
   328  	}
   329  }
   330  
   331  var modeExtraBits = abi.FlagSet{
   332  	{
   333  		Flag: ModeSetUID,
   334  		Name: "S_ISUID",
   335  	},
   336  	{
   337  		Flag: ModeSetGID,
   338  		Name: "S_ISGID",
   339  	},
   340  	{
   341  		Flag: ModeSticky,
   342  		Name: "S_ISVTX",
   343  	},
   344  }
   345  
   346  var fileType = abi.ValueSet{
   347  	ModeSocket:          "S_IFSOCK",
   348  	ModeSymlink:         "S_IFLINK",
   349  	ModeRegular:         "S_IFREG",
   350  	ModeBlockDevice:     "S_IFBLK",
   351  	ModeDirectory:       "S_IFDIR",
   352  	ModeCharacterDevice: "S_IFCHR",
   353  	ModeNamedPipe:       "S_IFIFO",
   354  }
   355  
   356  // Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
   357  const (
   358  	MFD_CLOEXEC       = 0x0001
   359  	MFD_ALLOW_SEALING = 0x0002
   360  )
   361  
   362  // Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
   363  const (
   364  	F_LINUX_SPECIFIC_BASE = 1024
   365  	F_ADD_SEALS           = F_LINUX_SPECIFIC_BASE + 9
   366  	F_GET_SEALS           = F_LINUX_SPECIFIC_BASE + 10
   367  
   368  	F_SEAL_SEAL   = 0x0001 // Prevent further seals from being set.
   369  	F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
   370  	F_SEAL_GROW   = 0x0004 // Prevent file from growing.
   371  	F_SEAL_WRITE  = 0x0008 // Prevent writes.
   372  )
   373  
   374  // Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
   375  const (
   376  	FALLOC_FL_KEEP_SIZE      = 0x01
   377  	FALLOC_FL_PUNCH_HOLE     = 0x02
   378  	FALLOC_FL_NO_HIDE_STALE  = 0x04
   379  	FALLOC_FL_COLLAPSE_RANGE = 0x08
   380  	FALLOC_FL_ZERO_RANGE     = 0x10
   381  	FALLOC_FL_INSERT_RANGE   = 0x20
   382  	FALLOC_FL_UNSHARE_RANGE  = 0x40
   383  )