github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/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/MerlinKodo/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 faccessat2(2).
   100  const (
   101  	AT_EACCESS = 0x200
   102  )
   103  
   104  // Constants for all file-related ...at(2) syscalls.
   105  const (
   106  	AT_FDCWD = -100
   107  )
   108  
   109  // Special values for the ns field in utimensat(2).
   110  const (
   111  	UTIME_NOW  = ((1 << 30) - 1)
   112  	UTIME_OMIT = ((1 << 30) - 2)
   113  )
   114  
   115  // MaxSymlinkTraversals is the maximum number of links that will be followed by
   116  // the kernel to resolve a symlink.
   117  const MaxSymlinkTraversals = 40
   118  
   119  // Constants for flock(2).
   120  const (
   121  	LOCK_SH = 1 // shared lock
   122  	LOCK_EX = 2 // exclusive lock
   123  	LOCK_NB = 4 // or'd with one of the above to prevent blocking
   124  	LOCK_UN = 8 // remove lock
   125  )
   126  
   127  // Values for mode_t.
   128  const (
   129  	S_IFMT   = 0170000
   130  	S_IFSOCK = 0140000
   131  	S_IFLNK  = 0120000
   132  	S_IFREG  = 0100000
   133  	S_IFBLK  = 060000
   134  	S_IFDIR  = 040000
   135  	S_IFCHR  = 020000
   136  	S_IFIFO  = 010000
   137  
   138  	FileTypeMask        = S_IFMT
   139  	ModeSocket          = S_IFSOCK
   140  	ModeSymlink         = S_IFLNK
   141  	ModeRegular         = S_IFREG
   142  	ModeBlockDevice     = S_IFBLK
   143  	ModeDirectory       = S_IFDIR
   144  	ModeCharacterDevice = S_IFCHR
   145  	ModeNamedPipe       = S_IFIFO
   146  
   147  	S_ISUID = 04000
   148  	S_ISGID = 02000
   149  	S_ISVTX = 01000
   150  
   151  	ModeSetUID = S_ISUID
   152  	ModeSetGID = S_ISGID
   153  	ModeSticky = S_ISVTX
   154  
   155  	ModeUserAll     = 0700
   156  	ModeUserRead    = 0400
   157  	ModeUserWrite   = 0200
   158  	ModeUserExec    = 0100
   159  	ModeGroupAll    = 0070
   160  	ModeGroupRead   = 0040
   161  	ModeGroupWrite  = 0020
   162  	ModeGroupExec   = 0010
   163  	ModeOtherAll    = 0007
   164  	ModeOtherRead   = 0004
   165  	ModeOtherWrite  = 0002
   166  	ModeOtherExec   = 0001
   167  	PermissionsMask = 0777
   168  )
   169  
   170  // Values for linux_dirent64.d_type.
   171  const (
   172  	DT_UNKNOWN = 0
   173  	DT_FIFO    = 1
   174  	DT_CHR     = 2
   175  	DT_DIR     = 4
   176  	DT_BLK     = 6
   177  	DT_REG     = 8
   178  	DT_LNK     = 10
   179  	DT_SOCK    = 12
   180  	DT_WHT     = 14
   181  )
   182  
   183  // DirentType are the friendly strings for linux_dirent64.d_type.
   184  var DirentType = abi.ValueSet{
   185  	DT_UNKNOWN: "DT_UNKNOWN",
   186  	DT_FIFO:    "DT_FIFO",
   187  	DT_CHR:     "DT_CHR",
   188  	DT_DIR:     "DT_DIR",
   189  	DT_BLK:     "DT_BLK",
   190  	DT_REG:     "DT_REG",
   191  	DT_LNK:     "DT_LNK",
   192  	DT_SOCK:    "DT_SOCK",
   193  	DT_WHT:     "DT_WHT",
   194  }
   195  
   196  // Values for preadv2/pwritev2.
   197  const (
   198  	// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
   199  	// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
   200  	// silently ignored.
   201  	RWF_HIPRI = 0x00000001
   202  	RWF_DSYNC = 0x00000002
   203  	RWF_SYNC  = 0x00000004
   204  	RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
   205  )
   206  
   207  // SizeOfStat is the size of a Stat struct.
   208  var SizeOfStat = (*Stat)(nil).SizeBytes()
   209  
   210  // Flags for statx.
   211  const (
   212  	AT_NO_AUTOMOUNT       = 0x800
   213  	AT_STATX_SYNC_TYPE    = 0x6000
   214  	AT_STATX_SYNC_AS_STAT = 0x0000
   215  	AT_STATX_FORCE_SYNC   = 0x2000
   216  	AT_STATX_DONT_SYNC    = 0x4000
   217  )
   218  
   219  // Mask values for statx.
   220  const (
   221  	STATX_TYPE        = 0x00000001
   222  	STATX_MODE        = 0x00000002
   223  	STATX_NLINK       = 0x00000004
   224  	STATX_UID         = 0x00000008
   225  	STATX_GID         = 0x00000010
   226  	STATX_ATIME       = 0x00000020
   227  	STATX_MTIME       = 0x00000040
   228  	STATX_CTIME       = 0x00000080
   229  	STATX_INO         = 0x00000100
   230  	STATX_SIZE        = 0x00000200
   231  	STATX_BLOCKS      = 0x00000400
   232  	STATX_BASIC_STATS = 0x000007ff
   233  	STATX_BTIME       = 0x00000800
   234  	STATX_ALL         = 0x00000fff
   235  	STATX__RESERVED   = 0x80000000
   236  )
   237  
   238  // Bitmasks for Statx.Attributes and Statx.AttributesMask, from
   239  // include/uapi/linux/stat.h.
   240  const (
   241  	STATX_ATTR_COMPRESSED = 0x00000004
   242  	STATX_ATTR_IMMUTABLE  = 0x00000010
   243  	STATX_ATTR_APPEND     = 0x00000020
   244  	STATX_ATTR_NODUMP     = 0x00000040
   245  	STATX_ATTR_ENCRYPTED  = 0x00000800
   246  	STATX_ATTR_AUTOMOUNT  = 0x00001000
   247  )
   248  
   249  // Statx represents struct statx.
   250  //
   251  // +marshal boundCheck slice:StatxSlice
   252  type Statx struct {
   253  	Mask           uint32
   254  	Blksize        uint32
   255  	Attributes     uint64
   256  	Nlink          uint32
   257  	UID            uint32
   258  	GID            uint32
   259  	Mode           uint16
   260  	_              uint16
   261  	Ino            uint64
   262  	Size           uint64
   263  	Blocks         uint64
   264  	AttributesMask uint64
   265  	Atime          StatxTimestamp
   266  	Btime          StatxTimestamp
   267  	Ctime          StatxTimestamp
   268  	Mtime          StatxTimestamp
   269  	RdevMajor      uint32
   270  	RdevMinor      uint32
   271  	DevMajor       uint32
   272  	DevMinor       uint32
   273  }
   274  
   275  // String implements fmt.Stringer.String.
   276  func (s *Statx) String() string {
   277  	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}",
   278  		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)
   279  }
   280  
   281  // SizeOfStatx is the size of a Statx struct.
   282  var SizeOfStatx = (*Statx)(nil).SizeBytes()
   283  
   284  // FileMode represents a mode_t.
   285  //
   286  // +marshal
   287  type FileMode uint16
   288  
   289  // Permissions returns just the permission bits.
   290  func (m FileMode) Permissions() FileMode {
   291  	return m & PermissionsMask
   292  }
   293  
   294  // FileType returns just the file type bits.
   295  func (m FileMode) FileType() FileMode {
   296  	return m & FileTypeMask
   297  }
   298  
   299  // ExtraBits returns everything but the file type and permission bits.
   300  func (m FileMode) ExtraBits() FileMode {
   301  	return m &^ (PermissionsMask | FileTypeMask)
   302  }
   303  
   304  // IsDir returns true if file type represents a directory.
   305  func (m FileMode) IsDir() bool {
   306  	return m.FileType() == S_IFDIR
   307  }
   308  
   309  // String returns a string representation of m.
   310  func (m FileMode) String() string {
   311  	var s []string
   312  	if ft := m.FileType(); ft != 0 {
   313  		s = append(s, fileType.Parse(uint64(ft)))
   314  	}
   315  	if eb := m.ExtraBits(); eb != 0 {
   316  		s = append(s, modeExtraBits.Parse(uint64(eb)))
   317  	}
   318  	s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
   319  	return strings.Join(s, "|")
   320  }
   321  
   322  // DirentType maps file types to dirent types appropriate for (struct
   323  // dirent)::d_type.
   324  func (m FileMode) DirentType() uint8 {
   325  	switch m.FileType() {
   326  	case ModeSocket:
   327  		return DT_SOCK
   328  	case ModeSymlink:
   329  		return DT_LNK
   330  	case ModeRegular:
   331  		return DT_REG
   332  	case ModeBlockDevice:
   333  		return DT_BLK
   334  	case ModeDirectory:
   335  		return DT_DIR
   336  	case ModeCharacterDevice:
   337  		return DT_CHR
   338  	case ModeNamedPipe:
   339  		return DT_FIFO
   340  	default:
   341  		return DT_UNKNOWN
   342  	}
   343  }
   344  
   345  var modeExtraBits = abi.FlagSet{
   346  	{
   347  		Flag: ModeSetUID,
   348  		Name: "S_ISUID",
   349  	},
   350  	{
   351  		Flag: ModeSetGID,
   352  		Name: "S_ISGID",
   353  	},
   354  	{
   355  		Flag: ModeSticky,
   356  		Name: "S_ISVTX",
   357  	},
   358  }
   359  
   360  var fileType = abi.ValueSet{
   361  	ModeSocket:          "S_IFSOCK",
   362  	ModeSymlink:         "S_IFLINK",
   363  	ModeRegular:         "S_IFREG",
   364  	ModeBlockDevice:     "S_IFBLK",
   365  	ModeDirectory:       "S_IFDIR",
   366  	ModeCharacterDevice: "S_IFCHR",
   367  	ModeNamedPipe:       "S_IFIFO",
   368  }
   369  
   370  // Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
   371  const (
   372  	MFD_CLOEXEC       = 0x0001
   373  	MFD_ALLOW_SEALING = 0x0002
   374  )
   375  
   376  // Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
   377  const (
   378  	F_LINUX_SPECIFIC_BASE = 1024
   379  	F_ADD_SEALS           = F_LINUX_SPECIFIC_BASE + 9
   380  	F_GET_SEALS           = F_LINUX_SPECIFIC_BASE + 10
   381  
   382  	F_SEAL_SEAL   = 0x0001 // Prevent further seals from being set.
   383  	F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
   384  	F_SEAL_GROW   = 0x0004 // Prevent file from growing.
   385  	F_SEAL_WRITE  = 0x0008 // Prevent writes.
   386  )
   387  
   388  // Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
   389  const (
   390  	FALLOC_FL_KEEP_SIZE      = 0x01
   391  	FALLOC_FL_PUNCH_HOLE     = 0x02
   392  	FALLOC_FL_NO_HIDE_STALE  = 0x04
   393  	FALLOC_FL_COLLAPSE_RANGE = 0x08
   394  	FALLOC_FL_ZERO_RANGE     = 0x10
   395  	FALLOC_FL_INSERT_RANGE   = 0x20
   396  	FALLOC_FL_UNSHARE_RANGE  = 0x40
   397  )
   398  
   399  // Constants related to close_range(2). Source: /include/uapi/linux/close_range.h
   400  const (
   401  	CLOSE_RANGE_UNSHARE = uint32(1 << 1)
   402  	CLOSE_RANGE_CLOEXEC = uint32(1 << 2)
   403  )