snapshot: sagernet/gvisor v0.0.0-20260727.0-sing-box-mod.1 + SPEC 048 guard

Обновление снапшота с v0.0.0-20250811.0 на пин, которого требует
sing-box после мержа 235 коммитов (upstream d620bbbf2 "Update gvisor to
20260727.0"). Прежний снапшот был взят 2026-08-04 ровно с той версии,
на которой тогда стоял апстрим; разрыв возник 2026-08-05 вместе с его
бампом.

За год апстрим-gvisor изменил ~14 000 строк в 292 файлах. Значимое для
нас — сетевой стек: tcp/connect.go (PMTU-discovery + исправление
начального RTT/RTO: раньше задержка ACK внутри стека завышала стартовый
таймаут на несколько RTT), tcp/snd.go, tcp/rcv.go, stack/conntrack.go,
stack/packet_buffer.go. Всего 30 файлов в TCP и 37 в stack.

Баг SPEC 048 апстрим НЕ исправил — проверено по коду новой версии:
handleConnecting по-прежнему проверяет состояние endpoint'а, но не ep.h,
а performHandshake так же зануляет h и отпускает мьютекс до Close().
Поэтому guard перенесён (12 строк) вместе со своим тестом (45 строк).

Red/green проверен на новой базе: без guard'а тест падает с той же
nil-паникой, что в полевом крашдампе; с ним зелёный.
This commit is contained in:
Leadaxe 2026-08-05 14:53:31 +03:00
parent ffebe42860
commit 117243aa02
293 changed files with 16413 additions and 2842 deletions

View file

@ -14,11 +14,15 @@
package linux
import "encoding/binary"
import (
"encoding/binary"
"structs"
)
// AIORing is struct aio_ring, from fs/aio.c, without the trailing
// variable-length array.
type AIORing struct {
_ structs.HostLayout
ID uint32
Nr uint32
Head uint32
@ -62,6 +66,7 @@ const (
//
// +marshal
type IOCallback struct {
_ structs.HostLayout
Data uint64
Key uint32
_ uint32
@ -86,6 +91,7 @@ type IOCallback struct {
// +marshal
// +stateify savable
type IOEvent struct {
_ structs.HostLayout
Data uint64
Obj uint64
Result int64

View file

@ -14,11 +14,16 @@
package linux
import (
"structs"
)
// BPFInstruction is a raw BPF virtual machine instruction.
//
// +marshal slice:BPFInstructionSlice
// +stateify savable
type BPFInstruction struct {
_ structs.HostLayout
// OpCode is the operation to execute.
OpCode uint16

View file

@ -16,6 +16,7 @@ package linux
import (
"strings"
"structs"
)
// A Capability represents the ability to perform a privileged operation.
@ -254,6 +255,7 @@ const (
//
// +marshal
type VfsCapData struct {
_ structs.HostLayout
MagicEtc uint32
PermittedLo uint32
InheritableLo uint32
@ -287,6 +289,7 @@ func (c *VfsCapData) ToString() string {
//
// +marshal
type VfsNsCapData struct {
_ structs.HostLayout
VfsCapData
RootID uint32
}
@ -323,6 +326,7 @@ func (c *VfsNsCapData) ToString() string {
//
// +marshal
type CapUserHeader struct {
_ structs.HostLayout
Version uint32
Pid int32
}
@ -331,6 +335,7 @@ type CapUserHeader struct {
//
// +marshal slice:CapUserDataSlice
type CapUserData struct {
_ structs.HostLayout
Effective uint32
Permitted uint32
Inheritable uint32

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Clone constants per clone(2).
const (
CSIGNAL = 0xff
@ -57,6 +61,7 @@ const (
//
// +marshal
type CloneArgs struct {
_ structs.HostLayout
Flags uint64
Pidfd uint64
ChildTID uint64

303
pkg/abi/linux/ebpf.go Normal file
View file

@ -0,0 +1,303 @@
// Copyright 2026 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 (
"structs"
"github.com/sagernet/gvisor/pkg/marshal"
)
// EBPFInstruction is the userspace representation of an eBPF instruction that has not
// been validated.
//
// +marshal slice:EBPFInstructionSlice
// +stateify savable
type EBPFInstruction struct {
_ structs.HostLayout
Code uint8
Registers uint8 // LE: 4 LSBs are destination, 4 MSBs are source
Offset int16
Immediate int32
}
// Constants defining eBPF-related limits.
const (
// Maximum instruction count in an eBPF program
BPF_COMPLEXITY_LIMIT_INSNS = 1_000_000
// Maximum length of an eBPF program's name
BPF_OBJ_NAME_LEN = 16
// Size of an EbpfInstruction
BPF_INSTRUCTION_SIZE = 8
// Maximum number of cgroup eBPF programs per attachment type.
BPF_CGROUP_MAX_PROGS = 64
)
// Valid values for `cmd` for bpf(2).
const (
BPF_MAP_CREATE = iota
BPF_MAP_LOOKUP_ELEM
BPF_MAP_UPDATE_ELEM
BPF_MAP_DELETE_ELEM
BPF_MAP_GET_NEXT_KEY
BPF_PROG_LOAD
BPF_OBJ_PIN
BPF_OBJ_GET
BPF_PROG_ATTACH
BPF_PROG_DETACH
BPF_PROG_TEST_RUN
BPF_PROG_GET_NEXT_ID
BPF_MAP_GET_NEXT_ID
BPF_PROG_GET_FD_BY_ID
BPF_MAP_GET_FD_BY_ID
BPF_OBJ_GET_INFO_BY_FD
BPF_PROG_QUERY
BPF_RAW_TRACEPOINT_OPEN
BPF_BTF_LOAD
BPF_BTF_GET_FD_BY_ID
BPF_TASK_FD_QUERY
BPF_MAP_LOOKUP_AND_DELETE_ELEM
BPF_MAP_FREEZE
BPF_BTF_GET_NEXT_ID
BPF_MAP_LOOKUP_BATCH
BPF_MAP_LOOKUP_AND_DELETE_BATCH
BPF_MAP_UPDATE_BATCH
BPF_MAP_DELETE_BATCH
BPF_LINK_CREATE
BPF_LINK_UPDATE
BPF_LINK_GET_FD_BY_ID
BPF_LINK_GET_NEXT_ID
BPF_ENABLE_STATS
BPF_ITER_CREATE
BPF_LINK_DETACH
BPF_PROG_BIND_MAP
BPF_TOKEN_CREATE
BPF_PROG_STREAM_READ_BY_FD
BPF_PROG_ASSOC_STRUCT_OPS
BPF_PROG_RUN = BPF_PROG_TEST_RUN
)
// BPFProgramType represents an type for an eBPF program.
type BPFProgramType uint
// Valid types of eBPF programs.
const (
BPF_PROG_TYPE_UNSPEC BPFProgramType = iota
BPF_PROG_TYPE_SOCKET_FILTER
BPF_PROG_TYPE_KPROBE
BPF_PROG_TYPE_SCHED_CLS
BPF_PROG_TYPE_SCHED_ACT
BPF_PROG_TYPE_TRACEPOINT
BPF_PROG_TYPE_XDP
BPF_PROG_TYPE_PERF_EVENT
BPF_PROG_TYPE_CGROUP_SKB
BPF_PROG_TYPE_CGROUP_SOCK
BPF_PROG_TYPE_LWT_IN
BPF_PROG_TYPE_LWT_OUT
BPF_PROG_TYPE_LWT_XMIT
BPF_PROG_TYPE_SOCK_OPS
BPF_PROG_TYPE_SK_SKB
BPF_PROG_TYPE_CGROUP_DEVICE
BPF_PROG_TYPE_SK_MSG
BPF_PROG_TYPE_RAW_TRACEPOINT
BPF_PROG_TYPE_CGROUP_SOCK_ADDR
BPF_PROG_TYPE_LWT_SEG6LOCAL
BPF_PROG_TYPE_LIRC_MODE2
BPF_PROG_TYPE_SK_REUSEPORT
BPF_PROG_TYPE_FLOW_DISSECTOR
BPF_PROG_TYPE_CGROUP_SYSCTL
BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
BPF_PROG_TYPE_CGROUP_SOCKOPT
BPF_PROG_TYPE_TRACING
BPF_PROG_TYPE_STRUCT_OPS
BPF_PROG_TYPE_EXT
BPF_PROG_TYPE_LSM
BPF_PROG_TYPE_SK_LOOKUP
BPF_PROG_TYPE_SYSCALL
BPF_PROG_TYPE_NETFILTER
)
// BPFAttachType represents an attachment type for an eBPF program.
type BPFAttachType uint
// All valid attachment types for eBPF programs.
const (
BPF_CGROUP_INET_INGRESS BPFAttachType = iota
BPF_CGROUP_INET_EGRESS
BPF_CGROUP_INET_SOCK_CREATE
BPF_CGROUP_SOCK_OPS
BPF_SK_SKB_STREAM_PARSER
BPF_SK_SKB_STREAM_VERDICT
BPF_CGROUP_DEVICE
BPF_SK_MSG_VERDICT
BPF_CGROUP_INET4_BIND
BPF_CGROUP_INET6_BIND
BPF_CGROUP_INET4_CONNECT
BPF_CGROUP_INET6_CONNECT
BPF_CGROUP_INET4_POST_BIND
BPF_CGROUP_INET6_POST_BIND
BPF_CGROUP_UDP4_SENDMSG
BPF_CGROUP_UDP6_SENDMSG
BPF_LIRC_MODE2
BPF_FLOW_DISSECTOR
BPF_CGROUP_SYSCTL
BPF_CGROUP_UDP4_RECVMSG
BPF_CGROUP_UDP6_RECVMSG
BPF_CGROUP_GETSOCKOPT
BPF_CGROUP_SETSOCKOPT
BPF_TRACE_RAW_TP
BPF_TRACE_FENTRY
BPF_TRACE_FEXIT
BPF_MODIFY_RETURN
BPF_LSM_MAC
BPF_TRACE_ITER
BPF_CGROUP_INET4_GETPEERNAME
BPF_CGROUP_INET6_GETPEERNAME
BPF_CGROUP_INET4_GETSOCKNAME
BPF_CGROUP_INET6_GETSOCKNAME
BPF_XDP_DEVMAP
BPF_CGROUP_INET_SOCK_RELEASE
BPF_XDP_CPUMAP
BPF_SK_LOOKUP
BPF_XDP
BPF_SK_SKB_VERDICT
BPF_SK_REUSEPORT_SELECT
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE
BPF_PERF_EVENT
BPF_TRACE_KPROBE_MULTI
BPF_LSM_CGROUP
BPF_STRUCT_OPS
BPF_NETFILTER
BPF_TCX_INGRESS
BPF_TCX_EGRESS
BPF_TRACE_UPROBE_MULTI
BPF_CGROUP_UNIX_CONNECT
BPF_CGROUP_UNIX_SENDMSG
BPF_CGROUP_UNIX_RECVMSG
BPF_CGROUP_UNIX_GETPEERNAME
BPF_CGROUP_UNIX_GETSOCKNAME
BPF_NETKIT_PRIMARY
BPF_NETKIT_PEER
BPF_TRACE_KPROBE_SESSION
BPF_TRACE_UPROBE_SESSION
BPF_TRACE_FSESSION
)
// BPFAttr represents the parameters to a bpf(2) call.
type BPFAttr interface {
marshal.Marshallable
implementsBPFAttr()
}
func (a *BPFAttrProgLoad) implementsBPFAttr() {}
func (a *BPFAttrProgQuery) implementsBPFAttr() {}
func (a *BPFAttrProgAttach) implementsBPFAttr() {}
// BPFAttrProgLoad contains parameters for a BPF_PROG_LOAD command.
//
// +marshal
type BPFAttrProgLoad struct {
_ structs.HostLayout
ProgType uint32
InstructionCount uint32
Instructions uint64
License uint64
LogLevel uint32
LogSize uint32
LogBuf uint64
KernVersion uint32
ProgFlags uint32
ProgName [BPF_OBJ_NAME_LEN]byte
ProgInterfaceIndex uint32
ExpectedAttachType uint32
ProgBTFFD uint32
FuncInfoRecSize uint32
FuncInfo uint64
FuncInfoCount uint32
LineInfoRecSize uint32
LineInfo uint64
LineInfoCount uint32
AttachBTFID uint32
AttachFD uint32 // union of either attach_prog_fd or attach_btf_obj_fd
CoreReloCount uint32
FDArray uint64
CoreRelos uint64
CoreReloRecSize uint32
LogTrueSize uint32
ProgTokenFD int32
FDArrayCount uint32
Signature uint64
SignatureSize uint32
KeyringID int32
}
// BPFAttrProgQuery contains parameters for a BPF_PROG_QUERY command.
//
// +marshal
type BPFAttrProgQuery struct {
_ structs.HostLayout
Target uint32 // union of either target_fd or target_ifindex
AttachType uint32
QueryFlags uint32
AttachFlags uint32
ProgIDs uint64
Count uint32 // union of either prog_cnt or count
_ uint32 // padding
ProgAttachFlags uint64
LinkIDs uint64
LinkAttachFlags uint64
Revision uint64
}
// BPFAttrProgAttach contains parameters for a BPF_PROG_ATTACH command.
//
// +marshal
type BPFAttrProgAttach struct {
_ structs.HostLayout
Target uint32 // union of either target_fd or target_ifindex
AttachBPFFD uint32
AttachType uint32
AttachFlags uint32
ReplaceBPFFD uint32
Relative uint32 // union of either relative_fd or relative_id
ExpectedRevision uint64
}
// BPF_ATTR_SIZE is the size of union bpf_attr, which is the largest of
// the sub-command attribute structures.
//
// BPF_ATTR_SIZE is immutable.
var BPF_ATTR_SIZE = max((*BPFAttrProgLoad)(nil).SizeBytes(), (*BPFAttrProgQuery)(nil).SizeBytes(), (*BPFAttrProgAttach)(nil).SizeBytes())
// eBPF-related flags
const (
BPF_F_ALLOW_OVERRIDE = 1 << iota
BPF_F_ALLOW_MULTI
BPF_F_REPLACE
BPF_F_BEFORE
BPF_F_AFTER
BPF_F_ID
BPF_F_PREORDER
BPF_F_LINK = 1 << 13
)

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Linux auxiliary vector entry types.
const (
// AT_NULL is the end of the auxiliary vector.
@ -111,6 +115,7 @@ const (
//
// +marshal
type ElfHeader64 struct {
_ structs.HostLayout
Ident [16]byte // File identification.
Type uint16 // File type.
Machine uint16 // Machine architecture.
@ -131,6 +136,7 @@ type ElfHeader64 struct {
//
// +marshal
type ElfSection64 struct {
_ structs.HostLayout
Name uint32 // Section name (index into the section header string table).
Type uint32 // Section type.
Flags uint64 // Section flags.
@ -147,6 +153,7 @@ type ElfSection64 struct {
//
// +marshal
type ElfProg64 struct {
_ structs.HostLayout
Type uint32 // Entry type.
Flags uint32 // Access permission flags.
Off uint64 // File offset of contents.

View file

@ -17,10 +17,15 @@
package linux
import (
"structs"
)
// EpollEvent is equivalent to struct epoll_event from epoll(2).
//
// +marshal slice:EpollEventSlice
type EpollEvent struct {
_ structs.HostLayout
Events uint32
// Linux makes struct epoll_event::data a __u64. We represent it as
// [2]int32 because, on amd64, Linux also makes struct epoll_event

View file

@ -17,10 +17,15 @@
package linux
import (
"structs"
)
// EpollEvent is equivalent to struct epoll_event from epoll(2).
//
// +marshal slice:EpollEventSlice
type EpollEvent struct {
_ structs.HostLayout
Events uint32
// Linux makes struct epoll_event a __u64, necessitating 4 bytes of padding
// here.

View file

@ -15,6 +15,8 @@
package linux
import (
"structs"
"github.com/sagernet/gvisor/pkg/marshal"
)
@ -31,6 +33,7 @@ const (
//
// +marshal
type SockExtendedErr struct {
_ structs.HostLayout
Errno uint32
Origin uint8
Type uint8
@ -54,6 +57,7 @@ type SockErrCMsg interface {
//
// +marshal
type SockErrCMsgIPv4 struct {
_ structs.HostLayout
SockExtendedErr
Offender SockAddrInet
}
@ -76,6 +80,7 @@ func (*SockErrCMsgIPv4) CMsgType() uint32 {
//
// +marshal
type SockErrCMsgIPv6 struct {
_ structs.HostLayout
SockExtendedErr
Offender SockAddrInet6
}

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Commands from linux/fcntl.h.
const (
F_DUPFD = 0
@ -54,6 +58,7 @@ const (
//
// +marshal
type Flock struct {
_ structs.HostLayout
Type int16
Whence int16
_ [4]byte
@ -74,6 +79,7 @@ const (
//
// +marshal
type FOwnerEx struct {
_ structs.HostLayout
Type int32
PID int32
}

View file

@ -17,6 +17,7 @@ package linux
import (
"fmt"
"strings"
"structs"
"github.com/sagernet/gvisor/pkg/abi"
)
@ -42,6 +43,20 @@ const (
O_TMPFILE = 0o20000000 // __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 fstatat(2).
const (
AT_SYMLINK_NOFOLLOW = 0x100
@ -85,6 +100,64 @@ const (
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
@ -265,6 +338,7 @@ const (
STATX_BLOCKS = 0x00000400
STATX_BASIC_STATS = 0x000007ff
STATX_BTIME = 0x00000800
STATX_MNT_ID = 0x00001000
STATX_ALL = 0x00000fff
STATX__RESERVED = 0x80000000
)
@ -284,6 +358,7 @@ const (
//
// +marshal boundCheck slice:StatxSlice
type Statx struct {
_ structs.HostLayout
Mask uint32
Blksize uint32
Attributes uint64
@ -304,12 +379,13 @@ type Statx struct {
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}",
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)
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.
@ -340,6 +416,19 @@ 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

View file

@ -17,6 +17,10 @@
package linux
import (
"structs"
)
// Constants for open(2).
const (
O_DIRECT = 0o00040000
@ -29,6 +33,7 @@ const (
//
// +marshal
type Stat struct {
_ structs.HostLayout
Dev uint64
Ino uint64
Nlink uint64

View file

@ -17,6 +17,10 @@
package linux
import (
"structs"
)
// Constants for open(2).
const (
O_DIRECTORY = 0o00040000
@ -29,6 +33,7 @@ const (
//
// +marshal
type Stat struct {
_ structs.HostLayout
Dev uint64
Ino uint64
Mode uint32

View file

@ -14,12 +14,20 @@
package linux
import (
"math"
"structs"
"github.com/sagernet/gvisor/pkg/hostarch"
)
// Filesystem types used in statfs(2).
//
// See linux/magic.h.
const (
ANON_INODE_FS_MAGIC = 0x09041934
CGROUP_SUPER_MAGIC = 0x27e0eb
CGROUP2_SUPER_MAGIC = 0x63677270
DEVPTS_SUPER_MAGIC = 0x00001cd1
EXT_SUPER_MAGIC = 0xef53
FUSE_SUPER_MAGIC = 0x65735546
@ -60,6 +68,7 @@ const (
//
// +marshal
type Statfs struct {
_ structs.HostLayout
// Type is one of the filesystem magic values, defined above.
Type uint64
@ -127,3 +136,8 @@ const (
WHITEOUT_MODE = 0
WHITEOUT_DEV = 0
)
// MAX_RW_COUNT is the maximum size in bytes of a single read or write.
// Reads and writes that exceed this size may be truncated.
// (Linux: include/linux/fs.h:MAX_RW_COUNT)
var MAX_RW_COUNT = int(hostarch.PageRoundDown(uint32(math.MaxInt32)))

View file

@ -15,6 +15,7 @@
package linux
import (
"structs"
"time"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
@ -93,6 +94,7 @@ const (
// +marshal
// +stateify savable
type FUSEHeaderIn struct {
_ structs.HostLayout
// Len specifies the total length of the data, including this header.
Len uint32
@ -127,6 +129,7 @@ var SizeOfFUSEHeaderIn = uint32((*FUSEHeaderIn)(nil).SizeBytes())
// +marshal
// +stateify savable
type FUSEHeaderOut struct {
_ structs.HostLayout
// Len specifies the total length of the data, including this header.
Len uint32
@ -172,9 +175,10 @@ const (
// Constants relevant to FUSE operations.
const (
FUSE_NAME_MAX = 1024
FUSE_PAGE_SIZE = 4096
FUSE_DIRENT_ALIGN = 8
FUSE_NAME_MAX = 1024
FUSE_PAGE_SIZE = 4096
FUSE_DIRENT_ALIGN = 8
FUSE_FSYNC_FDATASYNC = 1 << 0
)
// FUSEInitIn is the request sent by the kernel to the daemon,
@ -182,6 +186,7 @@ const (
//
// +marshal
type FUSEInitIn struct {
_ structs.HostLayout
// Major version supported by kernel.
Major uint32
@ -201,6 +206,7 @@ type FUSEInitIn struct {
//
// +marshal
type FUSEInitOut struct {
_ structs.HostLayout
// Major version supported by daemon.
Major uint32
@ -249,6 +255,7 @@ type FUSEInitOut struct {
//
// +marshal
type FUSEStatfsOut struct {
_ structs.HostLayout
// Blocks is the maximum number of data blocks the filesystem may store, in
// units of BlockSize.
Blocks uint64
@ -290,6 +297,7 @@ const FUSE_GETATTR_FH = (1 << 0)
//
// +marshal
type FUSEGetAttrIn struct {
_ structs.HostLayout
// GetAttrFlags specifies whether getattr request is sent with a nodeid or
// with a file handle.
GetAttrFlags uint32
@ -305,6 +313,7 @@ type FUSEGetAttrIn struct {
//
// +marshal
type FUSEAttr struct {
_ structs.HostLayout
// Ino is the inode number of this file.
Ino uint64
@ -376,6 +385,7 @@ func (a FUSEAttr) CTimeNsec() int64 {
//
// +marshal
type FUSEAttrOut struct {
_ structs.HostLayout
// AttrValid and AttrValidNsec describe the attribute cache duration
AttrValid uint64
@ -394,6 +404,7 @@ type FUSEAttrOut struct {
//
// +marshal
type FUSEEntryOut struct {
_ structs.HostLayout
// NodeID is the ID for current inode.
NodeID uint64
@ -445,6 +456,7 @@ func (s *CString) SizeBytes() int {
//
// +marshal dynamic
type FUSELookupIn struct {
_ structs.HostLayout
// Name is a file name to be looked up.
Name CString
}
@ -475,6 +487,12 @@ const (
FOPEN_KEEP_CACHE = 1 << 1
// FOPEN_NONSEEKABLE indicates the file cannot be seeked.
FOPEN_NONSEEKABLE = 1 << 2
// FOPEN_CACHE_DIR indicated to allow caching this directory
FOPEN_CACHE_DIR = 1 << 3
// FOPEN_STREAM indicates the file is stream-like (no file position at all)
FOPEN_STREAM = 1 << 4
// FOPEN_NOFLUSH indicates the file does not need to be flushed on close.
FOPEN_NOFLUSH = 1 << 5
)
// FUSEOpenIn is the request sent by the kernel to the daemon,
@ -482,6 +500,7 @@ const (
//
// +marshal
type FUSEOpenIn struct {
_ structs.HostLayout
// Flags of this open request.
Flags uint32
@ -493,6 +512,7 @@ type FUSEOpenIn struct {
//
// +marshal
type FUSEOpenOut struct {
_ structs.HostLayout
// Fh is the file handler for opened files.
Fh uint64
@ -507,6 +527,7 @@ type FUSEOpenOut struct {
//
// +marshal
type FUSECreateOut struct {
_ structs.HostLayout
FUSEEntryOut
FUSEOpenOut
}
@ -521,6 +542,7 @@ const (
//
// +marshal
type FUSEReadIn struct {
_ structs.HostLayout
// Fh is the file handle in userspace.
Fh uint64
@ -553,6 +575,7 @@ type FUSEReadIn struct {
//
// +marshal
type FUSEWriteIn struct {
_ structs.HostLayout
// Fh is the file handle in userspace.
Fh uint64
@ -583,8 +606,9 @@ var SizeOfFUSEWriteIn = uint32((*FUSEWriteIn)(nil).SizeBytes())
//
// +marshal dynamic
type FUSEWritePayloadIn struct {
_ structs.HostLayout
Header FUSEWriteIn
Payload primitive.ByteSlice
Payload primitive.ByteSlice `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -612,6 +636,7 @@ func (r *FUSEWritePayloadIn) UnmarshalBytes(src []byte) []byte {
//
// +marshal
type FUSEWriteOut struct {
_ structs.HostLayout
// Size is the number of bytes written.
Size uint32
@ -623,6 +648,7 @@ type FUSEWriteOut struct {
//
// +marshal
type FUSEReleaseIn struct {
_ structs.HostLayout
// Fh is the file handler for the file to be released.
Fh uint64
@ -641,6 +667,7 @@ type FUSEReleaseIn struct {
//
// +marshal
type FUSECreateMeta struct {
_ structs.HostLayout
// Flags of the creating file.
Flags uint32
@ -656,6 +683,7 @@ type FUSECreateMeta struct {
//
// +marshal dynamic
type FUSERenameIn struct {
_ structs.HostLayout
Newdir primitive.Uint64
Oldname CString
Newname CString
@ -683,6 +711,7 @@ func (r *FUSERenameIn) SizeBytes() int {
//
// +marshal dynamic
type FUSECreateIn struct {
_ structs.HostLayout
// CreateMeta contains mode, rdev and umash fields for FUSE_MKNODS.
CreateMeta FUSECreateMeta
@ -711,6 +740,7 @@ func (r *FUSECreateIn) SizeBytes() int {
//
// +marshal
type FUSEMknodMeta struct {
_ structs.HostLayout
// Mode of the inode to create.
Mode uint32
@ -728,6 +758,7 @@ type FUSEMknodMeta struct {
//
// +marshal dynamic
type FUSEMknodIn struct {
_ structs.HostLayout
// MknodMeta contains mode, rdev and umash fields for FUSE_MKNODS.
MknodMeta FUSEMknodMeta
// Name is the name of the node to create.
@ -755,6 +786,7 @@ func (r *FUSEMknodIn) SizeBytes() int {
//
// +marshal dynamic
type FUSESymlinkIn struct {
_ structs.HostLayout
// Name of symlink to create.
Name CString
@ -782,6 +814,7 @@ func (r *FUSESymlinkIn) SizeBytes() int {
//
// +marshal dynamic
type FUSELinkIn struct {
_ structs.HostLayout
// OldNodeID is the ID of the inode that is being linked to.
OldNodeID primitive.Uint64
// Name of the new hard link to create.
@ -807,7 +840,9 @@ func (r *FUSELinkIn) SizeBytes() int {
// FUSEEmptyIn is used by operations without request body.
//
// +marshal dynamic
type FUSEEmptyIn struct{}
type FUSEEmptyIn struct {
_ structs.HostLayout
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (r *FUSEEmptyIn) MarshalBytes(buf []byte) []byte {
@ -829,6 +864,7 @@ func (r *FUSEEmptyIn) SizeBytes() int {
//
// +marshal
type FUSEMkdirMeta struct {
_ structs.HostLayout
// Mode of the directory of create.
Mode uint32
// Umask is the user file creation mask.
@ -840,6 +876,7 @@ type FUSEMkdirMeta struct {
//
// +marshal dynamic
type FUSEMkdirIn struct {
_ structs.HostLayout
// MkdirMeta contains Mode and Umask of the directory to create.
MkdirMeta FUSEMkdirMeta
// Name of the directory to create.
@ -867,6 +904,7 @@ func (r *FUSEMkdirIn) SizeBytes() int {
//
// +marshal dynamic
type FUSERmDirIn struct {
_ structs.HostLayout
// Name is a directory name to be removed.
Name CString
}
@ -886,12 +924,94 @@ func (r *FUSERmDirIn) SizeBytes() int {
return r.Name.SizeBytes()
}
// FUSEGetXattrHdr contains the static fields of FUSEGetXattrIn.
//
// +marshal
type FUSEGetXattrHdr struct {
_ structs.HostLayout
Size uint32
_ uint32
}
// FUSEGetXattrIn contains the arguments for FUSE_GETXATTR.
//
// +marshal dynamic
type FUSEGetXattrIn struct {
_ structs.HostLayout
Hdr FUSEGetXattrHdr
Name CString
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (r *FUSEGetXattrIn) MarshalBytes(buf []byte) []byte {
buf = r.Hdr.MarshalBytes(buf)
return r.Name.MarshalBytes(buf)
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (r *FUSEGetXattrIn) UnmarshalBytes(buf []byte) []byte {
panic("Unimplemented, FUSEGetXattrIn is never unmarshalled")
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (r *FUSEGetXattrIn) SizeBytes() int {
return r.Hdr.SizeBytes() + r.Name.SizeBytes()
}
// FUSEGetXattrOut is the reply sent by the daemon to the kernel
// for FUSE_GETXATTR and FUSE_LISTXATTR when the input size was 0.
//
// +marshal
type FUSEGetXattrOut struct {
_ structs.HostLayout
Size uint32
_ uint32
}
// FUSESetXattrHdr contains the static fields of FUSESetXattrIn.
//
// +marshal
type FUSESetXattrHdr struct {
_ structs.HostLayout
Size uint32
Flags uint32
}
// FUSESetXattrIn contains the arguments for FUSE_SETXATTR.
//
// +marshal dynamic
type FUSESetXattrIn struct {
_ structs.HostLayout
Hdr FUSESetXattrHdr
Name CString
Value []byte `hostlayout:"ignore"`
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (r *FUSESetXattrIn) MarshalBytes(buf []byte) []byte {
buf = r.Hdr.MarshalBytes(buf)
buf = r.Name.MarshalBytes(buf)
copy(buf, r.Value)
return buf[len(r.Value):]
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (r *FUSESetXattrIn) UnmarshalBytes(buf []byte) []byte {
panic("Unimplemented, FUSESetXattrIn is never unmarshalled")
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (r *FUSESetXattrIn) SizeBytes() int {
return r.Hdr.SizeBytes() + r.Name.SizeBytes() + len(r.Value)
}
// FUSEDirents is a list of Dirents received from the FUSE daemon server.
// It is used for FUSE_READDIR.
//
// +marshal dynamic
type FUSEDirents struct {
Dirents []*FUSEDirent
_ structs.HostLayout
Dirents []*FUSEDirent `hostlayout:"ignore"`
}
// FUSEDirent is a Dirent received from the FUSE daemon server.
@ -899,10 +1019,11 @@ type FUSEDirents struct {
//
// +marshal dynamic
type FUSEDirent struct {
_ structs.HostLayout
// Meta contains all the static fields of FUSEDirent.
Meta FUSEDirentMeta
// Name is the filename of the dirent.
Name string
Name string `hostlayout:"ignore"`
}
// FUSEDirentMeta contains all the static fields of FUSEDirent.
@ -910,6 +1031,7 @@ type FUSEDirent struct {
//
// +marshal
type FUSEDirentMeta struct {
_ structs.HostLayout
// Inode of the dirent.
Ino uint64
// Offset of the dirent.
@ -937,23 +1059,17 @@ func (r *FUSEDirents) MarshalBytes(buf []byte) []byte {
// UnmarshalBytes deserializes FUSEDirents from the src buffer.
func (r *FUSEDirents) UnmarshalBytes(src []byte) []byte {
for {
if len(src) <= (*FUSEDirentMeta)(nil).SizeBytes() {
for len(src) >= (*FUSEDirentMeta)(nil).SizeBytes() {
var dirent FUSEDirent
rem := dirent.UnmarshalBytes(src)
if len(rem) == len(src) || len(dirent.Name) == 0 {
break
}
// Its unclear how many dirents there are in src. Each dirent is dynamically
// sized and so we can't make assumptions about how many dirents we can allocate.
if r.Dirents == nil {
r.Dirents = make([]*FUSEDirent, 0)
}
// We have to allocate a struct for each dirent - there must be a better way
// to do this. Linux allocates 1 page to store all the dirents and then
// simply reads them from the page.
var dirent FUSEDirent
src = dirent.UnmarshalBytes(src)
r.Dirents = append(r.Dirents, &dirent)
src = rem
}
return src
}
@ -985,12 +1101,18 @@ func (r *FUSEDirent) shiftNextDirent(buf []byte) []byte {
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (r *FUSEDirent) UnmarshalBytes(src []byte) []byte {
if len(src) < (*FUSEDirentMeta)(nil).SizeBytes() {
return src
}
srcP := r.Meta.UnmarshalBytes(src)
if r.Meta.NameLen > FUSE_NAME_MAX || r.Meta.NameLen > uint32(len(srcP)) {
// The name is too long and therefore invalid. We don't
// need to unmarshal the name since it'll be thrown away.
return r.shiftNextDirent(src)
// Calculate the 8-byte aligned size of this directory entry record.
recLen := (r.Meta.SizeBytes() + int(r.Meta.NameLen) + (FUSE_DIRENT_ALIGN - 1)) & ^(FUSE_DIRENT_ALIGN - 1)
// If the name is invalid or if the record straddles the end of the source
// buffer (making it incomplete), return the buffer unconsumed. This leaves
// the offset at the start of this entry so it can be re-fetched whole.
if r.Meta.NameLen == 0 || r.Meta.NameLen > FUSE_NAME_MAX || recLen > len(src) {
return src
}
buf := make([]byte, r.Meta.NameLen)
@ -1021,6 +1143,7 @@ const (
//
// +marshal
type FUSESetAttrIn struct {
_ structs.HostLayout
// Valid indicates which attributes are modified by this request.
Valid uint32
@ -1072,6 +1195,7 @@ type FUSESetAttrIn struct {
//
// +marshal dynamic
type FUSEUnlinkIn struct {
_ structs.HostLayout
// Name of the node to unlink.
Name CString
}
@ -1096,6 +1220,7 @@ func (r *FUSEUnlinkIn) SizeBytes() int {
//
// +marshal
type FUSEFsyncIn struct {
_ structs.HostLayout
Fh uint64
FsyncFlags uint32
@ -1109,6 +1234,7 @@ type FUSEFsyncIn struct {
//
// +marshal
type FUSEAccessIn struct {
_ structs.HostLayout
Mask uint32
// padding
_ uint32
@ -1119,6 +1245,7 @@ type FUSEAccessIn struct {
//
// +marshal
type FUSEFallocateIn struct {
_ structs.HostLayout
Fh uint64
Offset uint64
Length uint64
@ -1132,6 +1259,7 @@ type FUSEFallocateIn struct {
//
// +marshal
type FUSEFlushIn struct {
_ structs.HostLayout
Fh uint64
_ uint32 // unused
_ uint32 // padding

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// From <linux/futex.h> and <sys/time.h>.
// Flags are used in syscall futex(2).
const (
@ -71,6 +75,7 @@ const ROBUST_LIST_LIMIT = 2048
//
// +marshal
type RobustListHead struct {
_ structs.HostLayout
List uint64
FutexOffset uint64
ListOpPending uint64

View file

@ -19,9 +19,13 @@ package linux
// These are ordered by request number (low byte).
const (
TCGETS = 0x00005401
TCGETS2 = 0x802c542a
TCSETS = 0x00005402
TCSETS2 = 0x402c542b
TCSETSW = 0x00005403
TCSETSW2 = 0x402c542c
TCSETSF = 0x00005404
TCSETSF2 = 0x402c542d
TCSBRK = 0x00005409
TIOCEXCL = 0x0000540c
TIOCNXCL = 0x0000540d
@ -56,7 +60,7 @@ const (
TIOCCONS = 0x0000541d
TIOCSSERIAL = 0x0000541f
TIOCGEXCL = 0x80045440
TIOCGPTPEER = 0x80045441
TIOCGPTPEER = 0x00005441
TIOCGICOUNT = 0x0000545d
FIONCLEX = 0x00005450
FIOCLEX = 0x00005451
@ -152,6 +156,13 @@ func IOC_SIZE(nr uint32) uint32 {
return (nr >> IOC_SIZESHIFT) & ((1 << IOC_SIZEBITS) - 1)
}
// TCFLSH queue selector arguments.
const (
TCIFLUSH = 0
TCOFLUSH = 1
TCIOFLUSH = 2
)
/* Used for packet mode */
const (
TIOCPKT_DATA = 0
@ -184,3 +195,15 @@ const (
KCOV_MODE_TRACE_PC = 2
KCOV_MODE_TRACE_CMP = 3
)
// File clone/dedup ioctls from include/uapi/linux/fs.h.
var (
FICLONE = IOW(0x94, 9, 4)
FICLONERANGE = IOW(0x94, 13, 32)
FIDEDUPERANGE = IOWR(0x94, 54, 24)
)
// FUSE_DEV_IOC_CLONE from include/uapi/linux/fuse.h.
var (
FUSE_DEV_IOC_CLONE = IOR(229, 0, 4)
)

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h.
const (
IORING_SETUP_IOPOLL = (1 << 0)
@ -75,6 +79,7 @@ type IORingIndex uint32
//
// +marshal
type IOSqRingOffsets struct {
_ structs.HostLayout
Head uint32 // Offset to io_rings.sq.head
Tail uint32 // Offset to io_rings.sq.tail
RingMask uint32 // Offset to io_rings.sq_ring_mask
@ -92,6 +97,7 @@ type IOSqRingOffsets struct {
//
// +marshal
type IOCqRingOffsets struct {
_ structs.HostLayout
Head uint32 // Offset to io_rings.cq.head
Tail uint32 // Offset to io_rings.cq.tail
RingMask uint32 // Offset to io_rings.cq_ring_mask
@ -108,6 +114,7 @@ type IOCqRingOffsets struct {
//
// +marshal
type IOUringParams struct {
_ structs.HostLayout
SqEntries uint32
CqEntries uint32
Flags uint32
@ -128,6 +135,7 @@ type IOUringParams struct {
// +marshal
// +stateify savable
type IOUringCqe struct {
_ structs.HostLayout
UserData uint64
Res int32
Flags uint32
@ -139,6 +147,7 @@ type IOUringCqe struct {
// +marshal
// +stateify savable
type IOUring struct {
_ structs.HostLayout
// Both head and tail should be cacheline aligned. And we assume that
// cacheline size is 64 bytes.
Head uint32
@ -154,6 +163,7 @@ type IOUring struct {
// +marshal
// +stateify savable
type IORings struct {
_ structs.HostLayout
Sq IOUring
Cq IOUring
SqRingMask uint32
@ -177,6 +187,7 @@ type IORings struct {
// +marshal
// +stateify savable
type IOUringSqe struct {
_ structs.HostLayout
Opcode uint8
Flags uint8
IoPrio uint16

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Control commands used with semctl, shmctl, and msgctl.
//
// Source: include/uapi/linux/ipc.h.
@ -46,6 +50,7 @@ const (
//
// +marshal
type IPCPerm struct {
_ structs.HostLayout
Key uint32
UID uint32
GID uint32

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Resources for getrlimit(2)/setrlimit(2)/prlimit(2).
const (
RLIMIT_CPU = 0
@ -36,6 +40,7 @@ const (
// RLimit corresponds to Linux's struct rlimit.
type RLimit struct {
_ structs.HostLayout
// Cur specifies the soft limit.
Cur uint64
// Max specifies the hard limit.
@ -69,20 +74,20 @@ const (
// InitRLimits is a map of initial rlimits set by Linux in
// include/asm-generic/resource.h.
var InitRLimits = map[int]RLimit{
RLIMIT_CPU: {RLimInfinity, RLimInfinity},
RLIMIT_FSIZE: {RLimInfinity, RLimInfinity},
RLIMIT_DATA: {RLimInfinity, RLimInfinity},
RLIMIT_STACK: {DefaultStackSoftLimit, RLimInfinity},
RLIMIT_CORE: {0, RLimInfinity},
RLIMIT_RSS: {RLimInfinity, RLimInfinity},
RLIMIT_NPROC: {DefaultNprocLimit, DefaultNprocLimit},
RLIMIT_NOFILE: {DefaultNofileSoftLimit, DefaultNofileHardLimit},
RLIMIT_MEMLOCK: {DefaultMemlockLimit, DefaultMemlockLimit},
RLIMIT_AS: {RLimInfinity, RLimInfinity},
RLIMIT_LOCKS: {RLimInfinity, RLimInfinity},
RLIMIT_SIGPENDING: {0, 0},
RLIMIT_MSGQUEUE: {DefaultMsgqueueLimit, DefaultMsgqueueLimit},
RLIMIT_NICE: {0, 0},
RLIMIT_RTPRIO: {0, 0},
RLIMIT_RTTIME: {RLimInfinity, RLimInfinity},
RLIMIT_CPU: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_FSIZE: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_DATA: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_STACK: {Cur: DefaultStackSoftLimit, Max: RLimInfinity},
RLIMIT_CORE: {Cur: 0, Max: RLimInfinity},
RLIMIT_RSS: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_NPROC: {Cur: DefaultNprocLimit, Max: DefaultNprocLimit},
RLIMIT_NOFILE: {Cur: DefaultNofileSoftLimit, Max: DefaultNofileHardLimit},
RLIMIT_MEMLOCK: {Cur: DefaultMemlockLimit, Max: DefaultMemlockLimit},
RLIMIT_AS: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_LOCKS: {Cur: RLimInfinity, Max: RLimInfinity},
RLIMIT_SIGPENDING: {Cur: 0, Max: 0},
RLIMIT_MSGQUEUE: {Cur: DefaultMsgqueueLimit, Max: DefaultMsgqueueLimit},
RLIMIT_NICE: {Cur: 0, Max: 0},
RLIMIT_RTPRIO: {Cur: 0, Max: 0},
RLIMIT_RTTIME: {Cur: RLimInfinity, Max: RLimInfinity},
}

View file

@ -16,6 +16,10 @@
// Linux kernel.
package linux
import (
"structs"
)
// NumSoftIRQ is the number of software IRQs, exposed via /proc/stat.
//
// Defined in linux/interrupt.h.
@ -25,6 +29,7 @@ const NumSoftIRQ = 10
//
// +marshal
type Sysinfo struct {
_ structs.HostLayout
Uptime int64
Loads [3]uint64
TotalRAM uint64

File diff suppressed because it is too large Load diff

View file

@ -216,6 +216,56 @@ func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
return src[size*count:]
}
// ReadEpollEventSlice reads a []EpollEvent. It returns the number of bytes read
func ReadEpollEventSlice(src io.Reader, dst []EpollEvent) (int, error) {
count := len(dst)
if count == 0 {
return 0, nil
}
size := (*EpollEvent)(nil).SizeBytes()
ptr := unsafe.Pointer(&dst)
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(val)
hdr.Len = size * count
hdr.Cap = size * count
length, err := io.ReadFull(src, buf)
// Since we bypassed the compiler's escape analysis, indicate that dst
// must live until the use above.
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
return length, err
}
// WriteEpollEventSlice is like EpollEvent.WriteTo, but for a []EpollEvent.
func WriteEpollEventSlice(dst io.Writer, src []EpollEvent) (int, error) {
count := len(src)
if count == 0 {
return 0, nil
}
size := (*EpollEvent)(nil).SizeBytes()
ptr := unsafe.Pointer(&src)
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(val)
hdr.Len = size * count
hdr.Cap = size * count
length, err := dst.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that src
// must live until the use above.
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
return length, err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *Stat) SizeBytes() int {
return 72 +

View file

@ -220,6 +220,56 @@ func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
return src[size*count:]
}
// ReadEpollEventSlice reads a []EpollEvent. It returns the number of bytes read
func ReadEpollEventSlice(src io.Reader, dst []EpollEvent) (int, error) {
count := len(dst)
if count == 0 {
return 0, nil
}
size := (*EpollEvent)(nil).SizeBytes()
ptr := unsafe.Pointer(&dst)
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(val)
hdr.Len = size * count
hdr.Cap = size * count
length, err := io.ReadFull(src, buf)
// Since we bypassed the compiler's escape analysis, indicate that dst
// must live until the use above.
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
return length, err
}
// WriteEpollEventSlice is like EpollEvent.WriteTo, but for a []EpollEvent.
func WriteEpollEventSlice(dst io.Writer, src []EpollEvent) (int, error) {
count := len(src)
if count == 0 {
return 0, nil
}
size := (*EpollEvent)(nil).SizeBytes()
ptr := unsafe.Pointer(&src)
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(val)
hdr.Len = size * count
hdr.Cap = size * count
length, err := dst.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that src
// must live until the use above.
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
return length, err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *Stat) SizeBytes() int {
return 72 +

View file

@ -76,6 +76,40 @@ func (b *BPFInstruction) StateLoad(ctx context.Context, stateSourceObject state.
stateSourceObject.Load(3, &b.K)
}
func (e *EBPFInstruction) StateTypeName() string {
return "pkg/abi/linux.EBPFInstruction"
}
func (e *EBPFInstruction) StateFields() []string {
return []string{
"Code",
"Registers",
"Offset",
"Immediate",
}
}
func (e *EBPFInstruction) beforeSave() {}
// +checklocksignore
func (e *EBPFInstruction) StateSave(stateSinkObject state.Sink) {
e.beforeSave()
stateSinkObject.Save(0, &e.Code)
stateSinkObject.Save(1, &e.Registers)
stateSinkObject.Save(2, &e.Offset)
stateSinkObject.Save(3, &e.Immediate)
}
func (e *EBPFInstruction) afterLoad(context.Context) {}
// +checklocksignore
func (e *EBPFInstruction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &e.Code)
stateSourceObject.Load(1, &e.Registers)
stateSourceObject.Load(2, &e.Offset)
stateSourceObject.Load(3, &e.Immediate)
}
func (f *FUSEHeaderIn) StateTypeName() string {
return "pkg/abi/linux.FUSEHeaderIn"
}
@ -505,6 +539,40 @@ func (i *ICMP6Filter) StateLoad(ctx context.Context, stateSourceObject state.Sou
stateSourceObject.Load(0, &i.Filter)
}
func (w *Winsize) StateTypeName() string {
return "pkg/abi/linux.Winsize"
}
func (w *Winsize) StateFields() []string {
return []string{
"Row",
"Col",
"Xpixel",
"Ypixel",
}
}
func (w *Winsize) beforeSave() {}
// +checklocksignore
func (w *Winsize) StateSave(stateSinkObject state.Sink) {
w.beforeSave()
stateSinkObject.Save(0, &w.Row)
stateSinkObject.Save(1, &w.Col)
stateSinkObject.Save(2, &w.Xpixel)
stateSinkObject.Save(3, &w.Ypixel)
}
func (w *Winsize) afterLoad(context.Context) {}
// +checklocksignore
func (w *Winsize) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &w.Row)
stateSourceObject.Load(1, &w.Col)
stateSourceObject.Load(2, &w.Xpixel)
stateSourceObject.Load(3, &w.Ypixel)
}
func (t *KernelTermios) StateTypeName() string {
return "pkg/abi/linux.KernelTermios"
}
@ -551,37 +619,10 @@ func (t *KernelTermios) StateLoad(ctx context.Context, stateSourceObject state.S
stateSourceObject.Load(7, &t.OutputSpeed)
}
func (w *WindowSize) StateTypeName() string {
return "pkg/abi/linux.WindowSize"
}
func (w *WindowSize) StateFields() []string {
return []string{
"Rows",
"Cols",
}
}
func (w *WindowSize) beforeSave() {}
// +checklocksignore
func (w *WindowSize) StateSave(stateSinkObject state.Sink) {
w.beforeSave()
stateSinkObject.Save(0, &w.Rows)
stateSinkObject.Save(1, &w.Cols)
}
func (w *WindowSize) afterLoad(context.Context) {}
// +checklocksignore
func (w *WindowSize) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &w.Rows)
stateSourceObject.Load(1, &w.Cols)
}
func init() {
state.Register((*IOEvent)(nil))
state.Register((*BPFInstruction)(nil))
state.Register((*EBPFInstruction)(nil))
state.Register((*FUSEHeaderIn)(nil))
state.Register((*FUSEHeaderOut)(nil))
state.Register((*IOUringCqe)(nil))
@ -594,6 +635,6 @@ func init() {
state.Register((*ControlMessageIPPacketInfo)(nil))
state.Register((*ControlMessageIPv6PacketInfo)(nil))
state.Register((*ICMP6Filter)(nil))
state.Register((*Winsize)(nil))
state.Register((*KernelTermios)(nil))
state.Register((*WindowSize)(nil))
}

View file

@ -1,3 +0,0 @@
// Automatically generated marshal implementation. See tools/go_marshal.
package linux

View file

@ -1,3 +0,0 @@
// automatically generated by stateify.
package linux

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Default values for POSIX message queues. Source:
// include/linux/ipc_namespace.h
const (
@ -47,6 +51,7 @@ const (
//
// +marshal
type MqAttr struct {
_ structs.HostLayout
MqFlags int64 // Message queue flags.
MqMaxmsg int64 // Maximum number of messages.
MqMsgsize int64 // Maximum message size.

View file

@ -15,6 +15,8 @@
package linux
import (
"structs"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
)
@ -55,6 +57,7 @@ const (
//
// +marshal
type MsqidDS struct {
_ structs.HostLayout
MsgPerm IPCPerm // IPC permissions.
MsgStime TimeT // Last msgsnd time.
MsgRtime TimeT // Last msgrcv time.
@ -72,8 +75,9 @@ type MsqidDS struct {
//
// +marshal dynamic
type MsgBuf struct {
_ structs.HostLayout
Type primitive.Int64
Text primitive.ByteSlice
Text primitive.ByteSlice `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -97,6 +101,7 @@ func (b *MsgBuf) UnmarshalBytes(src []byte) []byte {
//
// +marshal
type MsgInfo struct {
_ structs.HostLayout
MsgPool int32
MsgMap int32
MsgMax int32

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
const (
// IFNAMSIZ is the size of the name field for IFReq.
IFNAMSIZ = 16
@ -23,6 +27,7 @@ const (
//
// +marshal
type IFReq struct {
_ structs.HostLayout
// IFName is an encoded name, normally null-terminated. This should be
// accessed via the Name and SetName functions.
IFName [IFNAMSIZ]byte
@ -66,6 +71,7 @@ var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
// IFMap contains interface hardware parameters.
type IFMap struct {
_ structs.HostLayout
MemStart uint64
MemEnd uint64
BaseAddr int16
@ -80,6 +86,7 @@ type IFMap struct {
//
// +marshal
type IFConf struct {
_ structs.HostLayout
Len int32
_ [4]byte // Pad to sizeof(struct ifconf).
Ptr uint64
@ -106,6 +113,7 @@ const (
//
// +marshal
type EthtoolGFeatures struct {
_ structs.HostLayout
Cmd uint32
Size uint32
}
@ -116,6 +124,7 @@ type EthtoolGFeatures struct {
//
// +marshal
type EthtoolGetFeaturesBlock struct {
_ structs.HostLayout
Available uint32
Requested uint32
Active uint32

View file

@ -15,6 +15,8 @@
package linux
import (
"structs"
"github.com/sagernet/gvisor/pkg/marshal"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
)
@ -109,6 +111,7 @@ const (
//
// +marshal
type IPTEntry struct {
_ structs.HostLayout
// IP is used to filter packets based on the IP header.
IP IPTIP
@ -148,13 +151,14 @@ const SizeOfIPTEntry = 112
//
// +marshal dynamic
type KernelIPTEntry struct {
_ structs.HostLayout
Entry IPTEntry
// Elems holds the data for all this rule's matches followed by the
// target. It is variable length -- users have to iterate over any
// matches and use TargetOffset and NextOffset to make sense of the
// data.
Elems primitive.ByteSlice
Elems primitive.ByteSlice `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -182,6 +186,7 @@ var _ marshal.Marshallable = (*KernelIPTEntry)(nil)
//
// +marshal
type IPTIP struct {
_ structs.HostLayout
// Src is the source IP address.
Src InetAddr
@ -246,6 +251,7 @@ const SizeOfIPTIP = 84
//
// +marshal
type XTCounters struct {
_ structs.HostLayout
// Pcnt is the packet count.
Pcnt uint64
@ -267,6 +273,7 @@ const SizeOfXTCounters = 16
//
// +marshal
type XTEntryMatch struct {
_ structs.HostLayout
MatchSize uint16
Name ExtensionName
Revision uint8
@ -281,8 +288,9 @@ const SizeOfXTEntryMatch = 32
// KernelXTEntryMatch is identical to XTEntryMatch, but contains
// variable-length Data field.
type KernelXTEntryMatch struct {
_ structs.HostLayout
XTEntryMatch
Data []byte
Data []byte `hostlayout:"ignore"`
}
// XTGetRevision corresponds to xt_get_revision in
@ -290,6 +298,7 @@ type KernelXTEntryMatch struct {
//
// +marshal
type XTGetRevision struct {
_ structs.HostLayout
Name ExtensionName
Revision uint8
}
@ -308,6 +317,7 @@ const SizeOfXTGetRevision = 30
//
// +marshal
type XTEntryTarget struct {
_ structs.HostLayout
TargetSize uint16
Name ExtensionName
Revision uint8
@ -322,8 +332,9 @@ const SizeOfXTEntryTarget = 32
// KernelXTEntryTarget is identical to XTEntryTarget, but contains a
// variable-length Data field.
type KernelXTEntryTarget struct {
_ structs.HostLayout
XTEntryTarget
Data []byte
Data []byte `hostlayout:"ignore"`
}
// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
@ -332,6 +343,7 @@ type KernelXTEntryTarget struct {
//
// +marshal
type XTStandardTarget struct {
_ structs.HostLayout
Target XTEntryTarget
// A positive verdict indicates a jump, and is the offset from the
// start of the table to jump to. A negative value means one of the
@ -350,6 +362,7 @@ const SizeOfXTStandardTarget = 40
//
// +marshal
type XTErrorTarget struct {
_ structs.HostLayout
Target XTEntryTarget
Name ErrorName
_ [2]byte
@ -379,6 +392,7 @@ const (
//
// +marshal
type NfNATIPV4Range struct {
_ structs.HostLayout
Flags uint32
MinIP [4]byte
MaxIP [4]byte
@ -391,6 +405,7 @@ type NfNATIPV4Range struct {
//
// +marshal
type NfNATIPV4MultiRangeCompat struct {
_ structs.HostLayout
RangeSize uint32
RangeIPV4 NfNATIPV4Range
}
@ -400,6 +415,7 @@ type NfNATIPV4MultiRangeCompat struct {
//
// +marshal
type XTRedirectTarget struct {
_ structs.HostLayout
Target XTEntryTarget
NfRange NfNATIPV4MultiRangeCompat
_ [4]byte
@ -413,6 +429,7 @@ const SizeOfXTRedirectTarget = 56
//
// +marshal
type XTNATTargetV0 struct {
_ structs.HostLayout
Target XTEntryTarget
NfRange NfNATIPV4MultiRangeCompat
_ [4]byte
@ -425,6 +442,7 @@ const SizeOfXTNATTargetV0 = 56
//
// +marshal
type XTNATTargetV1 struct {
_ structs.HostLayout
Target XTEntryTarget
Range NFNATRange
}
@ -436,6 +454,7 @@ const SizeOfXTNATTargetV1 = SizeOfXTEntryTarget + SizeOfNFNATRange
//
// +marshal
type XTNATTargetV2 struct {
_ structs.HostLayout
Target XTEntryTarget
Range NFNATRange2
}
@ -443,11 +462,33 @@ type XTNATTargetV2 struct {
// SizeOfXTNATTargetV2 is the size of an XTNATTargetV2.
const SizeOfXTNATTargetV2 = SizeOfXTEntryTarget + SizeOfNFNATRange2
// XTCTTargetInfoV0 corresponds to struct xt_ct_target_info (revision 0) in
// include/uapi/linux/netfilter/xt_CT.h. The CT target is used in the raw
// table for conntrack zone assignment. The trailing padding accounts for the
// kernel-internal nf_conn pointer that is 8-byte aligned.
//
// +marshal
type XTCTTargetInfoV0 struct {
_ structs.HostLayout
Target XTEntryTarget
Flags uint16
Zone uint16
CTEvents uint32
ExpEvents uint32
Helper [16]byte
_ [4]byte // padding for 8-byte alignment of ct pointer
_ [8]byte // space for kernel nf_conn pointer (unused in userspace)
}
// SizeOfXTCTTargetInfoV0 is the size of an XTCTTargetInfoV0.
const SizeOfXTCTTargetInfoV0 = 72
// IPTGetinfo is the argument for the IPT_SO_GET_INFO sockopt. It corresponds
// to struct ipt_getinfo in include/uapi/linux/netfilter_ipv4/ip_tables.h.
//
// +marshal
type IPTGetinfo struct {
_ structs.HostLayout
Name TableName
ValidHooks uint32
HookEntry [NF_INET_NUMHOOKS]uint32
@ -465,6 +506,7 @@ const SizeOfIPTGetinfo = 84
//
// +marshal
type IPTGetEntries struct {
_ structs.HostLayout
Name TableName
Size uint32
_ [4]byte
@ -482,8 +524,9 @@ const SizeOfIPTGetEntries = 40
//
// +marshal dynamic
type KernelIPTGetEntries struct {
_ structs.HostLayout
IPTGetEntries
Entrytable []KernelIPTEntry
Entrytable []KernelIPTEntry `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -521,6 +564,7 @@ var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
//
// +marshal
type IPTReplace struct {
_ structs.HostLayout
Name TableName
ValidHooks uint32
NumEntries uint32
@ -582,6 +626,7 @@ func goString(cstring []byte) string {
//
// +marshal
type XTTCP struct {
_ structs.HostLayout
// SourcePortStart specifies the inclusive start of the range of source
// ports to which the matcher applies.
SourcePortStart uint16
@ -637,6 +682,7 @@ const (
//
// +marshal
type XTUDP struct {
_ structs.HostLayout
// SourcePortStart is the inclusive start of the range of source ports
// to which the matcher applies.
SourcePortStart uint16
@ -679,6 +725,7 @@ const (
//
// +marshal
type IPTOwnerInfo struct {
_ structs.HostLayout
// UID is user id which created the packet.
UID uint32
@ -711,6 +758,7 @@ const SizeOfIPTOwnerInfo = 34
//
// +marshal
type XTOwnerMatchInfo struct {
_ structs.HostLayout
UIDMin uint32
UIDMax uint32
GIDMin uint32
@ -753,6 +801,7 @@ const (
//
// +marshal
type XTMultiport struct {
_ structs.HostLayout
// Flags indicates whether the match applies to
// source ports, destination ports, or either, as
// defined by "enum xt_multiport_flags".
@ -774,6 +823,7 @@ type XTMultiport struct {
//
// +marshal
type XTMultiportV1 struct {
_ structs.HostLayout
// Fields same as "XTMultiport".
Flags uint8
Count uint8
@ -794,3 +844,68 @@ const SizeOfXTMultiport = 2 + (XT_MULTI_PORTS * 2)
// SizeOfXTMultiportV1 is the size of XTMultiportV1 (in bytes).
const SizeOfXTMultiportV1 = SizeOfXTMultiport + XT_MULTI_PORTS + 1
// XTMarkMtinfo1 holds data for matching packets against a mark.
// It corresponds to struct xt_mark_mtinfo1 in include/uapi/linux/netfilter/xt_mark.h.
//
// +marshal
type XTMarkMtinfo1 struct {
_ structs.HostLayout
Mark uint32
Mask uint32
Invert uint8
_ [3]byte
}
// SizeOfXTMarkMtinfo1 is the size of XTMarkMtinfo1.
const SizeOfXTMarkMtinfo1 = 12
// Ref: include/uapi/linux/netfilter_ipv4/ipt_REJECT.h:enum ipt_reject_with
const (
IPT_ICMP_NET_UNREACHABLE = iota
IPT_ICMP_HOST_UNREACHABLE
IPT_ICMP_PROT_UNREACHABLE
IPT_ICMP_PORT_UNREACHABLE
IPT_ICMP_ECHOREPLY
IPT_ICMP_NET_PROHIBITED
IPT_ICMP_HOST_PROHIBITED
IPT_TCP_RESET
IPT_ICMP_ADMIN_PROHIBITED
)
// Ref: include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h:enum ip6t_reject_with
const (
IP6T_ICMP6_NO_ROUTE = iota
IP6T_ICMP6_ADM_PROHIBITED
IP6T_ICMP6_NOT_NEIGHBOUR
IP6T_ICMP6_ADDR_UNREACH
IP6T_ICMP6_PORT_UNREACH
IP6T_ICMP6_ECHOREPLY
IP6T_TCP_RESET
IP6T_ICMP6_POLICY_FAIL
IP6T_ICMP6_REJECT_ROUTE
)
// IPTRejectInfo is the argument for the IPT_REJECT target. It corresponds to
// struct ipt_reject_info in include/uapi/linux/netfilter_ipv4/ipt_REJECT.h.
//
// +marshal
type IPTRejectInfo struct {
_ structs.HostLayout
With uint32
}
// SizeOfIPTRejectInfo is the size of an IPTRejectInfo.
const SizeOfIPTRejectInfo = 4
// IP6TRejectInfo is the argument for the IP6T_REJECT target. It corresponds to
// struct ip6t_reject_info in include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h.
//
// +marshal
type IP6TRejectInfo struct {
_ structs.HostLayout
With uint32
}
// SizeOfIP6TRejectInfo is the size of an IP6TRejectInfo.
const SizeOfIP6TRejectInfo = 4

View file

@ -16,6 +16,7 @@ package linux
import (
"math"
"structs"
"github.com/sagernet/gvisor/pkg/marshal"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
@ -69,6 +70,7 @@ const IP6T_ORIGINAL_DST = 80
//
// +marshal
type IP6TReplace struct {
_ structs.HostLayout
Name TableName
ValidHooks uint32
NumEntries uint32
@ -90,8 +92,9 @@ const SizeOfIP6TReplace = 96
//
// +marshal dynamic
type KernelIP6TGetEntries struct {
_ structs.HostLayout
IPTGetEntries
Entrytable []KernelIP6TEntry
Entrytable []KernelIP6TEntry `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -128,6 +131,7 @@ var _ marshal.Marshallable = (*KernelIP6TGetEntries)(nil)
//
// +marshal
type IP6TEntry struct {
_ structs.HostLayout
// IPv6 is used to filter packets based on the IPv6 header.
IPv6 IP6TIP
@ -169,13 +173,14 @@ const SizeOfIP6TEntry = 168
//
// +marshal dynamic
type KernelIP6TEntry struct {
_ structs.HostLayout
Entry IP6TEntry
// Elems holds the data for all this rule's matches followed by the
// target. It is variable length -- users have to iterate over any
// matches and use TargetOffset and NextOffset to make sense of the
// data.
Elems primitive.ByteSlice
Elems primitive.ByteSlice `hostlayout:"ignore"`
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
@ -203,6 +208,7 @@ var _ marshal.Marshallable = (*KernelIP6TEntry)(nil)
//
// +marshal
type IP6TIP struct {
_ structs.HostLayout
// Src is the source IP address.
Src Inet6Addr
@ -286,6 +292,7 @@ const (
//
// +marshal
type NFNATRange struct {
_ structs.HostLayout
Flags uint32
MinAddr Inet6Addr
MaxAddr Inet6Addr
@ -301,6 +308,7 @@ const SizeOfNFNATRange = 40
//
// +marshal
type NFNATRange2 struct {
_ structs.HostLayout
Flags uint32
MinAddr Inet6Addr
MaxAddr Inet6Addr

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Netlink protocols, from uapi/linux/netlink.h.
const (
NETLINK_ROUTE = 0
@ -43,6 +47,7 @@ const (
//
// +marshal
type SockAddrNetlink struct {
_ structs.HostLayout
Family uint16
_ uint16
PortID uint32
@ -56,6 +61,7 @@ const SockAddrNetlinkSize = 12
//
// +marshal
type NetlinkMessageHeader struct {
_ structs.HostLayout
Length uint32
Type uint16
Flags uint16
@ -118,6 +124,7 @@ const NLMSG_ALIGNTO = 4
//
// +marshal
type NetlinkAttrHeader struct {
_ structs.HostLayout
Length uint16
Type uint16
}
@ -136,6 +143,33 @@ const NetlinkAttrHeaderSize = 4
// uapi/linux/netlink.h.
const NLA_ALIGNTO = 4
// Standard attribute types to specify validation policy, from
// include/net/netlink.h.
const (
NLA_UNSPEC = iota
NLA_U8
NLA_U16
NLA_U32
NLA_U64
NLA_STRING
NLA_FLAG
NLA_MSECS
NLA_NESTED
NLA_NESTED_ARRAY
NLA_NUL_STRING
NLA_BINARY
NLA_S8
NLA_S16
NLA_S32
NLA_S64
NLA_BITFIELD32
NLA_REJECT
NLA_BE16
NLA_BE32
__NLA_TYPE_MAX
NLA_TYPE_MAX = __NLA_TYPE_MAX - 1
)
// Socket options, from uapi/linux/netlink.h.
const (
NETLINK_ADD_MEMBERSHIP = 1
@ -154,6 +188,12 @@ const (
//
// +marshal
type NetlinkErrorMessage struct {
_ structs.HostLayout
Error int32
Header NetlinkMessageHeader
}
// RTNetlink multicast groups, from uapi/linux/rtnetlink.h.
const (
RTNLGRP_LINK = 1
)

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Group describes Netlink Netfilter groups, from uapi/linux/netfilter/nfnetlink.h.
// Users bind to specific groups to receive processing logs from those groups.
type Group uint16
@ -38,6 +42,7 @@ const (
//
// +marshal
type NetFilterGenMsg struct {
_ structs.HostLayout
Family uint8
Version uint8
ResourceID uint16

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Netlink message types for NETLINK_ROUTE sockets, from uapi/linux/rtnetlink.h.
const (
RTM_NEWLINK = 16
@ -88,6 +92,7 @@ const (
//
// +marshal
type InterfaceInfoMessage struct {
_ structs.HostLayout
Family uint8
_ uint8
Type uint16
@ -187,6 +192,7 @@ const (
//
// +marshal
type InterfaceAddrMessage struct {
_ structs.HostLayout
Family uint8
PrefixLen uint8
Flags uint8
@ -221,6 +227,7 @@ const (
//
// +marshal
type RouteMessage struct {
_ structs.HostLayout
Family uint8
DstLen uint8
SrcLen uint8
@ -369,6 +376,7 @@ const (
//
// +marshal
type RtAttr struct {
_ structs.HostLayout
Len uint16
Type uint16
}

View file

@ -28,6 +28,7 @@ const (
NFT_OBJ_MAXNAMELEN = NFT_NAME_MAXLEN
NFT_USERDATA_MAXLEN = 256
NFT_OSF_MAXGENRELEN = 16
NFT_SET_EXPR_MAX = 2
)
// 16-byte Registers that can be used to maintain state for rules.
@ -336,6 +337,22 @@ const (
NFTA_IMMEDIATE_MAX = __NFTA_IMMEDIATE_MAX - 1
)
// NfTablePayloadAttributes represents the netfilter payload attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_PAYLOAD_UNSPEC uint16 = iota
NFTA_PAYLOAD_DREG
NFTA_PAYLOAD_BASE
NFTA_PAYLOAD_OFFSET
NFTA_PAYLOAD_LEN
NFTA_PAYLOAD_SREG
NFTA_PAYLOAD_CSUM_TYPE
NFTA_PAYLOAD_CSUM_OFFSET
NFTA_PAYLOAD_CSUM_FLAGS
__NFTA_PAYLOAD_MAX
NFTA_PAYLOAD_MAX = __NFTA_PAYLOAD_MAX - 1
)
// Nf table relational operators.
// Used by the nft comparison operation to compare values in registers.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
@ -348,6 +365,17 @@ const (
NFT_CMP_GTE // greater than or equal to
)
// Nf table cmp expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_CMP_UNSPEC uint16 = iota
NFTA_CMP_SREG
NFTA_CMP_OP
NFTA_CMP_DATA
__NFTA_CMP_MAX
NFTA_CMP_MAX = __NFTA_CMP_MAX - 1
)
// Nf table range operators.
// Used by the nft range operation to compare values in registers.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
@ -392,6 +420,21 @@ const (
NFT_BITWISE_RSHIFT // right-shift operation
)
// Nf table bitwise expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_BITWISE_UNSPEC uint16 = iota
NFTA_BITWISE_SREG
NFTA_BITWISE_DREG
NFTA_BITWISE_LEN
NFTA_BITWISE_MASK
NFTA_BITWISE_XOR
NFTA_BITWISE_OP
NFTA_BITWISE_DATA
__NFTA_BITWISE_MAX
NFTA_BITWISE_MAX = __NFTA_BITWISE_MAX - 1
)
// Nf table route expression keys.
// Used by the nft route operation to determine the routing data to retrieve.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
@ -462,3 +505,323 @@ const (
NFT_META_SDIFNAME // Slave device interface name
NFT_META_BRI_BROUTE // Packet br_netfilter_broute bit
)
// Nf table meta expression netlink attributes
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_META_UNSPEC = iota
NFTA_META_DREG
NFTA_META_KEY
NFTA_META_SREG
__NFTA_META_MAX
NFTA_META_MAX = __NFTA_META_MAX - 1
)
// Nf table counter expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_COUNTER_UNSPEC = iota
NFTA_COUNTER_BYTES
NFTA_COUNTER_PACKETS
NFTA_COUNTER_PAD
__NFTA_COUNTER_MAX
NFTA_COUNTER_MAX = __NFTA_COUNTER_MAX - 1
)
// Nftables Generation Attributes
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_GEN_UNSPEC uint16 = iota
NFTA_GEN_ID
NFTA_GEN_PROC_PID
NFTA_GEN_PROC_NAME
__NFTA_GEN_MAX
NFTA_GEN_MAX = __NFTA_GEN_MAX - 1
)
// Nf table nat expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_NAT_UNSPEC uint16 = iota
NFTA_NAT_TYPE
NFTA_NAT_FAMILY
NFTA_NAT_REG_ADDR_MIN
NFTA_NAT_REG_ADDR_MAX
NFTA_NAT_REG_PROTO_MIN
NFTA_NAT_REG_PROTO_MAX
NFTA_NAT_FLAGS
__NFTA_NAT_MAX
NFTA_NAT_MAX = __NFTA_NAT_MAX - 1
)
// NfTableSetFlags represents the netfilter set flags.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_SET_ANONYMOUS = uint16(0x1)
NFT_SET_CONSTANT = uint16(0x2)
NFT_SET_INTERVAL = uint16(0x4)
NFT_SET_MAP = uint16(0x8)
NFT_SET_TIMEOUT = uint16(0x10)
NFT_SET_EVAL = uint16(0x20)
NFT_SET_OBJECT = uint16(0x40)
NFT_SET_CONCAT = uint16(0x80)
NFT_SET_EXPR = uint16(0x100)
)
// NfTableSetAttributes represents the netfilter set attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_SET_UNSPEC uint16 = iota
NFTA_SET_TABLE
NFTA_SET_NAME
NFTA_SET_FLAGS
NFTA_SET_KEY_TYPE
NFTA_SET_KEY_LEN
NFTA_SET_DATA_TYPE
NFTA_SET_DATA_LEN
NFTA_SET_POLICY
NFTA_SET_DESC
NFTA_SET_ID
NFTA_SET_TIMEOUT
NFTA_SET_GC_INTERVAL
NFTA_SET_USERDATA
NFTA_SET_PAD
NFTA_SET_OBJ_TYPE
NFTA_SET_HANDLE
NFTA_SET_EXPR
NFTA_SET_EXPRESSIONS
__NFTA_SET_MAX
NFTA_SET_MAX = __NFTA_SET_MAX - 1
)
// NfTableSetPolicies represents the netfilter set policies.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_SET_POL_PERFORMANCE uint32 = iota // prefer high performance over low memory use
NFT_SET_POL_MEMORY // prefer low memory use over high performance
)
// NfTableSetDescAttributes represents the netfilter set description attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_SET_DESC_UNSPEC uint16 = iota
NFTA_SET_DESC_SIZE
NFTA_SET_DESC_CONCAT
__NFTA_SET_DESC_MAX
NFTA_SET_DESC_MAX = __NFTA_SET_DESC_MAX - 1
)
// NfTableSetFieldAttributes represents the netfilter set field attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_SET_FIELD_UNSPEC uint16 = iota
NFTA_SET_FIELD_LEN
__NFTA_SET_FIELD_MAX
NFTA_SET_FIELD_MAX = __NFTA_SET_FIELD_MAX - 1
)
// NfTableObjectAttributes represents the netfilter object attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_OBJECT_UNSPEC uint32 = iota
NFT_OBJECT_COUNTER
NFT_OBJECT_QUOTA
NFT_OBJECT_CT_HELPER
NFT_OBJECT_LIMIT
NFT_OBJECT_CONNLIMIT
NFT_OBJECT_TUNNEL
NFT_OBJECT_CT_TIMEOUT
NFT_OBJECT_SECMARK
NFT_OBJECT_CT_EXPECT
NFT_OBJECT_SYNPROXY
__NFT_OBJECT_MAX
NFT_OBJECT_MAX = __NFT_OBJECT_MAX - 1
)
// NfTableSetElemListAttributes represents the netfilter set element list attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_SET_ELEM_LIST_UNSPEC uint16 = iota
NFTA_SET_ELEM_LIST_TABLE
NFTA_SET_ELEM_LIST_SET
NFTA_SET_ELEM_LIST_ELEMENTS
NFTA_SET_ELEM_LIST_SET_ID
__NFTA_SET_ELEM_LIST_MAX
NFTA_SET_ELEM_LIST_MAX = __NFTA_SET_ELEM_LIST_MAX - 1
)
// NfTableSetElemAttributes represents the netfilter set element attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_SET_ELEM_UNSPEC uint16 = iota
NFTA_SET_ELEM_KEY
NFTA_SET_ELEM_DATA
NFTA_SET_ELEM_FLAGS
NFTA_SET_ELEM_TIMEOUT
NFTA_SET_ELEM_EXPIRATION
NFTA_SET_ELEM_USERDATA
NFTA_SET_ELEM_EXPR
NFTA_SET_ELEM_PAD
NFTA_SET_ELEM_OBJREF
NFTA_SET_ELEM_KEY_END
NFTA_SET_ELEM_EXPRESSIONS
__NFTA_SET_ELEM_MAX
NFTA_SET_ELEM_MAX = __NFTA_SET_ELEM_MAX - 1
)
// NfTableSetElemFlags represents the netfilter set element flags.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_SET_ELEM_INTERVAL_END = uint16(0x1)
NFT_SET_ELEM_CATCHALL = uint16(0x2)
)
// NfTableLookupAttributes represents the netfilter lookup attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_LOOKUP_UNSPEC uint16 = iota
NFTA_LOOKUP_SET
NFTA_LOOKUP_SREG
NFTA_LOOKUP_DREG
NFTA_LOOKUP_SET_ID
NFTA_LOOKUP_FLAGS
__NFTA_LOOKUP_MAX
NFTA_LOOKUP_MAX = __NFTA_LOOKUP_MAX - 1
)
const NFT_LOOKUP_F_INV = uint32(1 << 0)
// NfTable fib expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_FIB_UNSPEC uint16 = iota
NFTA_FIB_DREG
NFTA_FIB_RESULT
NFTA_FIB_FLAGS
__NFTA_FIB_MAX
)
const NFTA_FIB_MAX = __NFTA_FIB_MAX - 1
// NfTable fib result types.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_FIB_RESULT_UNSPEC = iota
NFT_FIB_RESULT_OIF
NFT_FIB_RESULT_OIFNAME
NFT_FIB_RESULT_ADDRTYPE
__NFT_FIB_RESULT_MAX
)
const NFT_FIB_RESULT_MAX = __NFT_FIB_RESULT_MAX - 1
// NfTable fib flags.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_FIB_F_SADDR = 1 << 0
NFTA_FIB_F_DADDR = 1 << 1
NFTA_FIB_F_MARK = 1 << 2
NFTA_FIB_F_IIF = 1 << 3
NFTA_FIB_F_OIF = 1 << 4
NFTA_FIB_F_PRESENT = 1 << 5
)
// Nf table ct expression keys.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_CT_STATE = iota
NFT_CT_DIRECTION
NFT_CT_STATUS
NFT_CT_MARK
NFT_CT_SECMARK
NFT_CT_EXPIRATION
NFT_CT_HELPER
NFT_CT_L3PROTOCOL
NFT_CT_SRC
NFT_CT_DST
NFT_CT_PROTOCOL
NFT_CT_PROTO_SRC
NFT_CT_PROTO_DST
NFT_CT_LABELS
NFT_CT_PKTS
NFT_CT_BYTES
NFT_CT_AVGPKT
NFT_CT_ZONE
NFT_CT_EVENTMASK
NFT_CT_SRC_IP
NFT_CT_DST_IP
NFT_CT_SRC_IP6
NFT_CT_DST_IP6
NFT_CT_ID
__NFT_CT_MAX
NFT_CT_MAX = __NFT_CT_MAX - 1
)
// Nf table ct expression netlink attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_CT_UNSPEC uint16 = iota
NFTA_CT_DREG
NFTA_CT_KEY
NFTA_CT_DIRECTION
NFTA_CT_SREG
__NFTA_CT_MAX
NFTA_CT_MAX = __NFTA_CT_MAX - 1
)
// IPCTInfo represents the state of a connection.
// Used with NF_CT_STATE to represent the state of a connection.
// Ref: enum include/uapi/linux/netfilter/nf_conntrack.h:ip_conntrack_info
type IPCTInfo int
const (
// IP_CT_ESTABLISHED represents an established connection (either direction).
IP_CT_ESTABLISHED IPCTInfo = iota
// IP_CT_RELATED represents a connection related to an existing connection,
// or an ICMP error (in either direction).
IP_CT_RELATED
// IP_CT_NEW represents a new connection to track.
IP_CT_NEW
// IP_CT_IS_REPLY indicates reply direction.
IP_CT_IS_REPLY
// IP_CT_ESTABLISHED_REPLY represents an established connection in the reply direction.
IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY
// IP_CT_RELATED_REPLY represents a connection related to an existing connection,
// or an ICMP error in the reply direction.
IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY
// IP_CT_NUMBER is the number of distinct IP_CT types.
IP_CT_NUMBER = 5
// IP_CT_NEW_REPLY is for userspace compatibility.
IP_CT_NEW_REPLY = IP_CT_NUMBER
// IP_CT_UNTRACKED represents an untracked connection.
IP_CT_UNTRACKED = 7
)
// Conntrack states.
const (
// NF_CT_STATE_INVALID_BIT represents an invalid connection state.
NF_CT_STATE_INVALID_BIT = 1 << 0
// NF_CT_STATE_UNTRACKED_BIT represents an untracked connection state.
NF_CT_STATE_UNTRACKED_BIT = 1 << 6
)
// From include/uapi/linux/netfilter/nf_conntrack_common.h.
const (
IP_CT_DIR_ORIGINAL uint8 = iota
IP_CT_DIR_REPLY
IP_CT_DIR_MAX
)
// Nf table masq expression netlink attributes.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_MASQ_UNSPEC uint16 = iota
NFTA_MASQ_FLAGS
NFTA_MASQ_REG_PROTO_MIN
NFTA_MASQ_REG_PROTO_MAX
__NFTA_MASQ_MAX
NFTA_MASQ_MAX = __NFTA_MASQ_MAX - 1
)
// SizeOfNfConntrackManProto is the size of the nf_conntrack_man_proto in bytes.
// Ref: include/uapi/linux/netfilter/nf_conntrack_tuple_common.h:nf_conntrack_man_proto.
const SizeOfNfConntrackManProto = 2

View file

@ -0,0 +1,30 @@
// Copyright 2026 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
// Personality flags, used by personality(2),
// from include/uapi/linux/personality.h.
const (
SHORT_INODE = 0x1000000
WHOLE_SECONDS = 0x2000000
PER_LINUX = 0x0000
PER_BSD = 0x0006
PER_HPUX = 0x0010
)
// NOTE: All of the above flags are non-security-sensitive and may be copied
// from parent task to child task. However, this is not the case for all
// personality bits. If adding more, check PER_CLEAR_ON_SETID and ensure that
// these are cleared on suid/sgid execs.

View file

@ -1,4 +1,4 @@
// Copyright 2024 The gVisor Authors.
// Copyright 2026 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.
@ -14,9 +14,15 @@
package linux
import "unsafe"
// Flags for pidfd_open() from include/uapi/linux/pidfd.h.
const (
PIDFD_NONBLOCK = O_NONBLOCK
PIDFD_THREAD = O_EXCL
)
// Size returns the number of bytes for a VFIOIrqSet object.
func (vfioIrqSet VFIOIrqSet) Size() uint64 {
return uint64(unsafe.Sizeof(vfioIrqSet))
}
// Flags for pidfd_send_signal().
const (
PIDFD_SIGNAL_THREAD = 1 << 0
PIDFD_SIGNAL_THREAD_GROUP = 1 << 1
PIDFD_SIGNAL_PROCESS_GROUP = 1 << 2
)

View file

@ -14,10 +14,15 @@
package linux
import (
"structs"
)
// PollFD is struct pollfd, used by poll(2)/ppoll(2), from uapi/asm-generic/poll.h.
//
// +marshal slice:PollFDSlice
type PollFD struct {
_ structs.HostLayout
FD int32
Events int16
REvents int16
@ -42,3 +47,9 @@ const (
POLLFREE = 0x4000
POLL_BUSY_LOOP = 0x8000
)
const (
// ReventsOffsetInPollFD is the byte offset of the REvents field within
// linux.PollFD.
ReventsOffsetInPollFD = 6 // +checkoffset . PollFD.REvents
)

View file

@ -34,6 +34,12 @@ const (
// PR_SET_KEEPCAPS sets the value of the keep capabilities flag.
PR_SET_KEEPCAPS = 8
// PR_GET_SECUREBITS gets the securebits flags of the calling thread.
PR_GET_SECUREBITS = 27
// PR_SET_SECUREBITS sets the securebits flags of the calling thread.
PR_SET_SECUREBITS = 28
// PR_GET_TIMING gets the process' timing method.
PR_GET_TIMING = 13
@ -159,6 +165,21 @@ const (
// specified) to ptrace the current task.
PR_SET_PTRACER = 0x59616d61
PR_SET_PTRACER_ANY = -1
PR_SET_TAGGED_ADDR_CTRL = 55
PR_GET_TAGGED_ADDR_CTRL = 56
PR_TAGGED_ADDR_ENABLE = (1 << 0)
// PR_CAP_AMBIENT controls ambient capabilities.
PR_CAP_AMBIENT = 47
PR_CAP_AMBIENT_IS_SET = 1
PR_CAP_AMBIENT_RAISE = 2
PR_CAP_AMBIENT_LOWER = 3
PR_CAP_AMBIENT_CLEAR_ALL = 4
// SECBIT_* flags are used to control securebits.
SECBIT_KEEP_CAPS = 1 << 4
)
// From <asm/prctl.h>

View file

@ -17,12 +17,17 @@
package linux
import (
"structs"
)
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
// syscall.PtraceRegs.
//
// +marshal
// +stateify savable
type PtraceRegs struct {
_ structs.HostLayout
R15 uint64
R14 uint64
R13 uint64

View file

@ -17,6 +17,10 @@
package linux
import (
"structs"
)
const (
// PSR bits
PSR_MODE_EL0t = 0x00000000
@ -54,6 +58,7 @@ const (
// +marshal
// +stateify savable
type PtraceRegs struct {
_ structs.HostLayout
Regs [31]uint64
Sp uint64
Pc uint64

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Flags passed to rseq(2).
//
// Defined in include/uapi/linux/rseq.h.
@ -45,6 +49,7 @@ const (
//
// +marshal
type RSeqCriticalSection struct {
_ structs.HostLayout
// Version is the version of this structure. Version 0 is defined here.
Version uint32
@ -88,6 +93,7 @@ const (
//
// In userspace, this structure is always aligned to 32 bytes.
type RSeq struct {
_ structs.HostLayout
// CPUIDStart contains the current CPU ID if rseq is initialized.
//
// This field should only be read by the thread which registered this

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// Flags that may be used with wait4(2) and getrusage(2).
const (
// wait4(2) uses this to aggregate RUSAGE_SELF and RUSAGE_CHILDREN.
@ -29,6 +33,7 @@ const (
//
// +marshal
type Rusage struct {
_ structs.HostLayout
UTime Timeval
STime Timeval
MaxRSS int64

View file

@ -14,6 +14,8 @@
package linux
import "structs"
// Scheduling policies, exposed by sched_getscheduler(2)/sched_setscheduler(2).
const (
SCHED_NORMAL = 0
@ -35,3 +37,75 @@ const (
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
)
// SchedAttr represents struct sched_attr, as used by sched_setattr(2) and sched_getattr(2).
//
// +marshal
type SchedAttr struct {
_ structs.HostLayout
Size uint32
SchedPolicy uint32
SchedFlags uint64
SchedNice int32
SchedPriority uint32
// For SCHED_DEADLINE
SchedRuntime uint64
SchedDeadline uint64
SchedPeriod uint64
// Utilization hints
SchedUtilMin uint32
SchedUtilMax uint32
}
// Sizes for different versions of the SchedAttr struct.
const (
SCHED_ATTR_SIZE_VER0 = 48
SCHED_ATTR_SIZE_VER1 = 56
SCHED_ATTR_SIZE_LATEST = SCHED_ATTR_SIZE_VER1
)
// Flags for sched_setattr.
const (
SCHED_FLAG_RESET_ON_FORK = 0x01
SCHED_FLAG_RECLAIM = 0x02
SCHED_FLAG_DL_OVERRUN = 0x04
SCHED_FLAG_KEEP_POLICY = 0x08
SCHED_FLAG_KEEP_PARAMS = 0x10
SCHED_FLAG_UTIL_CLAMP_MIN = 0x20
SCHED_FLAG_UTIL_CLAMP_MAX = 0x40
)
// I/O priority target types.
const (
IOPRIO_WHO_PROCESS = 1
IOPRIO_WHO_PGRP = 2
IOPRIO_WHO_USER = 3
)
// I/O priority classes.
const (
IOPRIO_CLASS_NONE = 0
IOPRIO_CLASS_RT = 1
IOPRIO_CLASS_BE = 2
IOPRIO_CLASS_IDLE = 3
)
// I/O priority bitwise encoding constants.
const (
IOPRIO_CLASS_SHIFT = 13
IOPRIO_NR_CLASSES = 8
IOPRIO_CLASS_MASK = IOPRIO_NR_CLASSES - 1
IOPRIO_PRIO_MASK = (1 << IOPRIO_CLASS_SHIFT) - 1
)
// UnwrapIOPrio unwraps the bitmask ioprio into its enclosed ioclass and data fields.
func UnwrapIOPrio(ioprio int) (ioclass int8, iopriodata uint16) {
ioclass = int8((ioprio >> IOPRIO_CLASS_SHIFT) & (IOPRIO_CLASS_MASK))
iopriodata = uint16(ioprio & IOPRIO_PRIO_MASK)
return
}

View file

@ -14,7 +14,10 @@
package linux
import "fmt"
import (
"fmt"
"structs"
)
// Seccomp constants taken from <linux/seccomp.h>.
const (
@ -103,6 +106,7 @@ func (a BPFAction) WithReturnCode(code uint16) BPFAction {
// SockFprog is sock_fprog taken from <linux/filter.h>.
type SockFprog struct {
_ structs.HostLayout
Len uint16
pad [6]byte
Filter *BPFInstruction
@ -113,6 +117,7 @@ type SockFprog struct {
//
// +marshal
type SeccompData struct {
_ structs.HostLayout
// Nr is the system call number.
Nr int32
@ -131,6 +136,7 @@ type SeccompData struct {
//
// +marshal
type SeccompNotifResp struct {
_ structs.HostLayout
ID uint64
Val int64
Error int32
@ -141,6 +147,7 @@ type SeccompNotifResp struct {
//
// +marshal
type SeccompNotifSizes struct {
_ structs.HostLayout
Notif uint16
Notif_resp uint16
Data uint16
@ -150,6 +157,7 @@ type SeccompNotifSizes struct {
//
// +marshal
type SeccompNotif struct {
_ structs.HostLayout
ID uint64
Pid int32
Flags uint32

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
// semctl Command Definitions. Source: include/uapi/linux/sem.h
const (
GETPID = 11
@ -58,6 +62,7 @@ const (
//
// +marshal slice:SembufSlice
type Sembuf struct {
_ structs.HostLayout
SemNum uint16
SemOp int16
SemFlg int16
@ -69,6 +74,7 @@ type Sembuf struct {
//
// +marshal
type SemInfo struct {
_ structs.HostLayout
SemMap uint32
SemMni uint32
SemMns uint32

View file

@ -17,12 +17,17 @@
package linux
import (
"structs"
)
// SemidDS is equivalent to struct semid64_ds.
//
// Source: arch/x86/include/uapi/asm/sembuf.h
//
// +marshal
type SemidDS struct {
_ structs.HostLayout
SemPerm IPCPerm
SemOTime TimeT
unused1 uint64

View file

@ -17,12 +17,17 @@
package linux
import (
"structs"
)
// SemidDS is equivalent to struct semid64_ds.
//
// Source: include/uapi/asm-generic/sembuf.h
//
// +marshal
type SemidDS struct {
_ structs.HostLayout
SemPerm IPCPerm
SemOTime TimeT
SemCTime TimeT

View file

@ -14,7 +14,10 @@
package linux
import "math"
import (
"math"
"structs"
)
// shmat(2) flags. Source: include/uapi/linux/shm.h
const (
@ -54,6 +57,7 @@ const (
//
// +marshal
type ShmidDS struct {
_ structs.HostLayout
ShmPerm IPCPerm
ShmSegsz uint64
ShmAtime TimeT
@ -71,6 +75,7 @@ type ShmidDS struct {
//
// +marshal
type ShmParams struct {
_ structs.HostLayout
ShmMax uint64
ShmMin uint64
ShmMni uint64
@ -82,6 +87,7 @@ type ShmParams struct {
//
// +marshal
type ShmInfo struct {
_ structs.HostLayout
UsedIDs int32 // Number of currently existing segments.
_ [4]byte
ShmTot uint64 // Total number of shared memory pages.

View file

@ -15,6 +15,8 @@
package linux
import (
"structs"
"github.com/sagernet/gvisor/pkg/bits"
"github.com/sagernet/gvisor/pkg/hostarch"
)
@ -130,12 +132,12 @@ func MakeSignalSet(sigs ...Signal) SignalSet {
for i, sig := range sigs {
indices[i] = sig.Index()
}
return SignalSet(bits.Mask64(indices...))
return bits.Mask[SignalSet](indices...)
}
// SignalSetOf returns a SignalSet with a single signal set.
func SignalSetOf(sig Signal) SignalSet {
return SignalSet(bits.MaskOf64(sig.Index()))
return bits.MaskOf[SignalSet](sig.Index())
}
// ForEachSignal invokes f for each signal set in the given mask.
@ -291,6 +293,7 @@ const (
//
// +marshal
type Sigevent struct {
_ structs.HostLayout
Value uint64 // union sigval {int, void*}
Signo int32
Notify int32
@ -306,6 +309,7 @@ type Sigevent struct {
// +marshal
// +stateify savable
type SigAction struct {
_ structs.HostLayout
Handler uint64
Flags uint64
Restorer uint64
@ -318,6 +322,7 @@ type SigAction struct {
// +marshal
// +stateify savable
type SignalStack struct {
_ structs.HostLayout
Addr uint64
Flags uint32
_ uint32
@ -345,6 +350,7 @@ func (s *SignalStack) IsEnabled() bool {
// +marshal
// +stateify savable
type SignalInfo struct {
_ structs.HostLayout
Signo int32 // Signal number
Errno int32 // Errno value
Code int32 // Signal code

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
const (
// SFD_NONBLOCK is a signalfd(2) flag.
SFD_NONBLOCK = 0o0004000
@ -26,6 +30,7 @@ const (
//
// +marshal
type SignalfdSiginfo struct {
_ structs.HostLayout
Signo uint32
Errno int32
Code int32

View file

@ -15,6 +15,8 @@
package linux
import (
"structs"
"github.com/sagernet/gvisor/pkg/marshal"
)
@ -174,6 +176,7 @@ const (
//
// +marshal
type TpacketReq struct {
_ structs.HostLayout
TpBlockSize uint32
TpBlockNr uint32
TpFrameSize uint32
@ -185,6 +188,7 @@ type TpacketReq struct {
//
// +marshal
type TpacketHdr struct {
_ structs.HostLayout
TpStatus uint64
TpLen uint32
TpSnaplen uint32
@ -200,6 +204,7 @@ type TpacketHdr struct {
//
// +marshal
type Tpacket2Hdr struct {
_ structs.HostLayout
TpStatus uint32
TpLen uint32
TpSnaplen uint32
@ -217,6 +222,7 @@ type Tpacket2Hdr struct {
//
// +marshal
type TpacketStats struct {
_ structs.HostLayout
Packets uint32
Dropped uint32
}
@ -373,6 +379,7 @@ var SizeOfInetAddr = uint32((*InetAddr)(nil).SizeBytes())
//
// +marshal
type SockAddrInet struct {
_ structs.HostLayout
Family uint16
Port uint16
Addr InetAddr
@ -383,6 +390,7 @@ type SockAddrInet struct {
//
// +marshal
type Inet6MulticastRequest struct {
_ structs.HostLayout
MulticastAddr Inet6Addr
InterfaceIndex int32
}
@ -391,6 +399,7 @@ type Inet6MulticastRequest struct {
//
// +marshal
type InetMulticastRequest struct {
_ structs.HostLayout
MulticastAddr InetAddr
InterfaceAddr InetAddr
}
@ -399,6 +408,7 @@ type InetMulticastRequest struct {
//
// +marshal
type InetMulticastRequestWithNIC struct {
_ structs.HostLayout
InetMulticastRequest
InterfaceIndex int32
}
@ -412,6 +422,7 @@ type Inet6Addr [16]byte
//
// +marshal
type SockAddrInet6 struct {
_ structs.HostLayout
Family uint16
Port uint16
Flowinfo uint32
@ -423,6 +434,7 @@ type SockAddrInet6 struct {
//
// +marshal
type SockAddrLink struct {
_ structs.HostLayout
Family uint16
Protocol uint16
InterfaceIndex int32
@ -441,6 +453,7 @@ const UnixPathMax = 108
//
// +marshal
type SockAddrUnix struct {
_ structs.HostLayout
Family uint16
Path [UnixPathMax]int8
}
@ -466,6 +479,7 @@ func (s *SockAddrNetlink) implementsSockAddr() {}
//
// +marshal
type Linger struct {
_ structs.HostLayout
OnOff int32
Linger int32
}
@ -482,6 +496,7 @@ const SizeOfLinger = 8
//
// +marshal
type TCPInfo struct {
_ structs.HostLayout
// State is the state of the connection.
State uint8
@ -640,6 +655,7 @@ const (
//
// +marshal
type ControlMessageHeader struct {
_ structs.HostLayout
Length uint64
Level int32
Type int32
@ -655,6 +671,7 @@ var SizeOfControlMessageHeader = (*ControlMessageHeader)(nil).SizeBytes()
//
// +marshal
type ControlMessageCredentials struct {
_ structs.HostLayout
PID int32
UID uint32
GID uint32
@ -667,6 +684,7 @@ type ControlMessageCredentials struct {
// +marshal
// +stateify savable
type ControlMessageIPPacketInfo struct {
_ structs.HostLayout
NIC int32
LocalAddr InetAddr
DestinationAddr InetAddr
@ -677,6 +695,7 @@ type ControlMessageIPPacketInfo struct {
// +marshal
// +stateify savable
type ControlMessageIPv6PacketInfo struct {
_ structs.HostLayout
Addr Inet6Addr
NIC uint32
}
@ -728,6 +747,7 @@ const SO_ACCEPTCON = 1 << 16
// +marshal
// +stateify savable
type ICMP6Filter struct {
_ structs.HostLayout
Filter [8]uint32
}

View file

@ -16,6 +16,7 @@ package linux
import (
"math"
"structs"
"time"
)
@ -86,7 +87,10 @@ const (
TFD_NONBLOCK = O_NONBLOCK
// TFD_TIMER_ABSTIME is a timerfd_settime flag.
TFD_TIMER_ABSTIME = 1
TFD_TIMER_ABSTIME = 1 << 0
// TFD_TIMER_CANCEL_ON_SET is a timerfd_settime flag.
TFD_TIMER_CANCEL_ON_SET = 1 << 1
)
// The safe number of seconds you can represent by int64.
@ -106,6 +110,7 @@ func NsecToTimeT(nsec int64) TimeT {
//
// +marshal slice:TimespecSlice
type Timespec struct {
_ structs.HostLayout
Sec int64
Nsec int64
}
@ -162,6 +167,7 @@ const SizeOfTimeval = 16
//
// +marshal slice:TimevalSlice
type Timeval struct {
_ structs.HostLayout
Sec int64
Usec int64
}
@ -201,10 +207,16 @@ func DurationToTimeval(dur time.Duration) Timeval {
//
// +marshal
type Itimerspec struct {
_ structs.HostLayout
Interval Timespec
Value Timespec
}
// Valid returns whether the itimerspec contains valid values.
func (its Itimerspec) Valid() bool {
return its.Interval.Valid() && its.Value.Valid()
}
// ItimerVal mimics the following struct in <sys/time.h>
//
// struct itimerval {
@ -214,6 +226,7 @@ type Itimerspec struct {
//
// +marshal
type ItimerVal struct {
_ structs.HostLayout
Interval Timeval
Value Timeval
}
@ -232,6 +245,7 @@ func ClockTFromDuration(d time.Duration) ClockT {
//
// +marshal
type Tms struct {
_ structs.HostLayout
UTime ClockT
STime ClockT
CUTime ClockT
@ -248,6 +262,7 @@ type TimerID int32
//
// +marshal
type StatxTimestamp struct {
_ structs.HostLayout
Sec int64
Nsec uint32
_ int32
@ -283,6 +298,7 @@ func (sxts StatxTimestamp) ToTime() time.Time {
//
// +marshal
type Utime struct {
_ structs.HostLayout
Actime int64
Modtime int64
}

View file

@ -14,6 +14,10 @@
package linux
import (
"structs"
)
const (
// NumControlCharacters is the number of control characters in Termios.
NumControlCharacters = 19
@ -24,8 +28,10 @@ const (
// Winsize is struct winsize, defined in uapi/asm-generic/termios.h.
//
// +stateify savable
// +marshal
type Winsize struct {
_ structs.HostLayout
Row uint16
Col uint16
Xpixel uint16
@ -36,6 +42,7 @@ type Winsize struct {
//
// +marshal
type Termios struct {
_ structs.HostLayout
InputFlags uint32
OutputFlags uint32
ControlFlags uint32
@ -48,7 +55,9 @@ type Termios struct {
// uapi/asm-generic/termbits.h.
//
// +stateify savable
// +marshal
type KernelTermios struct {
_ structs.HostLayout
InputFlags uint32
OutputFlags uint32
ControlFlags uint32
@ -336,14 +345,3 @@ var DefaultReplicaTermios = KernelTermios{
InputSpeed: 38400,
OutputSpeed: 38400,
}
// WindowSize corresponds to struct winsize defined in
// include/uapi/asm-generic/termios.h.
//
// +stateify savable
// +marshal
type WindowSize struct {
Rows uint16
Cols uint16
_ [4]byte // Padding for 2 unused shorts.
}

View file

@ -17,6 +17,7 @@ package linux
import (
"bytes"
"fmt"
"structs"
)
const (
@ -29,6 +30,7 @@ const (
//
// +marshal
type UtsName struct {
_ structs.HostLayout
Sysname [UTSLen + 1]byte
Nodename [UTSLen + 1]byte
Release [UTSLen + 1]byte

View file

@ -16,6 +16,10 @@
package linux
import (
"structs"
)
// For IOCTLs requests from include/uapi/linux/vfio.h.
const (
VFIO_TYPE = ';'
@ -131,15 +135,26 @@ var (
//
// +marshal
type VFIODeviceInfo struct {
_ structs.HostLayout
VFIODeviceInfoMin
// Offset within info struct of first cap.
CapOffset uint32
pad uint32
}
// VFIODeviceInfoMin is the subset of vfio_device_info (from
// include/uapi/linux/vfio.h) that is copied into
// drivers/vfio/pci/vfio_pci_core.c:vfio_pci_ioctl_get_info().
//
// +marshal
type VFIODeviceInfoMin struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
// The total amount of regions.
NumRegions uint32
// The maximum number of IRQ.
NumIrqs uint32
// Offset within info struct of first cap.
CapOffset uint32
pad uint32
}
// VFIORegionInfo is analogous to vfio_region_info
@ -147,11 +162,12 @@ type VFIODeviceInfo struct {
//
// +marshal
type VFIORegionInfo struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
Index uint32
// Offset within info struct of first cap.
capOffset uint32
CapOffset uint32
// Region size in bytes.
Size uint64
// Region offset from start of device fd.
@ -163,6 +179,7 @@ type VFIORegionInfo struct {
//
// +marshal
type VFIOIrqInfo struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
Index uint32
@ -176,6 +193,7 @@ type VFIOIrqInfo struct {
//
// +marshal
type VFIOIrqSet struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
Index uint32
@ -188,6 +206,7 @@ type VFIOIrqSet struct {
//
// +marshal
type VFIOIommuType1DmaMap struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
// Process virtual address.
@ -203,6 +222,7 @@ type VFIOIommuType1DmaMap struct {
//
// +marshal
type VFIOIommuType1DmaUnmap struct {
_ structs.HostLayout
Argsz uint32
Flags uint32
// IO virtual address.

View file

@ -34,9 +34,10 @@ const (
// ID types for waitid(2), from include/uapi/linux/wait.h.
const (
P_ALL = 0x0
P_PID = 0x1
P_PGID = 0x2
P_ALL = 0x0
P_PID = 0x1
P_PGID = 0x2
P_PIDFD = 0x3
)
// WaitStatus represents a thread status, as returned by the wait* family of
@ -84,7 +85,8 @@ func (ws WaitStatus) Exited() bool {
// with WIFSIGNALED.
func (ws WaitStatus) Signaled() bool {
// ws&0x7f != 0 (exited) and ws&0x7f != 0x7f (stopped or continued)
return ((ws&0x7f)+1)>>1 != 0
bits := ws & 0x7f
return bits != 0 && bits != 0x7f
}
// CoreDumped returns true if ws indicates that a core dump was produced,

View file

@ -14,6 +14,11 @@
package linux
import (
"encoding/binary"
"structs"
)
// Constants for extended attributes.
const (
XATTR_NAME_MAX = 255
@ -37,3 +42,112 @@ const (
XATTR_USER_PREFIX = "user."
XATTR_USER_PREFIX_LEN = len(XATTR_USER_PREFIX)
)
// Constants for POSIX ACL extended attributes.
const (
// Extended attribute names for POSIX ACLs.
XATTR_NAME_POSIX_ACL_ACCESS = XATTR_SYSTEM_PREFIX + "posix_acl_access"
XATTR_NAME_POSIX_ACL_DEFAULT = XATTR_SYSTEM_PREFIX + "posix_acl_default"
POSIX_ACL_XATTR_VERSION = 2
// ACL_UNDEFINED_ID is the ID for entries that do not contain a
// named user or group.
ACL_UNDEFINED_ID = 0xffffffff
// ACL entry tags.
ACL_USER_OBJ = 0x01
ACL_USER = 0x02
ACL_GROUP_OBJ = 0x04
ACL_GROUP = 0x08
ACL_MASK = 0x10
ACL_OTHER = 0x20
// ACL entry permission bits.
ACL_READ = 0x04
ACL_WRITE = 0x02
ACL_EXECUTE = 0x01
)
// PosixACLXattrEntry is a single entry in the userspace representation
// of a POSIX ACL. It corresponds to Linux's struct posix_acl_xattr_entry.
//
// All fields in PosixACLXattrEntry are stored as little-endian.
//
// +marshal dynamic
type PosixACLXattrEntry struct {
_ structs.HostLayout
Tag uint16
Perm uint16
ID uint32
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (a *PosixACLXattrEntry) SizeBytes() int {
return 8
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (a *PosixACLXattrEntry) MarshalBytes(dst []byte) []byte {
binary.LittleEndian.PutUint16(dst[0:], a.Tag)
binary.LittleEndian.PutUint16(dst[2:], a.Perm)
binary.LittleEndian.PutUint32(dst[4:], a.ID)
return dst[8:]
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (a *PosixACLXattrEntry) UnmarshalBytes(src []byte) []byte {
a.Tag = binary.LittleEndian.Uint16(src[0:])
a.Perm = binary.LittleEndian.Uint16(src[2:])
a.ID = binary.LittleEndian.Uint32(src[4:])
return src[8:]
}
// PosixACLXattr is the userspace representation of a POSIX ACL.
//
// +marshal dynamic
type PosixACLXattr struct {
_ structs.HostLayout
// Version is the POSIX ACL version, stored as little-endian.
Version uint32
// Entries contains the ACL entries.
Entries []PosixACLXattrEntry `hostlayout:"ignore"`
}
// posixACLXattrHeaderSize is the size in bytes of the header.
const posixACLXattrHeaderSize = 4
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (a *PosixACLXattr) SizeBytes() int {
return posixACLXattrHeaderSize + len(a.Entries)*(*PosixACLXattrEntry)(nil).SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (a *PosixACLXattr) MarshalBytes(dst []byte) []byte {
binary.LittleEndian.PutUint32(dst, a.Version)
dst = dst[posixACLXattrHeaderSize:]
for _, entry := range a.Entries {
dst = entry.MarshalBytes(dst)
}
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (a *PosixACLXattr) UnmarshalBytes(src []byte) []byte {
a.Version = binary.LittleEndian.Uint32(src)
src = src[posixACLXattrHeaderSize:]
for len(src) >= (*PosixACLXattrEntry)(nil).SizeBytes() {
var entry PosixACLXattrEntry
src = entry.UnmarshalBytes(src)
a.Entries = append(a.Entries, entry)
}
return src
}