snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1

Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом
без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в
каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для
неё не нужна.

Module path github.com/sagernet/gvisor сохранён намеренно: на него
опирается replace-директива суперпроекта.

Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show
и переносилась на новый пин копированием.

SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
Leadaxe 2026-08-04 15:50:08 +03:00
commit 2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions

96
pkg/abi/linux/aio.go Normal file
View file

@ -0,0 +1,96 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import "encoding/binary"
// AIORing is struct aio_ring, from fs/aio.c, without the trailing
// variable-length array.
type AIORing struct {
ID uint32
Nr uint32
Head uint32
Tail uint32
Magic uint32
CompatFeatures uint32
IncompatFeatures uint32
HeaderLength uint32
}
// AIORingSize is sizeof(struct aio_ring).
const AIORingSize = 32
// AIO_RING_MAGIC is fs/aio.c:AIO_RING_MAGIC, the expected value of
// AIORing.Magic.
const AIO_RING_MAGIC = 0xa10a10a1
// I/O commands.
const (
IOCB_CMD_PREAD = 0
IOCB_CMD_PWRITE = 1
IOCB_CMD_FSYNC = 2
IOCB_CMD_FDSYNC = 3
// 4 was the experimental IOCB_CMD_PREADX.
IOCB_CMD_POLL = 5
IOCB_CMD_NOOP = 6
IOCB_CMD_PREADV = 7
IOCB_CMD_PWRITEV = 8
)
// I/O flags.
const (
IOCB_FLAG_RESFD = 1
IOCB_FLAG_IOPRIO = 2
)
// IOCallback describes an I/O request.
//
// The priority field is currently ignored in the implementation below. Also
// note that the IOCB_FLAG_RESFD feature is not supported.
//
// +marshal
type IOCallback struct {
Data uint64
Key uint32
_ uint32
OpCode uint16
ReqPrio int16
FD int32
Buf uint64
Bytes uint64
Offset int64
Reserved2 uint64
Flags uint32
// eventfd to signal if IOCB_FLAG_RESFD is set in flags.
ResFD int32
}
// IOEvent describes an I/O result.
//
// +marshal
// +stateify savable
type IOEvent struct {
Data uint64
Obj uint64
Result int64
Result2 int64
}
// IOEventSize is the size of an ioEvent encoded.
var IOEventSize = binary.Size(IOEvent{})

View file

@ -0,0 +1,24 @@
// Copyright 2020 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.
//go:build amd64
// +build amd64
package linux
// Start and end addresses of the vsyscall page.
const (
VSyscallStartAddr uint64 = 0xffffffffff600000
VSyscallEndAddr uint64 = 0xffffffffff601000
)

23
pkg/abi/linux/audit.go Normal file
View file

@ -0,0 +1,23 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Audit numbers identify different system call APIs, from <uapi/linux/audit.h>
const (
// AUDIT_ARCH_X86_64 identifies AMD64.
AUDIT_ARCH_X86_64 = 0xc000003e
// AUDIT_ARCH_AARCH64 identifies ARM64.
AUDIT_ARCH_AARCH64 = 0xc00000b7
)

35
pkg/abi/linux/bpf.go Normal file
View file

@ -0,0 +1,35 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// BPFInstruction is a raw BPF virtual machine instruction.
//
// +marshal slice:BPFInstructionSlice
// +stateify savable
type BPFInstruction struct {
// OpCode is the operation to execute.
OpCode uint16
// JumpIfTrue is the number of instructions to skip if OpCode is a
// conditional instruction and the condition is true.
JumpIfTrue uint8
// JumpIfFalse is the number of instructions to skip if OpCode is a
// conditional instruction and the condition is false.
JumpIfFalse uint8
// K is a constant parameter. The meaning depends on the value of OpCode.
K uint32
}

337
pkg/abi/linux/capability.go Normal file
View file

@ -0,0 +1,337 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"strings"
)
// A Capability represents the ability to perform a privileged operation.
type Capability int
// Capabilities defined by Linux. Taken from the kernel's
// include/uapi/linux/capability.h. See capabilities(7) or that file for more
// detailed capability descriptions.
const (
CAP_CHOWN = Capability(0)
CAP_DAC_OVERRIDE = Capability(1)
CAP_DAC_READ_SEARCH = Capability(2)
CAP_FOWNER = Capability(3)
CAP_FSETID = Capability(4)
CAP_KILL = Capability(5)
CAP_SETGID = Capability(6)
CAP_SETUID = Capability(7)
CAP_SETPCAP = Capability(8)
CAP_LINUX_IMMUTABLE = Capability(9)
CAP_NET_BIND_SERVICE = Capability(10)
CAP_NET_BROADCAST = Capability(11)
CAP_NET_ADMIN = Capability(12)
CAP_NET_RAW = Capability(13)
CAP_IPC_LOCK = Capability(14)
CAP_IPC_OWNER = Capability(15)
CAP_SYS_MODULE = Capability(16)
CAP_SYS_RAWIO = Capability(17)
CAP_SYS_CHROOT = Capability(18)
CAP_SYS_PTRACE = Capability(19)
CAP_SYS_PACCT = Capability(20)
CAP_SYS_ADMIN = Capability(21)
CAP_SYS_BOOT = Capability(22)
CAP_SYS_NICE = Capability(23)
CAP_SYS_RESOURCE = Capability(24)
CAP_SYS_TIME = Capability(25)
CAP_SYS_TTY_CONFIG = Capability(26)
CAP_MKNOD = Capability(27)
CAP_LEASE = Capability(28)
CAP_AUDIT_WRITE = Capability(29)
CAP_AUDIT_CONTROL = Capability(30)
CAP_SETFCAP = Capability(31)
CAP_MAC_OVERRIDE = Capability(32)
CAP_MAC_ADMIN = Capability(33)
CAP_SYSLOG = Capability(34)
CAP_WAKE_ALARM = Capability(35)
CAP_BLOCK_SUSPEND = Capability(36)
CAP_AUDIT_READ = Capability(37)
CAP_PERFMON = Capability(38)
CAP_BPF = Capability(39)
CAP_CHECKPOINT_RESTORE = Capability(40)
// CAP_LAST_CAP is the highest-numbered capability.
// Search for "CAP_LAST_CAP" to find other places that need to change.
CAP_LAST_CAP = CAP_CHECKPOINT_RESTORE
)
// Ok returns true if cp is a supported capability.
func (cp Capability) Ok() bool {
return cp >= 0 && cp <= CAP_LAST_CAP
}
// String returns the capability name.
func (cp Capability) String() string {
switch cp {
case CAP_CHOWN:
return "CAP_CHOWN"
case CAP_DAC_OVERRIDE:
return "CAP_DAC_OVERRIDE"
case CAP_DAC_READ_SEARCH:
return "CAP_DAC_READ_SEARCH"
case CAP_FOWNER:
return "CAP_FOWNER"
case CAP_FSETID:
return "CAP_FSETID"
case CAP_KILL:
return "CAP_KILL"
case CAP_SETGID:
return "CAP_SETGID"
case CAP_SETUID:
return "CAP_SETUID"
case CAP_SETPCAP:
return "CAP_SETPCAP"
case CAP_LINUX_IMMUTABLE:
return "CAP_LINUX_IMMUTABLE"
case CAP_NET_BIND_SERVICE:
return "CAP_NET_BIND_SERVICE"
case CAP_NET_BROADCAST:
return "CAP_NET_BROADCAST"
case CAP_NET_ADMIN:
return "CAP_NET_ADMIN"
case CAP_NET_RAW:
return "CAP_NET_RAW"
case CAP_IPC_LOCK:
return "CAP_IPC_LOCK"
case CAP_IPC_OWNER:
return "CAP_IPC_OWNER"
case CAP_SYS_MODULE:
return "CAP_SYS_MODULE"
case CAP_SYS_RAWIO:
return "CAP_SYS_RAWIO"
case CAP_SYS_CHROOT:
return "CAP_SYS_CHROOT"
case CAP_SYS_PTRACE:
return "CAP_SYS_PTRACE"
case CAP_SYS_PACCT:
return "CAP_SYS_PACCT"
case CAP_SYS_ADMIN:
return "CAP_SYS_ADMIN"
case CAP_SYS_BOOT:
return "CAP_SYS_BOOT"
case CAP_SYS_NICE:
return "CAP_SYS_NICE"
case CAP_SYS_RESOURCE:
return "CAP_SYS_RESOURCE"
case CAP_SYS_TIME:
return "CAP_SYS_TIME"
case CAP_SYS_TTY_CONFIG:
return "CAP_SYS_TTY_CONFIG"
case CAP_MKNOD:
return "CAP_MKNOD"
case CAP_LEASE:
return "CAP_LEASE"
case CAP_AUDIT_WRITE:
return "CAP_AUDIT_WRITE"
case CAP_AUDIT_CONTROL:
return "CAP_AUDIT_CONTROL"
case CAP_SETFCAP:
return "CAP_SETFCAP"
case CAP_MAC_OVERRIDE:
return "CAP_MAC_OVERRIDE"
case CAP_MAC_ADMIN:
return "CAP_MAC_ADMIN"
case CAP_SYSLOG:
return "CAP_SYSLOG"
case CAP_WAKE_ALARM:
return "CAP_WAKE_ALARM"
case CAP_BLOCK_SUSPEND:
return "CAP_BLOCK_SUSPEND"
case CAP_AUDIT_READ:
return "CAP_AUDIT_READ"
default:
return "UNKNOWN"
}
}
// TrimmedString returns the capability name without the "CAP_" prefix.
func (cp Capability) TrimmedString() string {
const capPrefix = "CAP_"
s := cp.String()
if !strings.HasPrefix(s, capPrefix) {
return s
}
// This could use strings.TrimPrefix, but that function doesn't guarantee
// that it won't allocate a new string, whereas string slicing does.
// In the case of this function, since Capability.String returns a constant
// string, the underlying set of bytes backing that string will never be
// garbage-collected. Therefore, we always want to use a string slice that
// points to this same constant set of bytes, rather than risking
// allocating a new string.
return s[len(capPrefix):]
}
// CapabilityFromString converts a string to a capability.
// If the capability doesn't exist, its second return value is `false`.
// The capability name is expected to include the "CAP_" prefix.
func CapabilityFromString(capability string) (Capability, bool) {
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
if !cp.Ok() {
continue
}
if cp.String() == capability {
return cp, true
}
}
return -1, false
}
// AllCapabilities returns a list of all defined capabilities.
func AllCapabilities() []Capability {
allCapapabilities := make([]Capability, 0, CAP_LAST_CAP+1)
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
if !cp.Ok() {
continue
}
allCapapabilities = append(allCapapabilities, cp)
}
return allCapapabilities
}
// Version numbers used by the capget/capset syscalls, defined in Linux's
// include/uapi/linux/capability.h.
const (
// LINUX_CAPABILITY_VERSION_1 causes the data pointer to be
// interpreted as a pointer to a single cap_user_data_t. Since capability
// sets are 64 bits and the "capability sets" in cap_user_data_t are 32
// bits only, this causes the upper 32 bits to be implicitly 0.
LINUX_CAPABILITY_VERSION_1 = 0x19980330
// LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the
// data pointer to be interpreted as a pointer to an array of 2
// cap_user_data_t, using the second to store the 32 MSB of each capability
// set. Versions 2 and 3 are identical, but Linux printk's a warning on use
// of version 2 due to a userspace API defect.
LINUX_CAPABILITY_VERSION_2 = 0x20071026
LINUX_CAPABILITY_VERSION_3 = 0x20080522
// HighestCapabilityVersion is the highest supported
// LINUX_CAPABILITY_VERSION_* version.
HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3
)
// Constants that are used by file capability extended attributes, defined
// in Linux's include/uapi/linux/capability.h.
const (
// VFS_CAP_FLAGS_EFFECTIVE allows the effective capability set to be
// initialized with the permitted file capabilities.
VFS_CAP_FLAGS_EFFECTIVE = 0x000001
// VFS_CAP_REVISION_2 allows for file capability masks that are 64
// bits in size, and was necessary as the number of supported
// capabilities grew beyond 32.
VFS_CAP_REVISION_2 = 0x02000000
// VFS_CAP_REVISION_3 are provided to support namespaced file capabilities.
// As with version 2 file capabilities, version 3 capability
// masks are 64 bits in size. But in addition, the root user
// ID of namespace is encoded in the security.capability
// extended attribute.
VFS_CAP_REVISION_3 = 0x03000000
VFS_CAP_REVISION_MASK = 0xFF000000
// XATTR_CAPS_SZ_2 is sizeof(struct vfs_cap_data).
XATTR_CAPS_SZ_2 = 20
// XATTR_CAPS_SZ_3 is sizeof(struct vfs_ns_cap_data).
XATTR_CAPS_SZ_3 = 24
)
// VfsCapData is equivalent to Linux's struct vfs_cap_data.
//
// +marshal
type VfsCapData struct {
MagicEtc uint32
PermittedLo uint32
InheritableLo uint32
PermittedHi uint32
InheritableHi uint32
}
// Permitted returns the permitted capability set.
func (c *VfsCapData) Permitted() uint64 {
return uint64(c.PermittedHi)<<32 | uint64(c.PermittedLo)
}
// Inheritable returns the inheritable capability set.
func (c *VfsCapData) Inheritable() uint64 {
return uint64(c.InheritableHi)<<32 | uint64(c.InheritableLo)
}
// IsRevision2 returns true if c is v2.
func (c *VfsCapData) IsRevision2() bool {
return (c.MagicEtc & VFS_CAP_REVISION_MASK) == VFS_CAP_REVISION_2
}
// ToString marshals c into bytes and returns it as a string.
func (c *VfsCapData) ToString() string {
buf := make([]byte, c.SizeBytes())
c.MarshalUnsafe(buf)
return string(buf)
}
// VfsNsCapData is equivalent to Linux's struct vfs_ns_cap_data.
//
// +marshal
type VfsNsCapData struct {
VfsCapData
RootID uint32
}
// ConvertToV3 converts c to v3 file capabilities.
func (c *VfsNsCapData) ConvertToV3(rootid uint32) {
c.RootID = rootid
if c.IsRevision2() {
// Change to v3 while retaining the effective bit.
c.MagicEtc = VFS_CAP_REVISION_3 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
}
}
// ConvertToV2 converts c to v2 file capabilities.
func (c *VfsNsCapData) ConvertToV2() {
c.RootID = 0
if !c.IsRevision2() {
// Change to v2 while retaining the effective bit.
c.MagicEtc = VFS_CAP_REVISION_2 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
}
}
// ToString marshals c into bytes and returns it as a string.
func (c *VfsNsCapData) ToString() string {
if c.IsRevision2() {
return c.VfsCapData.ToString()
}
buf := make([]byte, c.SizeBytes())
c.MarshalUnsafe(buf)
return string(buf)
}
// CapUserHeader is equivalent to Linux's cap_user_header_t.
//
// +marshal
type CapUserHeader struct {
Version uint32
Pid int32
}
// CapUserData is equivalent to Linux's cap_user_data_t.
//
// +marshal slice:CapUserDataSlice
type CapUserData struct {
Effective uint32
Permitted uint32
Inheritable uint32
}

71
pkg/abi/linux/clone.go Normal file
View file

@ -0,0 +1,71 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Clone constants per clone(2).
const (
CSIGNAL = 0xff
CLONE_VM = 0x100
CLONE_FS = 0x200
CLONE_FILES = 0x400
CLONE_SIGHAND = 0x800
CLONE_PIDFD = 0x1000
CLONE_PTRACE = 0x2000
CLONE_VFORK = 0x4000
CLONE_PARENT = 0x8000
CLONE_THREAD = 0x10000
CLONE_NEWNS = 0x20000
CLONE_SYSVSEM = 0x40000
CLONE_SETTLS = 0x80000
CLONE_PARENT_SETTID = 0x100000
CLONE_CHILD_CLEARTID = 0x200000
CLONE_DETACHED = 0x400000
CLONE_UNTRACED = 0x800000
CLONE_CHILD_SETTID = 0x1000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWUTS = 0x4000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWUSER = 0x10000000
CLONE_NEWPID = 0x20000000
CLONE_NEWNET = 0x40000000
CLONE_IO = 0x80000000
// Only passable via clone3(2).
CLONE_CLEAR_SIGHAND = 0x100000000
CLONE_INTO_CGROUP = 0x200000000
// Sizeof first published struct.
CLONE_ARGS_SIZE_VER0 = 64
// Sizeof third published struct.
CLONE_ARGS_SIZE_VER2 = 88
)
// CloneArgs is struct clone_args, from include/uapi/linux/sched.h.
//
// +marshal
type CloneArgs struct {
Flags uint64
Pidfd uint64
ChildTID uint64
ParentTID uint64
ExitSignal uint64
Stack uint64
StackSize uint64
TLS uint64
SetTID uint64
SetTIDSize uint64
Cgroup uint64
}

36
pkg/abi/linux/context.go Normal file
View file

@ -0,0 +1,36 @@
// Copyright 2021 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 (
"github.com/sagernet/gvisor/pkg/context"
)
// contextID is the linux package's type for context.Context.Value keys.
type contextID int
const (
// CtxSignalNoInfoFunc is a Context.Value key for a function to send signals.
CtxSignalNoInfoFunc contextID = iota
)
// SignalNoInfoFuncFromContext returns a callback function that can be used to send a
// signal to the given context.
func SignalNoInfoFuncFromContext(ctx context.Context) func(Signal) error {
if f := ctx.Value(CtxSignalNoInfoFunc); f != nil {
return f.(func(Signal) error)
}
return nil
}

72
pkg/abi/linux/dev.go Normal file
View file

@ -0,0 +1,72 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// MakeDeviceID encodes a major and minor device number into a single device ID.
//
// Format (see linux/kdev_t.h:new_encode_dev):
//
// Bits 7:0 - minor bits 7:0
// Bits 19:8 - major bits 11:0
// Bits 31:20 - minor bits 19:8
func MakeDeviceID(major uint16, minor uint32) uint32 {
return (minor & 0xff) | ((uint32(major) & 0xfff) << 8) | ((minor >> 8) << 20)
}
// DecodeDeviceID decodes a device ID into major and minor device numbers.
func DecodeDeviceID(rdev uint32) (uint16, uint32) {
major := uint16((rdev >> 8) & 0xfff)
minor := (rdev & 0xff) | ((rdev >> 20) << 8)
return major, minor
}
// Character device IDs.
//
// See Documentations/devices.txt and uapi/linux/major.h.
const (
// UNNAMED_MAJOR is the major device number for "unnamed" devices, whose
// minor numbers are dynamically allocated by the kernel.
UNNAMED_MAJOR = 0
// MEM_MAJOR is the major device number for "memory" character devices.
MEM_MAJOR = 1
// TTYAUX_MAJOR is the major device number for alternate TTY devices.
TTYAUX_MAJOR = 5
// MISC_MAJOR is the major device number for non-serial mice, misc feature
// devices.
MISC_MAJOR = 10
// UNIX98_PTY_MASTER_MAJOR is the initial major device number for
// Unix98 PTY masters.
UNIX98_PTY_MASTER_MAJOR = 128
// UNIX98_PTY_REPLICA_MAJOR is the initial major device number for
// Unix98 PTY replicas.
UNIX98_PTY_REPLICA_MAJOR = 136
)
// Minor device numbers for TTYAUX_MAJOR.
const (
// PTMX_MINOR is the minor device number for /dev/ptmx.
PTMX_MINOR = 2
)
// from Linux include/drm/drm_accel.h
const (
// ACCEL_MAJOR is the major device number for compute accelerator devices.
ACCEL_MAJOR = 121
)

158
pkg/abi/linux/elf.go Normal file
View file

@ -0,0 +1,158 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Linux auxiliary vector entry types.
const (
// AT_NULL is the end of the auxiliary vector.
AT_NULL = 0
// AT_IGNORE should be ignored.
AT_IGNORE = 1
// AT_EXECFD is the file descriptor of the program.
AT_EXECFD = 2
// AT_PHDR points to the program headers.
AT_PHDR = 3
// AT_PHENT is the size of a program header entry.
AT_PHENT = 4
// AT_PHNUM is the number of program headers.
AT_PHNUM = 5
// AT_PAGESZ is the system page size.
AT_PAGESZ = 6
// AT_BASE is the base address of the interpreter.
AT_BASE = 7
// AT_FLAGS are flags.
AT_FLAGS = 8
// AT_ENTRY is the program entry point.
AT_ENTRY = 9
// AT_NOTELF indicates that the program is not an ELF binary.
AT_NOTELF = 10
// AT_UID is the real UID.
AT_UID = 11
// AT_EUID is the effective UID.
AT_EUID = 12
// AT_GID is the real GID.
AT_GID = 13
// AT_EGID is the effective GID.
AT_EGID = 14
// AT_PLATFORM is a string identifying the CPU.
AT_PLATFORM = 15
// AT_HWCAP are arch-dependent CPU capabilities.
AT_HWCAP = 16
// AT_CLKTCK is the frequency used by times(2).
AT_CLKTCK = 17
// AT_SECURE indicate secure mode.
AT_SECURE = 23
// AT_BASE_PLATFORM is a string identifying the "real" platform. It may
// differ from AT_PLATFORM.
AT_BASE_PLATFORM = 24
// AT_RANDOM points to 16-bytes of random data.
AT_RANDOM = 25
// AT_HWCAP2 is an extension of AT_HWCAP.
AT_HWCAP2 = 26
// AT_EXECFN is the path used to execute the program.
AT_EXECFN = 31
// AT_SYSINFO_EHDR is the address of the VDSO.
AT_SYSINFO_EHDR = 33
)
// ELF ET_CORE and ptrace GETREGSET/SETREGSET register set types.
//
// See include/uapi/linux/elf.h.
const (
// NT_PRSTATUS is for general purpose register.
NT_PRSTATUS = 0x1
// NT_PRFPREG is for float point register.
NT_PRFPREG = 0x2
// NT_X86_XSTATE is for x86 extended state using xsave.
NT_X86_XSTATE = 0x202
// NT_ARM_TLS is for ARM TLS register.
NT_ARM_TLS = 0x401
)
// ElfHeader64 is the ELF64 file header.
//
// +marshal
type ElfHeader64 struct {
Ident [16]byte // File identification.
Type uint16 // File type.
Machine uint16 // Machine architecture.
Version uint32 // ELF format version.
Entry uint64 // Entry point.
Phoff uint64 // Program header file offset.
Shoff uint64 // Section header file offset.
Flags uint32 // Architecture-specific flags.
Ehsize uint16 // Size of ELF header in bytes.
Phentsize uint16 // Size of program header entry.
Phnum uint16 // Number of program header entries.
Shentsize uint16 // Size of section header entry.
Shnum uint16 // Number of section header entries.
Shstrndx uint16 // Section name strings section.
}
// ElfSection64 is the ELF64 Section header.
//
// +marshal
type ElfSection64 struct {
Name uint32 // Section name (index into the section header string table).
Type uint32 // Section type.
Flags uint64 // Section flags.
Addr uint64 // Address in memory image.
Off uint64 // Offset in file.
Size uint64 // Size in bytes.
Link uint32 // Index of a related section.
Info uint32 // Depends on section type.
Addralign uint64 // Alignment in bytes.
Entsize uint64 // Size of each entry in section.
}
// ElfProg64 is the ELF64 Program header.
//
// +marshal
type ElfProg64 struct {
Type uint32 // Entry type.
Flags uint32 // Access permission flags.
Off uint64 // File offset of contents.
Vaddr uint64 // Virtual address in memory image.
Paddr uint64 // Physical address (not used).
Filesz uint64 // Size of contents in file.
Memsz uint64 // Size of contents in memory.
Align uint64 // Alignment in memory and file.
}

58
pkg/abi/linux/epoll.go Normal file
View file

@ -0,0 +1,58 @@
// Copyright 2019 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
// Event masks.
const (
EPOLLIN = 0x1
EPOLLPRI = 0x2
EPOLLOUT = 0x4
EPOLLERR = 0x8
EPOLLHUP = 0x10
EPOLLRDNORM = 0x40
EPOLLRDBAND = 0x80
EPOLLWRNORM = 0x100
EPOLLWRBAND = 0x200
EPOLLMSG = 0x400
EPOLLRDHUP = 0x2000
)
// Per-file descriptor flags.
const (
EPOLLEXCLUSIVE = 1 << 28
EPOLLWAKEUP = 1 << 29
EPOLLONESHOT = 1 << 30
EPOLLET = 1 << 31
// EP_PRIVATE_BITS is fs/eventpoll.c:EP_PRIVATE_BITS, the set of all bits
// in an epoll event mask that correspond to flags rather than I/O events.
EP_PRIVATE_BITS = EPOLLEXCLUSIVE | EPOLLWAKEUP | EPOLLONESHOT | EPOLLET
)
// Operation flags.
const (
EPOLL_CLOEXEC = 0x80000
EPOLL_NONBLOCK = 0x800
)
// Control operations.
const (
EPOLL_CTL_ADD = 0x1
EPOLL_CTL_DEL = 0x2
EPOLL_CTL_MOD = 0x3
)
// SizeOfEpollEvent is the size of EpollEvent struct.
var SizeOfEpollEvent = (*EpollEvent)(nil).SizeBytes()

View file

@ -0,0 +1,30 @@
// Copyright 2019 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.
//go:build amd64
// +build amd64
package linux
// EpollEvent is equivalent to struct epoll_event from epoll(2).
//
// +marshal slice:EpollEventSlice
type EpollEvent struct {
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
// __attribute__((packed)), such that there is no padding between Events
// and Data.
Data [2]int32
}

View file

@ -0,0 +1,29 @@
// Copyright 2020 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.
//go:build arm64
// +build arm64
package linux
// EpollEvent is equivalent to struct epoll_event from epoll(2).
//
// +marshal slice:EpollEventSlice
type EpollEvent struct {
Events uint32
// Linux makes struct epoll_event a __u64, necessitating 4 bytes of padding
// here.
_ int32
Data [2]int32
}

View file

@ -0,0 +1,187 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package errno holds errno codes for abi/linux.
package errno
// Errno represents a Linux errno value.
type Errno uint32
// Errno values from include/uapi/asm-generic/errno-base.h.
const (
NOERRNO = iota
EPERM
ENOENT
ESRCH
EINTR
EIO
ENXIO
E2BIG
ENOEXEC
EBADF
ECHILD // 10
EAGAIN
ENOMEM
EACCES
EFAULT
ENOTBLK
EBUSY
EEXIST
EXDEV
ENODEV
ENOTDIR // 20
EISDIR
EINVAL
ENFILE
EMFILE
ENOTTY
ETXTBSY
EFBIG
ENOSPC
ESPIPE
EROFS // 30
EMLINK
EPIPE
EDOM
ERANGE
// Errno values from include/uapi/asm-generic/errno.h.
EDEADLK
ENAMETOOLONG
ENOLCK
ENOSYS
ENOTEMPTY
ELOOP // 40
_ // Skip for EWOULDBLOCK = EAGAIN.
ENOMSG // 42
EIDRM
ECHRNG
EL2NSYNC
EL3HLT
EL3RST
ELNRNG
EUNATCH
ENOCSI
EL2HLT // 50
EBADE
EBADR
EXFULL
ENOANO
EBADRQC
EBADSLT
_ // Skip for EDEADLOCK = EDEADLK.
EBFONT
ENOSTR // 60
ENODATA
ETIME
ENOSR
ENONET
ENOPKG
EREMOTE
ENOLINK
EADV
ESRMNT
ECOMM // 70
EPROTO
EMULTIHOP
EDOTDOT
EBADMSG
EOVERFLOW
ENOTUNIQ
EBADFD
EREMCHG
ELIBACC
ELIBBAD // 80
ELIBSCN
ELIBMAX
ELIBEXEC
EILSEQ
ERESTART
ESTRPIPE
EUSERS
ENOTSOCK
EDESTADDRREQ
EMSGSIZE // 90
EPROTOTYPE
ENOPROTOOPT
EPROTONOSUPPORT
ESOCKTNOSUPPORT
EOPNOTSUPP
EPFNOSUPPORT
EAFNOSUPPORT
EADDRINUSE
EADDRNOTAVAIL
ENETDOWN // 100
ENETUNREACH
ENETRESET
ECONNABORTED
ECONNRESET
ENOBUFS
EISCONN
ENOTCONN
ESHUTDOWN
ETOOMANYREFS
ETIMEDOUT // 110
ECONNREFUSED
EHOSTDOWN
EHOSTUNREACH
EALREADY
EINPROGRESS
ESTALE
EUCLEAN
ENOTNAM
ENAVAIL
EISNAM // 120
EREMOTEIO
EDQUOT
ENOMEDIUM
EMEDIUMTYPE
ECANCELED
ENOKEY
EKEYEXPIRED
EKEYREVOKED
EKEYREJECTED
EOWNERDEAD // 130
ENOTRECOVERABLE
ERFKILL
EHWPOISON
)
// errnos derived from other errnos.
const (
EWOULDBLOCK = EAGAIN
EDEADLOCK = EDEADLK
)
// errnos for internal errors.
const (
// ERESTARTSYS is returned by an interrupted syscall to indicate that it
// should be converted to EINTR if interrupted by a signal delivered to a
// user handler without SA_RESTART set, and restarted otherwise.
ERESTARTSYS = 512
// ERESTARTNOINTR is returned by an interrupted syscall to indicate that it
// should always be restarted.
ERESTARTNOINTR = 513
// ERESTARTNOHAND is returned by an interrupted syscall to indicate that it
// should be converted to EINTR if interrupted by a signal delivered to a
// user handler, and restarted otherwise.
ERESTARTNOHAND = 514
// ERESTART_RESTARTBLOCK is returned by an interrupted syscall to indicate
// that it should be restarted using a custom function. The interrupted
// syscall must register a custom restart function by calling
// Task.SetRestartSyscallFn.
ERESTART_RESTARTBLOCK = 516
)

View file

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

93
pkg/abi/linux/errqueue.go Normal file
View file

@ -0,0 +1,93 @@
// Copyright 2020 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 (
"github.com/sagernet/gvisor/pkg/marshal"
)
// Socket error origin codes as defined in include/uapi/linux/errqueue.h.
const (
SO_EE_ORIGIN_NONE = 0
SO_EE_ORIGIN_LOCAL = 1
SO_EE_ORIGIN_ICMP = 2
SO_EE_ORIGIN_ICMP6 = 3
)
// SockExtendedErr represents struct sock_extended_err in Linux defined in
// include/uapi/linux/errqueue.h.
//
// +marshal
type SockExtendedErr struct {
Errno uint32
Origin uint8
Type uint8
Code uint8
Pad uint8
Info uint32
Data uint32
}
// SockErrCMsg represents the IP*_RECVERR control message.
type SockErrCMsg interface {
marshal.Marshallable
CMsgLevel() uint32
CMsgType() uint32
}
// SockErrCMsgIPv4 is the IP_RECVERR control message used in
// recvmsg(MSG_ERRQUEUE) by ipv4 sockets. This is equilavent to `struct errhdr`
// defined in net/ipv4/ip_sockglue.c:ip_recv_error().
//
// +marshal
type SockErrCMsgIPv4 struct {
SockExtendedErr
Offender SockAddrInet
}
var _ SockErrCMsg = (*SockErrCMsgIPv4)(nil)
// CMsgLevel implements SockErrCMsg.CMsgLevel.
func (*SockErrCMsgIPv4) CMsgLevel() uint32 {
return SOL_IP
}
// CMsgType implements SockErrCMsg.CMsgType.
func (*SockErrCMsgIPv4) CMsgType() uint32 {
return IP_RECVERR
}
// SockErrCMsgIPv6 is the IPV6_RECVERR control message used in
// recvmsg(MSG_ERRQUEUE) by ipv6 sockets. This is equilavent to `struct errhdr`
// defined in net/ipv6/datagram.c:ipv6_recv_error().
//
// +marshal
type SockErrCMsgIPv6 struct {
SockExtendedErr
Offender SockAddrInet6
}
var _ SockErrCMsg = (*SockErrCMsgIPv6)(nil)
// CMsgLevel implements SockErrCMsg.CMsgLevel.
func (*SockErrCMsgIPv6) CMsgLevel() uint32 {
return SOL_IPV6
}
// CMsgType implements SockErrCMsg.CMsgType.
func (*SockErrCMsgIPv6) CMsgType() uint32 {
return IPV6_RECVERR
}

22
pkg/abi/linux/eventfd.go Normal file
View file

@ -0,0 +1,22 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Constants for eventfd2(2).
const (
EFD_SEMAPHORE = 0x1
EFD_CLOEXEC = O_CLOEXEC
EFD_NONBLOCK = O_NONBLOCK
)

18
pkg/abi/linux/exec.go Normal file
View file

@ -0,0 +1,18 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// TASK_COMM_LEN is the task command name length.
const TASK_COMM_LEN = 16

25
pkg/abi/linux/fadvise.go Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2020 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
// Fadvise constants.
const (
POSIX_FADV_NORMAL = 0
POSIX_FADV_RANDOM = 1
POSIX_FADV_SEQUENTIAL = 2
POSIX_FADV_WILLNEED = 3
POSIX_FADV_DONTNEED = 4
POSIX_FADV_NOREUSE = 5
)

79
pkg/abi/linux/fcntl.go Normal file
View file

@ -0,0 +1,79 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Commands from linux/fcntl.h.
const (
F_DUPFD = 0
F_GETFD = 1
F_SETFD = 2
F_GETFL = 3
F_SETFL = 4
F_GETLK = 5
F_SETLK = 6
F_SETLKW = 7
F_SETOWN = 8
F_GETOWN = 9
F_SETSIG = 10
F_GETSIG = 11
F_SETOWN_EX = 15
F_GETOWN_EX = 16
F_OFD_GETLK = 36
F_OFD_SETLK = 37
F_OFD_SETLKW = 38
F_DUPFD_CLOEXEC = 1024 + 6
F_SETPIPE_SZ = 1024 + 7
F_GETPIPE_SZ = 1024 + 8
)
// Commands for F_SETLK.
const (
F_RDLCK = 0
F_WRLCK = 1
F_UNLCK = 2
)
// Flags for fcntl.
const (
FD_CLOEXEC = 0o0000001
)
// Flock is the lock structure for F_SETLK.
//
// +marshal
type Flock struct {
Type int16
Whence int16
_ [4]byte
Start int64
Len int64
PID int32
_ [4]byte
}
// Owner types for F_SETOWN_EX and F_GETOWN_EX.
const (
F_OWNER_TID = 0
F_OWNER_PID = 1
F_OWNER_PGRP = 2
)
// FOwnerEx is the owner structure for F_SETOWN_EX and F_GETOWN_EX.
//
// +marshal
type FOwnerEx struct {
Type int32
PID int32
}

437
pkg/abi/linux/file.go Normal file
View file

@ -0,0 +1,437 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"fmt"
"strings"
"github.com/sagernet/gvisor/pkg/abi"
)
// Constants for open(2).
const (
O_ACCMODE = 0o00000003
O_RDONLY = 0o00000000
O_WRONLY = 0o00000001
O_RDWR = 0o00000002
O_CREAT = 0o00000100
O_EXCL = 0o00000200
O_NOCTTY = 0o00000400
O_TRUNC = 0o00001000
O_APPEND = 0o00002000
O_NONBLOCK = 0o00004000
O_DSYNC = 0o00010000
O_ASYNC = 0o00020000
O_NOATIME = 0o01000000
O_CLOEXEC = 0o02000000
O_SYNC = 0o04000000 // __O_SYNC in Linux
O_PATH = 0o10000000
O_TMPFILE = 0o20000000 // __O_TMPFILE in Linux
)
// Constants for fstatat(2).
const (
AT_SYMLINK_NOFOLLOW = 0x100
)
// Constants for mount(2).
const (
MS_RDONLY = 0x1
MS_NOSUID = 0x2
MS_NODEV = 0x4
MS_NOEXEC = 0x8
MS_SYNCHRONOUS = 0x10
MS_REMOUNT = 0x20
MS_MANDLOCK = 0x40
MS_DIRSYNC = 0x80
MS_NOATIME = 0x400
MS_NODIRATIME = 0x800
MS_BIND = 0x1000
MS_MOVE = 0x2000
MS_REC = 0x4000
MS_POSIXACL = 0x10000
MS_UNBINDABLE = 0x20000
MS_PRIVATE = 0x40000
MS_SLAVE = 0x80000
MS_SHARED = 0x100000
MS_RELATIME = 0x200000
MS_KERNMOUNT = 0x400000
MS_I_VERSION = 0x800000
MS_STRICTATIME = 0x1000000
MS_MGC_VAL = 0xC0ED0000
MS_MGC_MSK = 0xffff0000
)
// Constants for umount2(2).
const (
MNT_FORCE = 0x1
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
UMOUNT_NOFOLLOW = 0x8
)
// Constants for unlinkat(2).
const (
AT_REMOVEDIR = 0x200
)
// Constants for linkat(2) and fchownat(2).
const (
AT_SYMLINK_FOLLOW = 0x400
AT_EMPTY_PATH = 0x1000
)
// Constants for faccessat2(2).
const (
AT_EACCESS = 0x200
)
// Constants for all file-related ...at(2) syscalls.
const (
AT_FDCWD = -100
)
// Special values for the ns field in utimensat(2).
const (
UTIME_NOW = ((1 << 30) - 1)
UTIME_OMIT = ((1 << 30) - 2)
)
// MaxSymlinkTraversals is the maximum number of links that will be followed by
// the kernel to resolve a symlink.
const MaxSymlinkTraversals = 40
// Constants for flock(2).
const (
LOCK_SH = 1 // shared lock
LOCK_EX = 2 // exclusive lock
LOCK_NB = 4 // or'd with one of the above to prevent blocking
LOCK_UN = 8 // remove lock
)
// Values for mode_t.
const (
S_IFMT = 0o170000
S_IFSOCK = 0o140000
S_IFLNK = 0o120000
S_IFREG = 0o100000
S_IFBLK = 0o60000
S_IFDIR = 0o40000
S_IFCHR = 0o20000
S_IFIFO = 0o10000
FileTypeMask = S_IFMT
ModeSocket = S_IFSOCK
ModeSymlink = S_IFLNK
ModeRegular = S_IFREG
ModeBlockDevice = S_IFBLK
ModeDirectory = S_IFDIR
ModeCharacterDevice = S_IFCHR
ModeNamedPipe = S_IFIFO
S_ISUID = 0o4000
S_ISGID = 0o2000
S_ISVTX = 0o1000
ModeSetUID = S_ISUID
ModeSetGID = S_ISGID
ModeSticky = S_ISVTX
ModeUserAll = 0o700
ModeUserRead = 0o400
ModeUserWrite = 0o200
ModeUserExec = 0o100
ModeGroupAll = 0o070
ModeGroupRead = 0o040
ModeGroupWrite = 0o020
ModeGroupExec = 0o010
ModeOtherAll = 0o007
ModeOtherRead = 0o004
ModeOtherWrite = 0o002
ModeOtherExec = 0o001
PermissionsMask = 0o777
)
// Values for linux_dirent64.d_type.
const (
DT_UNKNOWN = 0
DT_FIFO = 1
DT_CHR = 2
DT_DIR = 4
DT_BLK = 6
DT_REG = 8
DT_LNK = 10
DT_SOCK = 12
DT_WHT = 14
)
// DirentType are the friendly strings for linux_dirent64.d_type.
var DirentType = abi.ValueSet{
DT_UNKNOWN: "DT_UNKNOWN",
DT_FIFO: "DT_FIFO",
DT_CHR: "DT_CHR",
DT_DIR: "DT_DIR",
DT_BLK: "DT_BLK",
DT_REG: "DT_REG",
DT_LNK: "DT_LNK",
DT_SOCK: "DT_SOCK",
DT_WHT: "DT_WHT",
}
// Values for fs on-disk file types.
const (
FT_UNKNOWN = 0
FT_REG_FILE = 1
FT_DIR = 2
FT_CHRDEV = 3
FT_BLKDEV = 4
FT_FIFO = 5
FT_SOCK = 6
FT_SYMLINK = 7
FT_MAX = 8
)
// Conversion from fs on-disk file type to dirent type.
var direntTypeByFileType = [FT_MAX]uint8{
FT_UNKNOWN: DT_UNKNOWN,
FT_REG_FILE: DT_REG,
FT_DIR: DT_DIR,
FT_CHRDEV: DT_CHR,
FT_BLKDEV: DT_BLK,
FT_FIFO: DT_FIFO,
FT_SOCK: DT_SOCK,
FT_SYMLINK: DT_LNK,
}
// FileTypeToDirentType converts the on-disk file type (FT_*) to the directory
// entry type (DT_*).
func FileTypeToDirentType(filetype uint8) uint8 {
if filetype >= FT_MAX {
return DT_UNKNOWN
}
return direntTypeByFileType[filetype]
}
// Values for preadv2/pwritev2.
const (
// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
// silently ignored.
RWF_HIPRI = 0x00000001
RWF_DSYNC = 0x00000002
RWF_SYNC = 0x00000004
RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
)
// SizeOfStat is the size of a Stat struct.
var SizeOfStat = (*Stat)(nil).SizeBytes()
// Flags for statx.
const (
AT_NO_AUTOMOUNT = 0x800
AT_STATX_SYNC_TYPE = 0x6000
AT_STATX_SYNC_AS_STAT = 0x0000
AT_STATX_FORCE_SYNC = 0x2000
AT_STATX_DONT_SYNC = 0x4000
)
// Mask values for statx.
const (
STATX_TYPE = 0x00000001
STATX_MODE = 0x00000002
STATX_NLINK = 0x00000004
STATX_UID = 0x00000008
STATX_GID = 0x00000010
STATX_ATIME = 0x00000020
STATX_MTIME = 0x00000040
STATX_CTIME = 0x00000080
STATX_INO = 0x00000100
STATX_SIZE = 0x00000200
STATX_BLOCKS = 0x00000400
STATX_BASIC_STATS = 0x000007ff
STATX_BTIME = 0x00000800
STATX_ALL = 0x00000fff
STATX__RESERVED = 0x80000000
)
// Bitmasks for Statx.Attributes and Statx.AttributesMask, from
// include/uapi/linux/stat.h.
const (
STATX_ATTR_COMPRESSED = 0x00000004
STATX_ATTR_IMMUTABLE = 0x00000010
STATX_ATTR_APPEND = 0x00000020
STATX_ATTR_NODUMP = 0x00000040
STATX_ATTR_ENCRYPTED = 0x00000800
STATX_ATTR_AUTOMOUNT = 0x00001000
)
// Statx represents struct statx.
//
// +marshal boundCheck slice:StatxSlice
type Statx struct {
Mask uint32
Blksize uint32
Attributes uint64
Nlink uint32
UID uint32
GID uint32
Mode uint16
_ uint16
Ino uint64
Size uint64
Blocks uint64
AttributesMask uint64
Atime StatxTimestamp
Btime StatxTimestamp
Ctime StatxTimestamp
Mtime StatxTimestamp
RdevMajor uint32
RdevMinor uint32
DevMajor uint32
DevMinor uint32
}
// 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)
}
// SizeOfStatx is the size of a Statx struct.
var SizeOfStatx = (*Statx)(nil).SizeBytes()
// FileMode represents a mode_t.
//
// +marshal
type FileMode uint16
// Permissions returns just the permission bits.
func (m FileMode) Permissions() FileMode {
return m & PermissionsMask
}
// FileType returns just the file type bits.
func (m FileMode) FileType() FileMode {
return m & FileTypeMask
}
// ExtraBits returns everything but the file type and permission bits.
func (m FileMode) ExtraBits() FileMode {
return m &^ (PermissionsMask | FileTypeMask)
}
// IsDir returns true if file type represents a directory.
func (m FileMode) IsDir() bool {
return m.FileType() == S_IFDIR
}
// String returns a string representation of m.
func (m FileMode) String() string {
var s []string
if ft := m.FileType(); ft != 0 {
s = append(s, fileType.Parse(uint64(ft)))
}
if eb := m.ExtraBits(); eb != 0 {
s = append(s, modeExtraBits.Parse(uint64(eb)))
}
s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
return strings.Join(s, "|")
}
// DirentType maps file types to dirent types appropriate for (struct
// dirent)::d_type.
func (m FileMode) DirentType() uint8 {
switch m.FileType() {
case ModeSocket:
return DT_SOCK
case ModeSymlink:
return DT_LNK
case ModeRegular:
return DT_REG
case ModeBlockDevice:
return DT_BLK
case ModeDirectory:
return DT_DIR
case ModeCharacterDevice:
return DT_CHR
case ModeNamedPipe:
return DT_FIFO
default:
return DT_UNKNOWN
}
}
var modeExtraBits = abi.FlagSet{
{
Flag: ModeSetUID,
Name: "S_ISUID",
},
{
Flag: ModeSetGID,
Name: "S_ISGID",
},
{
Flag: ModeSticky,
Name: "S_ISVTX",
},
}
var fileType = abi.ValueSet{
ModeSocket: "S_IFSOCK",
ModeSymlink: "S_IFLINK",
ModeRegular: "S_IFREG",
ModeBlockDevice: "S_IFBLK",
ModeDirectory: "S_IFDIR",
ModeCharacterDevice: "S_IFCHR",
ModeNamedPipe: "S_IFIFO",
}
// Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
const (
MFD_CLOEXEC = 0x0001
MFD_ALLOW_SEALING = 0x0002
)
// Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
const (
F_LINUX_SPECIFIC_BASE = 1024
F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9
F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10
F_SEAL_SEAL = 0x0001 // Prevent further seals from being set.
F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
F_SEAL_GROW = 0x0004 // Prevent file from growing.
F_SEAL_WRITE = 0x0008 // Prevent writes.
)
// Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
const (
FALLOC_FL_KEEP_SIZE = 0x01
FALLOC_FL_PUNCH_HOLE = 0x02
FALLOC_FL_NO_HIDE_STALE = 0x04
FALLOC_FL_COLLAPSE_RANGE = 0x08
FALLOC_FL_ZERO_RANGE = 0x10
FALLOC_FL_INSERT_RANGE = 0x20
FALLOC_FL_UNSHARE_RANGE = 0x40
)
// Constants related to close_range(2). Source: /include/uapi/linux/close_range.h
const (
CLOSE_RANGE_UNSHARE = uint32(1 << 1)
CLOSE_RANGE_CLOEXEC = uint32(1 << 2)
)

View file

@ -0,0 +1,47 @@
// Copyright 2018 The gVisor Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build amd64
// +build amd64
package linux
// Constants for open(2).
const (
O_DIRECT = 0o00040000
O_LARGEFILE = 0o00100000
O_DIRECTORY = 0o00200000
O_NOFOLLOW = 0o00400000
)
// Stat represents struct stat.
//
// +marshal
type Stat struct {
Dev uint64
Ino uint64
Nlink uint64
Mode uint32
UID uint32
GID uint32
_ int32
Rdev uint64
Size int64
Blksize int64
Blocks int64
ATime Timespec
MTime Timespec
CTime Timespec
_ [3]int64
}

View file

@ -0,0 +1,48 @@
// Copyright 2019 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.
//go:build arm64
// +build arm64
package linux
// Constants for open(2).
const (
O_DIRECTORY = 0o00040000
O_NOFOLLOW = 0o00100000
O_DIRECT = 0o00200000
O_LARGEFILE = 0o00400000
)
// Stat represents struct stat.
//
// +marshal
type Stat struct {
Dev uint64
Ino uint64
Mode uint32
Nlink uint32
UID uint32
GID uint32
Rdev uint64
_ uint64
Size int64
Blksize int32
_ int32
Blocks int64
ATime Timespec
MTime Timespec
CTime Timespec
_ [2]int32
}

129
pkg/abi/linux/fs.go Normal file
View file

@ -0,0 +1,129 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Filesystem types used in statfs(2).
//
// See linux/magic.h.
const (
ANON_INODE_FS_MAGIC = 0x09041934
CGROUP_SUPER_MAGIC = 0x27e0eb
DEVPTS_SUPER_MAGIC = 0x00001cd1
EXT_SUPER_MAGIC = 0xef53
FUSE_SUPER_MAGIC = 0x65735546
MQUEUE_MAGIC = 0x19800202
NSFS_MAGIC = 0x6e736673
OVERLAYFS_SUPER_MAGIC = 0x794c7630
PIPEFS_MAGIC = 0x50495045
PROC_SUPER_MAGIC = 0x9fa0
RAMFS_MAGIC = 0x09041934
SOCKFS_MAGIC = 0x534F434B
SYSFS_MAGIC = 0x62656572
TMPFS_MAGIC = 0x01021994
V9FS_MAGIC = 0x01021997
)
// Filesystem path limits, from uapi/linux/limits.h.
const (
NAME_MAX = 255
PATH_MAX = 4096
)
// The bit mask f_flags in struct statfs, from include/linux/statfs.h
const (
ST_RDONLY = 0x0001
ST_NOSUID = 0x0002
ST_NODEV = 0x0004
ST_NOEXEC = 0x0008
ST_SYNCHRONOUS = 0x0010
ST_VALID = 0x0020
ST_MANDLOCK = 0x0040
ST_NOATIME = 0x0400
ST_NODIRATIME = 0x0800
ST_RELATIME = 0x1000
ST_NOSYMFOLLOW = 0x2000
)
// Statfs is struct statfs, from uapi/asm-generic/statfs.h.
//
// +marshal
type Statfs struct {
// Type is one of the filesystem magic values, defined above.
Type uint64
// BlockSize is the optimal transfer block size in bytes.
BlockSize int64
// Blocks is the maximum number of data blocks the filesystem may store, in
// units of BlockSize.
Blocks uint64
// BlocksFree is the number of free data blocks, in units of BlockSize.
BlocksFree uint64
// BlocksAvailable is the number of data blocks free for use by
// unprivileged users, in units of BlockSize.
BlocksAvailable uint64
// Files is the number of used file nodes on the filesystem.
Files uint64
// FileFress is the number of free file nodes on the filesystem.
FilesFree uint64
// FSID is the filesystem ID.
FSID [2]int32
// NameLength is the maximum file name length.
NameLength uint64
// FragmentSize is equivalent to BlockSize.
FragmentSize int64
// Flags is the set of filesystem mount flags.
Flags uint64
// Spare is unused.
Spare [4]uint64
}
// Whence argument to lseek(2), from include/uapi/linux/fs.h.
const (
SEEK_SET = 0
SEEK_CUR = 1
SEEK_END = 2
SEEK_DATA = 3
SEEK_HOLE = 4
)
// Sync_file_range flags, from include/uapi/linux/fs.h
const (
SYNC_FILE_RANGE_WAIT_BEFORE = 1
SYNC_FILE_RANGE_WRITE = 2
SYNC_FILE_RANGE_WAIT_AFTER = 4
)
// Flag argument to renameat2(2), from include/uapi/linux/fs.h.
const (
RENAME_NOREPLACE = (1 << 0) // Don't overwrite target.
RENAME_EXCHANGE = (1 << 1) // Exchange src and dst.
RENAME_WHITEOUT = (1 << 2) // Whiteout src.
)
// Overlayfs constants from include/linux/fs.h.
const (
WHITEOUT_MODE = 0
WHITEOUT_DEV = 0
)

1139
pkg/abi/linux/fuse.go Normal file

File diff suppressed because it is too large Load diff

80
pkg/abi/linux/futex.go Normal file
View file

@ -0,0 +1,80 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// From <linux/futex.h> and <sys/time.h>.
// Flags are used in syscall futex(2).
const (
FUTEX_WAIT = 0
FUTEX_WAKE = 1
FUTEX_FD = 2
FUTEX_REQUEUE = 3
FUTEX_CMP_REQUEUE = 4
FUTEX_WAKE_OP = 5
FUTEX_LOCK_PI = 6
FUTEX_UNLOCK_PI = 7
FUTEX_TRYLOCK_PI = 8
FUTEX_WAIT_BITSET = 9
FUTEX_WAKE_BITSET = 10
FUTEX_WAIT_REQUEUE_PI = 11
FUTEX_CMP_REQUEUE_PI = 12
FUTEX_PRIVATE_FLAG = 128
FUTEX_CLOCK_REALTIME = 256
)
// These are flags are from <linux/futex.h> and are used in FUTEX_WAKE_OP
// to define the operations.
const (
FUTEX_OP_SET = 0
FUTEX_OP_ADD = 1
FUTEX_OP_OR = 2
FUTEX_OP_ANDN = 3
FUTEX_OP_XOR = 4
FUTEX_OP_OPARG_SHIFT = 8
FUTEX_OP_CMP_EQ = 0
FUTEX_OP_CMP_NE = 1
FUTEX_OP_CMP_LT = 2
FUTEX_OP_CMP_LE = 3
FUTEX_OP_CMP_GT = 4
FUTEX_OP_CMP_GE = 5
)
// FUTEX_TID_MASK is the TID portion of a PI futex word.
const FUTEX_TID_MASK = 0x3fffffff
// Constants used for priority-inheritance futexes.
const (
FUTEX_WAITERS = 0x80000000
FUTEX_OWNER_DIED = 0x40000000
)
// FUTEX_BITSET_MATCH_ANY has all bits set.
const FUTEX_BITSET_MATCH_ANY = 0xffffffff
// ROBUST_LIST_LIMIT protects against a deliberately circular list.
const ROBUST_LIST_LIMIT = 2048
// RobustListHead corresponds to Linux's struct robust_list_head.
//
// +marshal
type RobustListHead struct {
List uint64
FutexOffset uint64
ListOpPending uint64
}
// SizeOfRobustListHead is the size of a RobustListHead struct.
var SizeOfRobustListHead = (*RobustListHead)(nil).SizeBytes()

97
pkg/abi/linux/inotify.go Normal file
View file

@ -0,0 +1,97 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Inotify events observable by userspace. These directly correspond to
// filesystem operations and there may only be a single of them per inotify
// event read from an inotify fd.
const (
// IN_ACCESS indicates a file was accessed.
IN_ACCESS = 0x00000001
// IN_MODIFY indicates a file was modified.
IN_MODIFY = 0x00000002
// IN_ATTRIB indicates a watch target's metadata changed.
IN_ATTRIB = 0x00000004
// IN_CLOSE_WRITE indicates a writable file was closed.
IN_CLOSE_WRITE = 0x00000008
// IN_CLOSE_NOWRITE indicates a non-writable file was closed.
IN_CLOSE_NOWRITE = 0x00000010
// IN_OPEN indicates a file was opened.
IN_OPEN = 0x00000020
// IN_MOVED_FROM indicates a file was moved from X.
IN_MOVED_FROM = 0x00000040
// IN_MOVED_TO indicates a file was moved to Y.
IN_MOVED_TO = 0x00000080
// IN_CREATE indicates a file was created in a watched directory.
IN_CREATE = 0x00000100
// IN_DELETE indicates a file was deleted in a watched directory.
IN_DELETE = 0x00000200
// IN_DELETE_SELF indicates a watch target itself was deleted.
IN_DELETE_SELF = 0x00000400
// IN_MOVE_SELF indicates a watch target itself was moved.
IN_MOVE_SELF = 0x00000800
// IN_ALL_EVENTS is a mask for all observable userspace events.
IN_ALL_EVENTS = 0x00000fff
)
// Inotify control events. These may be present in their own events, or ORed
// with other observable events.
const (
// IN_UNMOUNT indicates the backing filesystem was unmounted.
IN_UNMOUNT = 0x00002000
// IN_Q_OVERFLOW indicates the event queued overflowed.
IN_Q_OVERFLOW = 0x00004000
// IN_IGNORED indicates a watch was removed, either implicitly or through
// inotify_rm_watch(2).
IN_IGNORED = 0x00008000
// IN_ISDIR indicates the subject of an event was a directory.
IN_ISDIR = 0x40000000
)
// Feature flags for inotify_add_watch(2).
const (
// IN_ONLYDIR indicates that a path should be watched only if it's a
// directory.
IN_ONLYDIR = 0x01000000
// IN_DONT_FOLLOW indicates that the watch path shouldn't be resolved if
// it's a symlink.
IN_DONT_FOLLOW = 0x02000000
// IN_EXCL_UNLINK indicates events to this watch from unlinked objects
// should be filtered out.
IN_EXCL_UNLINK = 0x04000000
// IN_MASK_ADD indicates the provided mask should be ORed into any existing
// watch on the provided path.
IN_MASK_ADD = 0x20000000
// IN_ONESHOT indicates the watch should be removed after one event.
IN_ONESHOT = 0x80000000
)
// Feature flags for inotify_init1(2).
const (
// IN_CLOEXEC is an alias for O_CLOEXEC. It indicates that the inotify
// fd should be closed on exec(2) and friends.
IN_CLOEXEC = 0x00080000
// IN_NONBLOCK is an alias for O_NONBLOCK. It indicates I/O syscall on the
// inotify fd should not block.
IN_NONBLOCK = 0x00000800
)
// ALL_INOTIFY_BITS contains all the bits for all possible inotify events. It's
// defined in the Linux source at "include/linux/inotify.h".
const ALL_INOTIFY_BITS = IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |
IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE |
IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_Q_OVERFLOW |
IN_IGNORED | IN_ONLYDIR | IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD |
IN_ISDIR | IN_ONESHOT

186
pkg/abi/linux/ioctl.go Normal file
View file

@ -0,0 +1,186 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// ioctl(2) requests provided by asm-generic/ioctls.h
//
// These are ordered by request number (low byte).
const (
TCGETS = 0x00005401
TCSETS = 0x00005402
TCSETSW = 0x00005403
TCSETSF = 0x00005404
TCSBRK = 0x00005409
TIOCEXCL = 0x0000540c
TIOCNXCL = 0x0000540d
TIOCSCTTY = 0x0000540e
TIOCGPGRP = 0x0000540f
TIOCSPGRP = 0x00005410
TIOCOUTQ = 0x00005411
TIOCSTI = 0x00005412
TIOCGWINSZ = 0x00005413
TIOCSWINSZ = 0x00005414
TIOCMGET = 0x00005415
TIOCMBIS = 0x00005416
TIOCMBIC = 0x00005417
TIOCMSET = 0x00005418
TIOCINQ = 0x0000541b
FIONREAD = TIOCINQ
TIOCPKT = 0x00005420
FIONBIO = 0x00005421
TIOCSETD = 0x00005423
TIOCNOTTY = 0x00005422
TIOCGETD = 0x00005424
TCSBRKP = 0x00005425
TIOCSBRK = 0x00005427
TIOCCBRK = 0x00005428
TIOCGSID = 0x00005429
TIOCGPTN = 0x80045430
TIOCSPTLCK = 0x40045431
TIOCGDEV = 0x80045432
TIOCVHANGUP = 0x00005437
TIOCGPKT = 0x80045438
TCFLSH = 0x0000540b
TIOCCONS = 0x0000541d
TIOCSSERIAL = 0x0000541f
TIOCGEXCL = 0x80045440
TIOCGPTPEER = 0x80045441
TIOCGICOUNT = 0x0000545d
FIONCLEX = 0x00005450
FIOCLEX = 0x00005451
FIOASYNC = 0x00005452
FIOSETOWN = 0x00008901
SIOCSPGRP = 0x00008902
FIOGETOWN = 0x00008903
SIOCGPGRP = 0x00008904
)
// ioctl(2) requests provided by uapi/linux/sockios.h
const (
SIOCGIFNAME = 0x8910
SIOCGIFCONF = 0x8912
SIOCGIFFLAGS = 0x8913
SIOCGIFADDR = 0x8915
SIOCGIFDSTADDR = 0x8917
SIOCGIFBRDADDR = 0x8919
SIOCGIFNETMASK = 0x891b
SIOCGIFMETRIC = 0x891d
SIOCGIFMTU = 0x8921
SIOCGIFMEM = 0x891f
SIOCGIFHWADDR = 0x8927
SIOCGIFINDEX = 0x8933
SIOCGIFPFLAGS = 0x8935
SIOCGIFTXQLEN = 0x8942
SIOCETHTOOL = 0x8946
SIOCGMIIPHY = 0x8947
SIOCGMIIREG = 0x8948
SIOCGIFMAP = 0x8970
)
// ioctl(2) requests provided by uapi/asm-generic/sockios.h
const (
SIOCGSTAMP = 0x8906
)
// ioctl(2) directions. Used to calculate requests number.
// Constants from asm-generic/ioctl.h.
const (
IOC_NONE = 0
IOC_WRITE = 1
IOC_READ = 2
)
// Constants from asm-generic/ioctl.h.
const (
IOC_NRBITS = 8
IOC_TYPEBITS = 8
IOC_SIZEBITS = 14
IOC_DIRBITS = 2
IOC_NRSHIFT = 0
IOC_TYPESHIFT = IOC_NRSHIFT + IOC_NRBITS
IOC_SIZESHIFT = IOC_TYPESHIFT + IOC_TYPEBITS
IOC_DIRSHIFT = IOC_SIZESHIFT + IOC_SIZEBITS
)
// IOC outputs the result of _IOC macro in include/uapi/asm-generic/ioctl.h.
func IOC(dir, typ, nr, size uint32) uint32 {
return uint32(dir)<<IOC_DIRSHIFT | typ<<IOC_TYPESHIFT | nr<<IOC_NRSHIFT | size<<IOC_SIZESHIFT
}
// IO outputs the result of _IO macro in include/uapi/asm-generic/ioctl.h.
func IO(typ, nr uint32) uint32 {
return IOC(IOC_NONE, typ, nr, 0)
}
// IOR outputs the result of _IOR macro in include/uapi/asm-generic/ioctl.h.
func IOR(typ, nr, size uint32) uint32 {
return IOC(IOC_READ, typ, nr, size)
}
// IOW outputs the result of _IOW macro in include/uapi/asm-generic/ioctl.h.
func IOW(typ, nr, size uint32) uint32 {
return IOC(IOC_WRITE, typ, nr, size)
}
// IOWR outputs the result of _IOWR macro in include/uapi/asm-generic/ioctl.h.
func IOWR(typ, nr, size uint32) uint32 {
return IOC(IOC_READ|IOC_WRITE, typ, nr, size)
}
// IOC_NR outputs the result of IOC_NR macro in
// include/uapi/asm-generic/ioctl.h.
func IOC_NR(nr uint32) uint32 {
return (nr >> IOC_NRSHIFT) & ((1 << IOC_NRBITS) - 1)
}
// IOC_SIZE outputs the result of IOC_SIZE macro in
// include/uapi/asm-generic/ioctl.h.
func IOC_SIZE(nr uint32) uint32 {
return (nr >> IOC_SIZESHIFT) & ((1 << IOC_SIZEBITS) - 1)
}
/* Used for packet mode */
const (
TIOCPKT_DATA = 0
TIOCPKT_FLUSHREAD = 1
TIOCPKT_FLUSHWRITE = 2
TIOCPKT_STOP = 4
TIOCPKT_START = 8
TIOCPKT_NOSTOP = 16
TIOCPKT_DOSTOP = 32
TIOCPKT_IOCTL = 64
)
// Kcov ioctls from include/uapi/linux/kcov.h.
var (
KCOV_INIT_TRACE = IOR('c', 1, 8)
KCOV_ENABLE = IO('c', 100)
KCOV_DISABLE = IO('c', 101)
)
// Kcov trace types from include/uapi/linux/kcov.h.
const (
KCOV_TRACE_PC = 0
KCOV_TRACE_CMP = 1
)
// Kcov state constants from include/uapi/linux/kcov.h.
const (
KCOV_MODE_DISABLED = 0
KCOV_MODE_INIT = 1
KCOV_MODE_TRACE_PC = 2
KCOV_MODE_TRACE_CMP = 3
)

View file

@ -0,0 +1,33 @@
// Copyright 2020 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
// ioctl(2) request numbers from linux/if_tun.h
var (
TUNSETIFF = IOW('T', 202, 4)
TUNSETPERSIST = IOW('T', 203, 4)
TUNGETIFF = IOR('T', 210, 4)
)
// Flags from net/if_tun.h
const (
IFF_TUN = 0x0001
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
IFF_NOFILTER = 0x1000
IFF_TUN_EXCL = 0x8000
// According to linux/if_tun.h "This flag has no real effect"
IFF_ONE_QUEUE = 0x2000
)

238
pkg/abi/linux/iouring.go Normal file
View file

@ -0,0 +1,238 @@
// Copyright 2022 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
// Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h.
const (
IORING_SETUP_IOPOLL = (1 << 0)
IORING_SETUP_SQPOLL = (1 << 1)
IORING_SETUP_SQ_AFF = (1 << 2)
IORING_SETUP_CQSIZE = (1 << 3)
IORING_SETUP_CLAMP = (1 << 4)
IORING_SETUP_ATTACH_WQ = (1 << 5)
IORING_SETUP_R_DISABLED = (1 << 6)
IORING_SETUP_SUBMIT_ALL = (1 << 7)
)
// Constants for io_uring_enter(2). See include/uapi/linux/io_uring.h.
const (
IORING_ENTER_GETEVENTS = (1 << 0)
)
// Constants for IoUringParams.Features. See include/uapi/linux/io_uring.h.
const (
IORING_FEAT_SINGLE_MMAP = (1 << 0)
)
// Constants for IO_URING. See include/uapi/linux/io_uring.h.
const (
IORING_SETUP_COOP_TASKRUN = (1 << 8)
IORING_SETUP_TASKRUN_FLAG = (1 << 9)
IORING_SETUP_SQE128 = (1 << 10)
IORING_SETUP_CQE32 = (1 << 11)
)
// Constants for IO_URING. See io_uring/io_uring.c.
const (
IORING_MAX_ENTRIES = (1 << 15) // 32768
IORING_MAX_CQ_ENTRIES = (2 * IORING_MAX_ENTRIES)
)
// Constants for the offsets for the application to mmap the data it needs.
// See include/uapi/linux/io_uring.h.
const (
IORING_OFF_SQ_RING = 0
IORING_OFF_CQ_RING = 0x8000000
IORING_OFF_SQES = 0x10000000
)
// Constants for the IO_URING opcodes. See include/uapi/linux/io_uring.h.
const (
IORING_OP_NOP = 0
IORING_OP_READV = 1
)
// IORingIndex represents SQE array indexes.
//
// +marshal
type IORingIndex uint32
// IOSqRingOffsets implements io_sqring_offsets struct.
// IOSqRingOffsets represents offsets into IORings.
// See struct io_sqring_offsets in include/uapi/linux/io_uring.h.
//
// +marshal
type IOSqRingOffsets struct {
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
RingEntries uint32 // Offset to io_rings.sq_ring_entries
Flags uint32 // Offset to io_rings.sq_flags
Dropped uint32 // Offset to io_rings.sq_dropped
Array uint32 // Offset to an array of SQE indices
Resv1 uint32 // Currently reserved and expected to be zero
Resv2 uint64 // Currently reserved and expected to be zero
}
// IOCqRingOffsets implements io_cqring_offsets struct.
// IOCqRingOffsets represents offsets into IORings.
// See struct io_cqring_offsets in include/uapi/linux/io_uring.h.
//
// +marshal
type IOCqRingOffsets struct {
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
RingEntries uint32 // Offset to io_rings.cq_ring_entries
Overflow uint32 // Offset to io_rings.cq_overflow
Cqes uint32 // Offset to io_rings.cqes
Flags uint32 // Offset to io_rings.cq_flags
Resv1 uint32 // Currently reserved and expected to be zero
Resv2 uint64 // Currently reserved and expected to be zero
}
// IOUringParams implements io_uring_params struct.
// See struct io_uring_params in include/uapi/linux/io_uring.h.
//
// +marshal
type IOUringParams struct {
SqEntries uint32
CqEntries uint32
Flags uint32
SqThreadCPU uint32
SqThreadIdle uint32
Features uint32
WqFd uint32
Resv [3]uint32
SqOff IOSqRingOffsets
CqOff IOCqRingOffsets
}
// IOUringCqe implements IO completion data structure (Completion Queue Entry)
// io_uring_cqe struct. As we don't currently support IORING_SETUP_CQE32 flag
// its size is 16 bytes.
// See struct io_uring_cqe in include/uapi/linux/io_uring.h.
//
// +marshal
// +stateify savable
type IOUringCqe struct {
UserData uint64
Res int32
Flags uint32
}
// IOUring implements io_uring struct.
// See struct io_uring in io_uring/io_uring.c.
//
// +marshal
// +stateify savable
type IOUring struct {
// Both head and tail should be cacheline aligned. And we assume that
// cacheline size is 64 bytes.
Head uint32
_ [60]byte
Tail uint32
_ [60]byte
}
// IORings implements io_rings struct.
// This struct describes layout of the mapped region backed by the ringBuffersFile.
// See struct io_rings in io_uring/io_uring.c.
//
// +marshal
// +stateify savable
type IORings struct {
Sq IOUring
Cq IOUring
SqRingMask uint32
CqRingMask uint32
SqRingEntries uint32
CqRingEntries uint32
sqDropped uint32
sqFlags int32
cqFlags uint32
CqOverflow uint32
_ [32]byte // Padding so cqes is cacheline aligned
// Linux has an additional field struct io_uring_cqe cqes[], which represents
// a dynamic array. We don't include it here in order to enable marshalling.
}
// IOUringSqe implements io_uring_sqe struct.
// This struct represents IO submission data structure (Submission Queue Entry). As we don't yet
// support IORING_SETUP_SQE128 flag, its size is 64 bytes with no extra padding at the end.
// See include/uapi/linux/io_uring.h.
//
// +marshal
// +stateify savable
type IOUringSqe struct {
Opcode uint8
Flags uint8
IoPrio uint16
Fd int32
OffOrAddrOrCmdOp uint64
AddrOrSpliceOff uint64
Len uint32
specialFlags uint32
UserData uint64
BufIndexOrGroup uint16
personality uint16
spliceFDOrFileIndex int32
addr3 uint64
_ uint64
}
const (
_IOSqRingOffset = 0 // +checkoffset . IORings.Sq
_IOSqRingOffsetHead = 0 // +checkoffset . IOUring.Head
_IOSqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
_IOSqRingOffsetMask = 256 // +checkoffset . IORings.SqRingMask
_IOSqRingOffsetEntries = 264 // +checkoffset . IORings.SqRingEntries
_IOSqRingOffsetFlags = 276 // +checkoffset . IORings.sqFlags
_IOSqRingOffsetDropped = 272 // +checkoffset . IORings.sqDropped
)
// PreComputedIOSqRingOffsets returns precomputed values for IOSqRingOffsets.
func PreComputedIOSqRingOffsets() IOSqRingOffsets {
return IOSqRingOffsets{
Head: _IOSqRingOffset + _IOSqRingOffsetHead,
Tail: _IOSqRingOffset + _IOSqRingOffsetTail,
RingMask: _IOSqRingOffsetMask,
RingEntries: _IOSqRingOffsetEntries,
Flags: _IOSqRingOffsetFlags,
Dropped: _IOSqRingOffsetDropped,
}
}
const (
_IOCqRingOffset = 128 // +checkoffset . IORings.Cq
_IOCqRingOffsetHead = 0 // +checkoffset . IOUring.Head
_IOCqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
_IOCqRingOffsetMask = 260 // +checkoffset . IORings.CqRingMask
_IOCqRingOffsetEntries = 268 // +checkoffset . IORings.CqRingEntries
_IOCqRingOffsetFlags = 280 // +checkoffset . IORings.cqFlags
_IOCqRingOffsetOverflow = 284 // +checkoffset . IORings.CqOverflow
)
// PreComputedIOCqRingOffsets returns precomputed values for IOCqRingOffsets.
func PreComputedIOCqRingOffsets() IOCqRingOffsets {
return IOCqRingOffsets{
Head: _IOCqRingOffset + _IOCqRingOffsetHead,
Tail: _IOCqRingOffset + _IOCqRingOffsetTail,
RingMask: _IOCqRingOffsetMask,
RingEntries: _IOCqRingOffsetEntries,
Overflow: _IOCqRingOffsetOverflow,
Flags: _IOCqRingOffsetFlags,
}
}

171
pkg/abi/linux/ip.go Normal file
View file

@ -0,0 +1,171 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// IP protocols
const (
IPPROTO_IP = 0
IPPROTO_ICMP = 1
IPPROTO_IGMP = 2
IPPROTO_IPIP = 4
IPPROTO_TCP = 6
IPPROTO_EGP = 8
IPPROTO_PUP = 12
IPPROTO_UDP = 17
IPPROTO_IDP = 22
IPPROTO_TP = 29
IPPROTO_DCCP = 33
IPPROTO_IPV6 = 41
IPPROTO_RSVP = 46
IPPROTO_GRE = 47
IPPROTO_ESP = 50
IPPROTO_AH = 51
IPPROTO_ICMPV6 = 58
IPPROTO_MTP = 92
IPPROTO_BEETPH = 94
IPPROTO_ENCAP = 98
IPPROTO_PIM = 103
IPPROTO_COMP = 108
IPPROTO_SCTP = 132
IPPROTO_UDPLITE = 136
IPPROTO_MPLS = 137
IPPROTO_RAW = 255
)
// Socket options from uapi/linux/in.h
const (
IP_TOS = 1
IP_TTL = 2
IP_HDRINCL = 3
IP_OPTIONS = 4
IP_ROUTER_ALERT = 5
IP_RECVOPTS = 6
IP_RETOPTS = 7
IP_PKTINFO = 8
IP_PKTOPTIONS = 9
IP_MTU_DISCOVER = 10
IP_RECVERR = 11
IP_RECVTTL = 12
IP_RECVTOS = 13
IP_MTU = 14
IP_FREEBIND = 15
IP_IPSEC_POLICY = 16
IP_XFRM_POLICY = 17
IP_PASSSEC = 18
IP_TRANSPARENT = 19
IP_ORIGDSTADDR = 20
IP_RECVORIGDSTADDR = IP_ORIGDSTADDR
IP_MINTTL = 21
IP_NODEFRAG = 22
IP_CHECKSUM = 23
IP_BIND_ADDRESS_NO_PORT = 24
IP_RECVFRAGSIZE = 25
IP_RECVERR_RFC4884 = 26
IP_MULTICAST_IF = 32
IP_MULTICAST_TTL = 33
IP_MULTICAST_LOOP = 34
IP_ADD_MEMBERSHIP = 35
IP_DROP_MEMBERSHIP = 36
IP_UNBLOCK_SOURCE = 37
IP_BLOCK_SOURCE = 38
IP_ADD_SOURCE_MEMBERSHIP = 39
IP_DROP_SOURCE_MEMBERSHIP = 40
IP_MSFILTER = 41
MCAST_JOIN_GROUP = 42
MCAST_BLOCK_SOURCE = 43
MCAST_UNBLOCK_SOURCE = 44
MCAST_LEAVE_GROUP = 45
MCAST_JOIN_SOURCE_GROUP = 46
MCAST_LEAVE_SOURCE_GROUP = 47
MCAST_MSFILTER = 48
IP_MULTICAST_ALL = 49
IP_UNICAST_IF = 50
IP_LOCAL_PORT_RANGE = 51
)
// IP_MTU_DISCOVER values from uapi/linux/in.h
const (
IP_PMTUDISC_DONT = 0
IP_PMTUDISC_WANT = 1
IP_PMTUDISC_DO = 2
IP_PMTUDISC_PROBE = 3
IP_PMTUDISC_INTERFACE = 4
IP_PMTUDISC_OMIT = 5
)
// Socket options from uapi/linux/in6.h
const (
IPV6_ADDRFORM = 1
IPV6_2292PKTINFO = 2
IPV6_2292HOPOPTS = 3
IPV6_2292DSTOPTS = 4
IPV6_2292RTHDR = 5
IPV6_2292PKTOPTIONS = 6
IPV6_CHECKSUM = 7
IPV6_2292HOPLIMIT = 8
IPV6_NEXTHOP = 9
IPV6_FLOWINFO = 11
IPV6_UNICAST_HOPS = 16
IPV6_MULTICAST_IF = 17
IPV6_MULTICAST_HOPS = 18
IPV6_MULTICAST_LOOP = 19
IPV6_ADD_MEMBERSHIP = 20
IPV6_DROP_MEMBERSHIP = 21
IPV6_ROUTER_ALERT = 22
IPV6_MTU_DISCOVER = 23
IPV6_MTU = 24
IPV6_RECVERR = 25
IPV6_V6ONLY = 26
IPV6_JOIN_ANYCAST = 27
IPV6_LEAVE_ANYCAST = 28
IPV6_MULTICAST_ALL = 29
IPV6_ROUTER_ALERT_ISOLATE = 30
IPV6_RECVERR_RFC4884 = 31
IPV6_FLOWLABEL_MGR = 32
IPV6_FLOWINFO_SEND = 33
IPV6_IPSEC_POLICY = 34
IPV6_XFRM_POLICY = 35
IPV6_HDRINCL = 36
IPV6_RECVPKTINFO = 49
IPV6_PKTINFO = 50
IPV6_RECVHOPLIMIT = 51
IPV6_HOPLIMIT = 52
IPV6_RECVHOPOPTS = 53
IPV6_HOPOPTS = 54
IPV6_RTHDRDSTOPTS = 55
IPV6_RECVRTHDR = 56
IPV6_RTHDR = 57
IPV6_RECVDSTOPTS = 58
IPV6_DSTOPTS = 59
IPV6_RECVPATHMTU = 60
IPV6_PATHMTU = 61
IPV6_DONTFRAG = 62
IPV6_RECVTCLASS = 66
IPV6_TCLASS = 67
IPV6_AUTOFLOWLABEL = 70
IPV6_ADDR_PREFERENCES = 72
IPV6_MINHOPCOUNT = 73
IPV6_ORIGDSTADDR = 74
IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR
IPV6_TRANSPARENT = 75
IPV6_UNICAST_IF = 76
IPV6_RECVFRAGSIZE = 77
IPV6_FREEBIND = 78
)
// Socket options from uapi/linux/icmpv6.h
const (
ICMPV6_FILTER = 1
)

61
pkg/abi/linux/ipc.go Normal file
View file

@ -0,0 +1,61 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Control commands used with semctl, shmctl, and msgctl.
//
// Source: include/uapi/linux/ipc.h.
const (
IPC_RMID = 0
IPC_SET = 1
IPC_STAT = 2
IPC_INFO = 3
)
// Resource get request flags.
//
// Source: include/uapi/linux/ipc.h
const (
IPC_CREAT = 0o0001000
IPC_EXCL = 0o0002000
IPC_NOWAIT = 0o0004000
)
// IPC flags.
const (
IPC_PRIVATE = 0
)
// In Linux, amd64 does not enable CONFIG_ARCH_WANT_IPC_PARSE_VERSION, so SysV
// IPC unconditionally uses the "new" 64-bit structures that are needed for
// features like 32-bit UIDs.
// IPCPerm is equivalent to struct ipc64_perm.
//
// +marshal
type IPCPerm struct {
Key uint32
UID uint32
GID uint32
CUID uint32
CGID uint32
Mode uint16
_ uint16
Seq uint16
_ uint16
_ uint32
unused1 uint64
unused2 uint64
}

29
pkg/abi/linux/keyctl.go Normal file
View file

@ -0,0 +1,29 @@
// Copyright 2023 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
// Constants used by keyctl(2) and other keyrings-related syscalls.
// Source: include/uapi/linux/keyctl.h
const (
KEY_SPEC_SESSION_KEYRING = -3
)
const (
KEYCTL_GET_KEYRING_ID = 0
KEYCTL_JOIN_SESSION_KEYRING = 1
KEYCTL_SETPERM = 5
KEYCTL_DESCRIBE = 6
)

88
pkg/abi/linux/limits.go Normal file
View file

@ -0,0 +1,88 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Resources for getrlimit(2)/setrlimit(2)/prlimit(2).
const (
RLIMIT_CPU = 0
RLIMIT_FSIZE = 1
RLIMIT_DATA = 2
RLIMIT_STACK = 3
RLIMIT_CORE = 4
RLIMIT_RSS = 5
RLIMIT_NPROC = 6
RLIMIT_NOFILE = 7
RLIMIT_MEMLOCK = 8
RLIMIT_AS = 9
RLIMIT_LOCKS = 10
RLIMIT_SIGPENDING = 11
RLIMIT_MSGQUEUE = 12
RLIMIT_NICE = 13
RLIMIT_RTPRIO = 14
RLIMIT_RTTIME = 15
)
// RLimit corresponds to Linux's struct rlimit.
type RLimit struct {
// Cur specifies the soft limit.
Cur uint64
// Max specifies the hard limit.
Max uint64
}
const (
// RLimInfinity is RLIM_INFINITY on Linux.
RLimInfinity = ^uint64(0)
// DefaultStackSoftLimit is called _STK_LIM in Linux.
DefaultStackSoftLimit = 8 * 1024 * 1024
// DefaultNprocLimit is defined in kernel/fork.c:set_max_threads, and
// called MAX_THREADS / 2 in Linux.
DefaultNprocLimit = FUTEX_TID_MASK / 2
// DefaultNofileSoftLimit is called INR_OPEN_CUR in Linux.
DefaultNofileSoftLimit = 1024
// DefaultNofileHardLimit is called INR_OPEN_MAX in Linux.
DefaultNofileHardLimit = 4096
// DefaultMemlockLimit is called MLOCK_LIMIT in Linux.
DefaultMemlockLimit = 64 * 1024
// DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux.
DefaultMsgqueueLimit = 819200
)
// 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},
}

42
pkg/abi/linux/linux.go Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package linux contains the constants and types needed to interface with a
// Linux kernel.
package linux
// NumSoftIRQ is the number of software IRQs, exposed via /proc/stat.
//
// Defined in linux/interrupt.h.
const NumSoftIRQ = 10
// Sysinfo is the structure provided by sysinfo on linux versions > 2.3.48.
//
// +marshal
type Sysinfo struct {
Uptime int64
Loads [3]uint64
TotalRAM uint64
FreeRAM uint64
SharedRAM uint64
BufferRAM uint64
TotalSwap uint64
FreeSwap uint64
Procs uint16
_ [6]byte // Pad Procs to 64bits.
TotalHigh uint64
FreeHigh uint64
Unit uint32 `marshal:"unaligned"` // Struct ends mid-64-bit-word.
// The _f field in the glibc version of Sysinfo has size 0 on AMD64.
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,760 @@
// Automatically generated marshal implementation. See tools/go_marshal.
// If there are issues with build constraint aggregation, see
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
// come from the input set of files used to generate this file. This input set
// is filtered based on pre-defined file suffixes related to build constraints,
// see tools/defs.bzl:calculate_sets().
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
// +build amd64,amd64,amd64,amd64,amd64,amd64
package linux
import (
"io"
"reflect"
"runtime"
"unsafe"
"github.com/sagernet/gvisor/pkg/gohacks"
"github.com/sagernet/gvisor/pkg/hostarch"
"github.com/sagernet/gvisor/pkg/marshal"
)
// Marshallable types used by this file.
var (
_ marshal.Marshallable = (*EpollEvent)(nil)
_ marshal.Marshallable = (*IPCPerm)(nil)
_ marshal.Marshallable = (*PtraceRegs)(nil)
_ marshal.Marshallable = (*SemidDS)(nil)
_ marshal.Marshallable = (*Stat)(nil)
_ marshal.Marshallable = (*TimeT)(nil)
_ marshal.Marshallable = (*Timespec)(nil)
)
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (e *EpollEvent) SizeBytes() int {
return 4 +
4*2
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
dst = dst[4:]
for idx := 0; idx < 2; idx++ {
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
dst = dst[4:]
}
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
for idx := 0; idx < 2; idx++ {
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
}
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (e *EpollEvent) Packed() bool {
return true
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
size := e.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
return dst[size:]
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
size := e.SizeBytes()
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return e.CopyOutN(cc, addr, e.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return e.CopyInN(cc, addr, e.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return int64(length), err
}
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, 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 := cc.CopyInBytes(addr, 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
}
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, 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 := cc.CopyOutBytes(addr, 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
}
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
count := len(src)
if count == 0 {
return dst
}
size := (*EpollEvent)(nil).SizeBytes()
buf := dst[:size*count]
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
return dst[size*count:]
}
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
count := len(dst)
if count == 0 {
return src
}
size := (*EpollEvent)(nil).SizeBytes()
buf := src[:size*count]
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
return src[size*count:]
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *Stat) SizeBytes() int {
return 72 +
(*Timespec)(nil).SizeBytes() +
(*Timespec)(nil).SizeBytes() +
(*Timespec)(nil).SizeBytes() +
8*3
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (s *Stat) MarshalBytes(dst []byte) []byte {
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Nlink))
dst = dst[8:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
dst = dst[4:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
dst = dst[4:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
dst = dst[4:]
// Padding: dst[:sizeof(int32)] ~= int32(0)
dst = dst[4:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blksize))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
dst = dst[8:]
dst = s.ATime.MarshalUnsafe(dst)
dst = s.MTime.MarshalUnsafe(dst)
dst = s.CTime.MarshalUnsafe(dst)
// Padding: dst[:sizeof(int64)*3] ~= [3]int64{0}
dst = dst[8*(3):]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (s *Stat) UnmarshalBytes(src []byte) []byte {
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Nlink = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
// Padding: var _ int32 ~= src[:sizeof(int32)]
src = src[4:]
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Blksize = int64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
src = s.ATime.UnmarshalUnsafe(src)
src = s.MTime.UnmarshalUnsafe(src)
src = s.CTime.UnmarshalUnsafe(src)
// Padding: ~ copy([3]int64(s._), src[:sizeof(int64)*3])
src = src[8*(3):]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (s *Stat) Packed() bool {
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
return dst[size:]
}
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
return s.MarshalBytes(dst)
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
return s.UnmarshalBytes(src)
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
s.MarshalBytes(buf) // escapes: fallback.
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyOutN(cc, addr, s.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Unmarshal unconditionally. If we had a short copy-in, this results in a
// partially unmarshalled struct.
s.UnmarshalBytes(buf) // escapes: fallback.
return length, err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyInN(cc, addr, s.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := make([]byte, s.SizeBytes())
s.MarshalBytes(buf)
length, err := writer.Write(buf)
return int64(length), err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return int64(length), err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (p *PtraceRegs) SizeBytes() int {
return 216
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R15))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R14))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R13))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R12))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbp))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbx))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R11))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R10))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R9))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R8))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rax))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rcx))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdx))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsi))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdi))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Orig_rax))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rip))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Cs))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Eflags))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsp))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ss))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs_base))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs_base))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ds))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Es))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs))
dst = dst[8:]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
p.R15 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R14 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R13 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R12 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rbp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rbx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R11 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R10 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R9 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.R8 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rcx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rdx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rsi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rdi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Orig_rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rip = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Cs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Eflags = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Rsp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Ss = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Fs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Gs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Ds = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Es = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Fs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Gs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (p *PtraceRegs) Packed() bool {
return true
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
size := p.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
return dst[size:]
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
size := p.SizeBytes()
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return p.CopyOutN(cc, addr, p.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return p.CopyInN(cc, addr, p.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return int64(length), err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *SemidDS) SizeBytes() int {
return 40 +
(*IPCPerm)(nil).SizeBytes() +
(*TimeT)(nil).SizeBytes() +
(*TimeT)(nil).SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
dst = s.SemPerm.MarshalUnsafe(dst)
dst = s.SemOTime.MarshalUnsafe(dst)
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused1))
dst = dst[8:]
dst = s.SemCTime.MarshalUnsafe(dst)
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused2))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
dst = dst[8:]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
src = s.SemPerm.UnmarshalUnsafe(src)
src = s.SemOTime.UnmarshalUnsafe(src)
s.unused1 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
src = s.SemCTime.UnmarshalUnsafe(src)
s.unused2 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (s *SemidDS) Packed() bool {
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
return dst[size:]
}
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
return s.MarshalBytes(dst)
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
return s.UnmarshalBytes(src)
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
s.MarshalBytes(buf) // escapes: fallback.
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyOutN(cc, addr, s.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Unmarshal unconditionally. If we had a short copy-in, this results in a
// partially unmarshalled struct.
s.UnmarshalBytes(buf) // escapes: fallback.
return length, err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyInN(cc, addr, s.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := make([]byte, s.SizeBytes())
s.MarshalBytes(buf)
length, err := writer.Write(buf)
return int64(length), err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return int64(length), err
}

View file

@ -0,0 +1,119 @@
// automatically generated by stateify.
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
// +build amd64,amd64,amd64,amd64,amd64,amd64
package linux
import (
"context"
"github.com/sagernet/gvisor/pkg/state"
)
func (p *PtraceRegs) StateTypeName() string {
return "pkg/abi/linux.PtraceRegs"
}
func (p *PtraceRegs) StateFields() []string {
return []string{
"R15",
"R14",
"R13",
"R12",
"Rbp",
"Rbx",
"R11",
"R10",
"R9",
"R8",
"Rax",
"Rcx",
"Rdx",
"Rsi",
"Rdi",
"Orig_rax",
"Rip",
"Cs",
"Eflags",
"Rsp",
"Ss",
"Fs_base",
"Gs_base",
"Ds",
"Es",
"Fs",
"Gs",
}
}
func (p *PtraceRegs) beforeSave() {}
// +checklocksignore
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
p.beforeSave()
stateSinkObject.Save(0, &p.R15)
stateSinkObject.Save(1, &p.R14)
stateSinkObject.Save(2, &p.R13)
stateSinkObject.Save(3, &p.R12)
stateSinkObject.Save(4, &p.Rbp)
stateSinkObject.Save(5, &p.Rbx)
stateSinkObject.Save(6, &p.R11)
stateSinkObject.Save(7, &p.R10)
stateSinkObject.Save(8, &p.R9)
stateSinkObject.Save(9, &p.R8)
stateSinkObject.Save(10, &p.Rax)
stateSinkObject.Save(11, &p.Rcx)
stateSinkObject.Save(12, &p.Rdx)
stateSinkObject.Save(13, &p.Rsi)
stateSinkObject.Save(14, &p.Rdi)
stateSinkObject.Save(15, &p.Orig_rax)
stateSinkObject.Save(16, &p.Rip)
stateSinkObject.Save(17, &p.Cs)
stateSinkObject.Save(18, &p.Eflags)
stateSinkObject.Save(19, &p.Rsp)
stateSinkObject.Save(20, &p.Ss)
stateSinkObject.Save(21, &p.Fs_base)
stateSinkObject.Save(22, &p.Gs_base)
stateSinkObject.Save(23, &p.Ds)
stateSinkObject.Save(24, &p.Es)
stateSinkObject.Save(25, &p.Fs)
stateSinkObject.Save(26, &p.Gs)
}
func (p *PtraceRegs) afterLoad(context.Context) {}
// +checklocksignore
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &p.R15)
stateSourceObject.Load(1, &p.R14)
stateSourceObject.Load(2, &p.R13)
stateSourceObject.Load(3, &p.R12)
stateSourceObject.Load(4, &p.Rbp)
stateSourceObject.Load(5, &p.Rbx)
stateSourceObject.Load(6, &p.R11)
stateSourceObject.Load(7, &p.R10)
stateSourceObject.Load(8, &p.R9)
stateSourceObject.Load(9, &p.R8)
stateSourceObject.Load(10, &p.Rax)
stateSourceObject.Load(11, &p.Rcx)
stateSourceObject.Load(12, &p.Rdx)
stateSourceObject.Load(13, &p.Rsi)
stateSourceObject.Load(14, &p.Rdi)
stateSourceObject.Load(15, &p.Orig_rax)
stateSourceObject.Load(16, &p.Rip)
stateSourceObject.Load(17, &p.Cs)
stateSourceObject.Load(18, &p.Eflags)
stateSourceObject.Load(19, &p.Rsp)
stateSourceObject.Load(20, &p.Ss)
stateSourceObject.Load(21, &p.Fs_base)
stateSourceObject.Load(22, &p.Gs_base)
stateSourceObject.Load(23, &p.Ds)
stateSourceObject.Load(24, &p.Es)
stateSourceObject.Load(25, &p.Fs)
stateSourceObject.Load(26, &p.Gs)
}
func init() {
state.Register((*PtraceRegs)(nil))
}

View file

@ -0,0 +1,673 @@
// Automatically generated marshal implementation. See tools/go_marshal.
// If there are issues with build constraint aggregation, see
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
// come from the input set of files used to generate this file. This input set
// is filtered based on pre-defined file suffixes related to build constraints,
// see tools/defs.bzl:calculate_sets().
//go:build arm64 && arm64 && arm64 && arm64 && arm64
// +build arm64,arm64,arm64,arm64,arm64
package linux
import (
"io"
"reflect"
"runtime"
"unsafe"
"github.com/sagernet/gvisor/pkg/gohacks"
"github.com/sagernet/gvisor/pkg/hostarch"
"github.com/sagernet/gvisor/pkg/marshal"
)
// Marshallable types used by this file.
var (
_ marshal.Marshallable = (*EpollEvent)(nil)
_ marshal.Marshallable = (*IPCPerm)(nil)
_ marshal.Marshallable = (*PtraceRegs)(nil)
_ marshal.Marshallable = (*SemidDS)(nil)
_ marshal.Marshallable = (*Stat)(nil)
_ marshal.Marshallable = (*TimeT)(nil)
_ marshal.Marshallable = (*Timespec)(nil)
)
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (e *EpollEvent) SizeBytes() int {
return 8 +
4*2
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
dst = dst[4:]
// Padding: dst[:sizeof(int32)] ~= int32(0)
dst = dst[4:]
for idx := 0; idx < 2; idx++ {
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
dst = dst[4:]
}
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
// Padding: var _ int32 ~= src[:sizeof(int32)]
src = src[4:]
for idx := 0; idx < 2; idx++ {
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
}
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (e *EpollEvent) Packed() bool {
return true
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
size := e.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
return dst[size:]
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
size := e.SizeBytes()
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return e.CopyOutN(cc, addr, e.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return e.CopyInN(cc, addr, e.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
hdr.Len = e.SizeBytes()
hdr.Cap = e.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that e
// must live until the use above.
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
return int64(length), err
}
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, 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 := cc.CopyInBytes(addr, 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
}
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, 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 := cc.CopyOutBytes(addr, 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
}
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
count := len(src)
if count == 0 {
return dst
}
size := (*EpollEvent)(nil).SizeBytes()
buf := dst[:size*count]
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
return dst[size*count:]
}
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
count := len(dst)
if count == 0 {
return src
}
size := (*EpollEvent)(nil).SizeBytes()
buf := src[:size*count]
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
return src[size*count:]
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *Stat) SizeBytes() int {
return 72 +
(*Timespec)(nil).SizeBytes() +
(*Timespec)(nil).SizeBytes() +
(*Timespec)(nil).SizeBytes() +
4*2
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (s *Stat) MarshalBytes(dst []byte) []byte {
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
dst = dst[8:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
dst = dst[4:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Nlink))
dst = dst[4:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
dst = dst[4:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
dst = dst[4:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
dst = dst[8:]
// Padding: dst[:sizeof(uint64)] ~= uint64(0)
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
dst = dst[8:]
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Blksize))
dst = dst[4:]
// Padding: dst[:sizeof(int32)] ~= int32(0)
dst = dst[4:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
dst = dst[8:]
dst = s.ATime.MarshalUnsafe(dst)
dst = s.MTime.MarshalUnsafe(dst)
dst = s.CTime.MarshalUnsafe(dst)
// Padding: dst[:sizeof(int32)*2] ~= [2]int32{0}
dst = dst[4*(2):]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (s *Stat) UnmarshalBytes(src []byte) []byte {
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.Nlink = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
// Padding: var _ uint64 ~= src[:sizeof(uint64)]
src = src[8:]
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.Blksize = int32(hostarch.ByteOrder.Uint32(src[:4]))
src = src[4:]
// Padding: var _ int32 ~= src[:sizeof(int32)]
src = src[4:]
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
src = s.ATime.UnmarshalUnsafe(src)
src = s.MTime.UnmarshalUnsafe(src)
src = s.CTime.UnmarshalUnsafe(src)
// Padding: ~ copy([2]int32(s._), src[:sizeof(int32)*2])
src = src[4*(2):]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (s *Stat) Packed() bool {
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
return dst[size:]
}
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
return s.MarshalBytes(dst)
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
return s.UnmarshalBytes(src)
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
s.MarshalBytes(buf) // escapes: fallback.
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyOutN(cc, addr, s.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Unmarshal unconditionally. If we had a short copy-in, this results in a
// partially unmarshalled struct.
s.UnmarshalBytes(buf) // escapes: fallback.
return length, err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyInN(cc, addr, s.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := make([]byte, s.SizeBytes())
s.MarshalBytes(buf)
length, err := writer.Write(buf)
return int64(length), err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return int64(length), err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (p *PtraceRegs) SizeBytes() int {
return 24 +
8*31
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
for idx := 0; idx < 31; idx++ {
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Regs[idx]))
dst = dst[8:]
}
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Sp))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pc))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pstate))
dst = dst[8:]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
for idx := 0; idx < 31; idx++ {
p.Regs[idx] = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
}
p.Sp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Pc = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
p.Pstate = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (p *PtraceRegs) Packed() bool {
return true
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
size := p.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
return dst[size:]
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
size := p.SizeBytes()
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return p.CopyOutN(cc, addr, p.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return p.CopyInN(cc, addr, p.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
hdr.Len = p.SizeBytes()
hdr.Cap = p.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that p
// must live until the use above.
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
return int64(length), err
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *SemidDS) SizeBytes() int {
return 24 +
(*IPCPerm)(nil).SizeBytes() +
(*TimeT)(nil).SizeBytes() +
(*TimeT)(nil).SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
dst = s.SemPerm.MarshalUnsafe(dst)
dst = s.SemOTime.MarshalUnsafe(dst)
dst = s.SemCTime.MarshalUnsafe(dst)
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
dst = dst[8:]
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
dst = dst[8:]
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
src = s.SemPerm.UnmarshalUnsafe(src)
src = s.SemOTime.UnmarshalUnsafe(src)
src = s.SemCTime.UnmarshalUnsafe(src)
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
src = src[8:]
return src
}
// Packed implements marshal.Marshallable.Packed.
//
//go:nosplit
func (s *SemidDS) Packed() bool {
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
}
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
return dst[size:]
}
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
return s.MarshalBytes(dst)
}
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
size := s.SizeBytes()
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
return src[size:]
}
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
return s.UnmarshalBytes(src)
}
// CopyOutN implements marshal.Marshallable.CopyOutN.
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
s.MarshalBytes(buf) // escapes: fallback.
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyOut implements marshal.Marshallable.CopyOut.
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyOutN(cc, addr, s.SizeBytes())
}
// CopyInN implements marshal.Marshallable.CopyInN.
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Unmarshal unconditionally. If we had a short copy-in, this results in a
// partially unmarshalled struct.
s.UnmarshalBytes(buf) // escapes: fallback.
return length, err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return length, err
}
// CopyIn implements marshal.Marshallable.CopyIn.
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
return s.CopyInN(cc, addr, s.SizeBytes())
}
// WriteTo implements io.WriterTo.WriteTo.
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := make([]byte, s.SizeBytes())
s.MarshalBytes(buf)
length, err := writer.Write(buf)
return int64(length), err
}
// Construct a slice backed by dst's underlying memory.
var buf []byte
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
hdr.Len = s.SizeBytes()
hdr.Cap = s.SizeBytes()
length, err := writer.Write(buf)
// Since we bypassed the compiler's escape analysis, indicate that s
// must live until the use above.
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
return int64(length), err
}

View file

@ -0,0 +1,50 @@
// automatically generated by stateify.
//go:build arm64 && arm64 && arm64 && arm64 && arm64
// +build arm64,arm64,arm64,arm64,arm64
package linux
import (
"context"
"github.com/sagernet/gvisor/pkg/state"
)
func (p *PtraceRegs) StateTypeName() string {
return "pkg/abi/linux.PtraceRegs"
}
func (p *PtraceRegs) StateFields() []string {
return []string{
"Regs",
"Sp",
"Pc",
"Pstate",
}
}
func (p *PtraceRegs) beforeSave() {}
// +checklocksignore
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
p.beforeSave()
stateSinkObject.Save(0, &p.Regs)
stateSinkObject.Save(1, &p.Sp)
stateSinkObject.Save(2, &p.Pc)
stateSinkObject.Save(3, &p.Pstate)
}
func (p *PtraceRegs) afterLoad(context.Context) {}
// +checklocksignore
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &p.Regs)
stateSourceObject.Load(1, &p.Sp)
stateSourceObject.Load(2, &p.Pc)
stateSourceObject.Load(3, &p.Pstate)
}
func init() {
state.Register((*PtraceRegs)(nil))
}

View file

@ -0,0 +1,599 @@
// automatically generated by stateify.
package linux
import (
"context"
"github.com/sagernet/gvisor/pkg/state"
)
func (i *IOEvent) StateTypeName() string {
return "pkg/abi/linux.IOEvent"
}
func (i *IOEvent) StateFields() []string {
return []string{
"Data",
"Obj",
"Result",
"Result2",
}
}
func (i *IOEvent) beforeSave() {}
// +checklocksignore
func (i *IOEvent) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.Data)
stateSinkObject.Save(1, &i.Obj)
stateSinkObject.Save(2, &i.Result)
stateSinkObject.Save(3, &i.Result2)
}
func (i *IOEvent) afterLoad(context.Context) {}
// +checklocksignore
func (i *IOEvent) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.Data)
stateSourceObject.Load(1, &i.Obj)
stateSourceObject.Load(2, &i.Result)
stateSourceObject.Load(3, &i.Result2)
}
func (b *BPFInstruction) StateTypeName() string {
return "pkg/abi/linux.BPFInstruction"
}
func (b *BPFInstruction) StateFields() []string {
return []string{
"OpCode",
"JumpIfTrue",
"JumpIfFalse",
"K",
}
}
func (b *BPFInstruction) beforeSave() {}
// +checklocksignore
func (b *BPFInstruction) StateSave(stateSinkObject state.Sink) {
b.beforeSave()
stateSinkObject.Save(0, &b.OpCode)
stateSinkObject.Save(1, &b.JumpIfTrue)
stateSinkObject.Save(2, &b.JumpIfFalse)
stateSinkObject.Save(3, &b.K)
}
func (b *BPFInstruction) afterLoad(context.Context) {}
// +checklocksignore
func (b *BPFInstruction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &b.OpCode)
stateSourceObject.Load(1, &b.JumpIfTrue)
stateSourceObject.Load(2, &b.JumpIfFalse)
stateSourceObject.Load(3, &b.K)
}
func (f *FUSEHeaderIn) StateTypeName() string {
return "pkg/abi/linux.FUSEHeaderIn"
}
func (f *FUSEHeaderIn) StateFields() []string {
return []string{
"Len",
"Opcode",
"Unique",
"NodeID",
"UID",
"GID",
"PID",
}
}
func (f *FUSEHeaderIn) beforeSave() {}
// +checklocksignore
func (f *FUSEHeaderIn) StateSave(stateSinkObject state.Sink) {
f.beforeSave()
stateSinkObject.Save(0, &f.Len)
stateSinkObject.Save(1, &f.Opcode)
stateSinkObject.Save(2, &f.Unique)
stateSinkObject.Save(3, &f.NodeID)
stateSinkObject.Save(4, &f.UID)
stateSinkObject.Save(5, &f.GID)
stateSinkObject.Save(6, &f.PID)
}
func (f *FUSEHeaderIn) afterLoad(context.Context) {}
// +checklocksignore
func (f *FUSEHeaderIn) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &f.Len)
stateSourceObject.Load(1, &f.Opcode)
stateSourceObject.Load(2, &f.Unique)
stateSourceObject.Load(3, &f.NodeID)
stateSourceObject.Load(4, &f.UID)
stateSourceObject.Load(5, &f.GID)
stateSourceObject.Load(6, &f.PID)
}
func (f *FUSEHeaderOut) StateTypeName() string {
return "pkg/abi/linux.FUSEHeaderOut"
}
func (f *FUSEHeaderOut) StateFields() []string {
return []string{
"Len",
"Error",
"Unique",
}
}
func (f *FUSEHeaderOut) beforeSave() {}
// +checklocksignore
func (f *FUSEHeaderOut) StateSave(stateSinkObject state.Sink) {
f.beforeSave()
stateSinkObject.Save(0, &f.Len)
stateSinkObject.Save(1, &f.Error)
stateSinkObject.Save(2, &f.Unique)
}
func (f *FUSEHeaderOut) afterLoad(context.Context) {}
// +checklocksignore
func (f *FUSEHeaderOut) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &f.Len)
stateSourceObject.Load(1, &f.Error)
stateSourceObject.Load(2, &f.Unique)
}
func (i *IOUringCqe) StateTypeName() string {
return "pkg/abi/linux.IOUringCqe"
}
func (i *IOUringCqe) StateFields() []string {
return []string{
"UserData",
"Res",
"Flags",
}
}
func (i *IOUringCqe) beforeSave() {}
// +checklocksignore
func (i *IOUringCqe) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.UserData)
stateSinkObject.Save(1, &i.Res)
stateSinkObject.Save(2, &i.Flags)
}
func (i *IOUringCqe) afterLoad(context.Context) {}
// +checklocksignore
func (i *IOUringCqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.UserData)
stateSourceObject.Load(1, &i.Res)
stateSourceObject.Load(2, &i.Flags)
}
func (i *IOUring) StateTypeName() string {
return "pkg/abi/linux.IOUring"
}
func (i *IOUring) StateFields() []string {
return []string{
"Head",
"Tail",
}
}
func (i *IOUring) beforeSave() {}
// +checklocksignore
func (i *IOUring) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.Head)
stateSinkObject.Save(1, &i.Tail)
}
func (i *IOUring) afterLoad(context.Context) {}
// +checklocksignore
func (i *IOUring) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.Head)
stateSourceObject.Load(1, &i.Tail)
}
func (i *IORings) StateTypeName() string {
return "pkg/abi/linux.IORings"
}
func (i *IORings) StateFields() []string {
return []string{
"Sq",
"Cq",
"SqRingMask",
"CqRingMask",
"SqRingEntries",
"CqRingEntries",
"sqDropped",
"sqFlags",
"cqFlags",
"CqOverflow",
}
}
func (i *IORings) beforeSave() {}
// +checklocksignore
func (i *IORings) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.Sq)
stateSinkObject.Save(1, &i.Cq)
stateSinkObject.Save(2, &i.SqRingMask)
stateSinkObject.Save(3, &i.CqRingMask)
stateSinkObject.Save(4, &i.SqRingEntries)
stateSinkObject.Save(5, &i.CqRingEntries)
stateSinkObject.Save(6, &i.sqDropped)
stateSinkObject.Save(7, &i.sqFlags)
stateSinkObject.Save(8, &i.cqFlags)
stateSinkObject.Save(9, &i.CqOverflow)
}
func (i *IORings) afterLoad(context.Context) {}
// +checklocksignore
func (i *IORings) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.Sq)
stateSourceObject.Load(1, &i.Cq)
stateSourceObject.Load(2, &i.SqRingMask)
stateSourceObject.Load(3, &i.CqRingMask)
stateSourceObject.Load(4, &i.SqRingEntries)
stateSourceObject.Load(5, &i.CqRingEntries)
stateSourceObject.Load(6, &i.sqDropped)
stateSourceObject.Load(7, &i.sqFlags)
stateSourceObject.Load(8, &i.cqFlags)
stateSourceObject.Load(9, &i.CqOverflow)
}
func (i *IOUringSqe) StateTypeName() string {
return "pkg/abi/linux.IOUringSqe"
}
func (i *IOUringSqe) StateFields() []string {
return []string{
"Opcode",
"Flags",
"IoPrio",
"Fd",
"OffOrAddrOrCmdOp",
"AddrOrSpliceOff",
"Len",
"specialFlags",
"UserData",
"BufIndexOrGroup",
"personality",
"spliceFDOrFileIndex",
"addr3",
}
}
func (i *IOUringSqe) beforeSave() {}
// +checklocksignore
func (i *IOUringSqe) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.Opcode)
stateSinkObject.Save(1, &i.Flags)
stateSinkObject.Save(2, &i.IoPrio)
stateSinkObject.Save(3, &i.Fd)
stateSinkObject.Save(4, &i.OffOrAddrOrCmdOp)
stateSinkObject.Save(5, &i.AddrOrSpliceOff)
stateSinkObject.Save(6, &i.Len)
stateSinkObject.Save(7, &i.specialFlags)
stateSinkObject.Save(8, &i.UserData)
stateSinkObject.Save(9, &i.BufIndexOrGroup)
stateSinkObject.Save(10, &i.personality)
stateSinkObject.Save(11, &i.spliceFDOrFileIndex)
stateSinkObject.Save(12, &i.addr3)
}
func (i *IOUringSqe) afterLoad(context.Context) {}
// +checklocksignore
func (i *IOUringSqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.Opcode)
stateSourceObject.Load(1, &i.Flags)
stateSourceObject.Load(2, &i.IoPrio)
stateSourceObject.Load(3, &i.Fd)
stateSourceObject.Load(4, &i.OffOrAddrOrCmdOp)
stateSourceObject.Load(5, &i.AddrOrSpliceOff)
stateSourceObject.Load(6, &i.Len)
stateSourceObject.Load(7, &i.specialFlags)
stateSourceObject.Load(8, &i.UserData)
stateSourceObject.Load(9, &i.BufIndexOrGroup)
stateSourceObject.Load(10, &i.personality)
stateSourceObject.Load(11, &i.spliceFDOrFileIndex)
stateSourceObject.Load(12, &i.addr3)
}
func (s *SigAction) StateTypeName() string {
return "pkg/abi/linux.SigAction"
}
func (s *SigAction) StateFields() []string {
return []string{
"Handler",
"Flags",
"Restorer",
"Mask",
}
}
func (s *SigAction) beforeSave() {}
// +checklocksignore
func (s *SigAction) StateSave(stateSinkObject state.Sink) {
s.beforeSave()
stateSinkObject.Save(0, &s.Handler)
stateSinkObject.Save(1, &s.Flags)
stateSinkObject.Save(2, &s.Restorer)
stateSinkObject.Save(3, &s.Mask)
}
func (s *SigAction) afterLoad(context.Context) {}
// +checklocksignore
func (s *SigAction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &s.Handler)
stateSourceObject.Load(1, &s.Flags)
stateSourceObject.Load(2, &s.Restorer)
stateSourceObject.Load(3, &s.Mask)
}
func (s *SignalStack) StateTypeName() string {
return "pkg/abi/linux.SignalStack"
}
func (s *SignalStack) StateFields() []string {
return []string{
"Addr",
"Flags",
"Size",
}
}
func (s *SignalStack) beforeSave() {}
// +checklocksignore
func (s *SignalStack) StateSave(stateSinkObject state.Sink) {
s.beforeSave()
stateSinkObject.Save(0, &s.Addr)
stateSinkObject.Save(1, &s.Flags)
stateSinkObject.Save(2, &s.Size)
}
func (s *SignalStack) afterLoad(context.Context) {}
// +checklocksignore
func (s *SignalStack) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &s.Addr)
stateSourceObject.Load(1, &s.Flags)
stateSourceObject.Load(2, &s.Size)
}
func (s *SignalInfo) StateTypeName() string {
return "pkg/abi/linux.SignalInfo"
}
func (s *SignalInfo) StateFields() []string {
return []string{
"Signo",
"Errno",
"Code",
"Fields",
}
}
func (s *SignalInfo) beforeSave() {}
// +checklocksignore
func (s *SignalInfo) StateSave(stateSinkObject state.Sink) {
s.beforeSave()
stateSinkObject.Save(0, &s.Signo)
stateSinkObject.Save(1, &s.Errno)
stateSinkObject.Save(2, &s.Code)
stateSinkObject.Save(3, &s.Fields)
}
func (s *SignalInfo) afterLoad(context.Context) {}
// +checklocksignore
func (s *SignalInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &s.Signo)
stateSourceObject.Load(1, &s.Errno)
stateSourceObject.Load(2, &s.Code)
stateSourceObject.Load(3, &s.Fields)
}
func (c *ControlMessageIPPacketInfo) StateTypeName() string {
return "pkg/abi/linux.ControlMessageIPPacketInfo"
}
func (c *ControlMessageIPPacketInfo) StateFields() []string {
return []string{
"NIC",
"LocalAddr",
"DestinationAddr",
}
}
func (c *ControlMessageIPPacketInfo) beforeSave() {}
// +checklocksignore
func (c *ControlMessageIPPacketInfo) StateSave(stateSinkObject state.Sink) {
c.beforeSave()
stateSinkObject.Save(0, &c.NIC)
stateSinkObject.Save(1, &c.LocalAddr)
stateSinkObject.Save(2, &c.DestinationAddr)
}
func (c *ControlMessageIPPacketInfo) afterLoad(context.Context) {}
// +checklocksignore
func (c *ControlMessageIPPacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &c.NIC)
stateSourceObject.Load(1, &c.LocalAddr)
stateSourceObject.Load(2, &c.DestinationAddr)
}
func (c *ControlMessageIPv6PacketInfo) StateTypeName() string {
return "pkg/abi/linux.ControlMessageIPv6PacketInfo"
}
func (c *ControlMessageIPv6PacketInfo) StateFields() []string {
return []string{
"Addr",
"NIC",
}
}
func (c *ControlMessageIPv6PacketInfo) beforeSave() {}
// +checklocksignore
func (c *ControlMessageIPv6PacketInfo) StateSave(stateSinkObject state.Sink) {
c.beforeSave()
stateSinkObject.Save(0, &c.Addr)
stateSinkObject.Save(1, &c.NIC)
}
func (c *ControlMessageIPv6PacketInfo) afterLoad(context.Context) {}
// +checklocksignore
func (c *ControlMessageIPv6PacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &c.Addr)
stateSourceObject.Load(1, &c.NIC)
}
func (i *ICMP6Filter) StateTypeName() string {
return "pkg/abi/linux.ICMP6Filter"
}
func (i *ICMP6Filter) StateFields() []string {
return []string{
"Filter",
}
}
func (i *ICMP6Filter) beforeSave() {}
// +checklocksignore
func (i *ICMP6Filter) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.Filter)
}
func (i *ICMP6Filter) afterLoad(context.Context) {}
// +checklocksignore
func (i *ICMP6Filter) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.Filter)
}
func (t *KernelTermios) StateTypeName() string {
return "pkg/abi/linux.KernelTermios"
}
func (t *KernelTermios) StateFields() []string {
return []string{
"InputFlags",
"OutputFlags",
"ControlFlags",
"LocalFlags",
"LineDiscipline",
"ControlCharacters",
"InputSpeed",
"OutputSpeed",
}
}
func (t *KernelTermios) beforeSave() {}
// +checklocksignore
func (t *KernelTermios) StateSave(stateSinkObject state.Sink) {
t.beforeSave()
stateSinkObject.Save(0, &t.InputFlags)
stateSinkObject.Save(1, &t.OutputFlags)
stateSinkObject.Save(2, &t.ControlFlags)
stateSinkObject.Save(3, &t.LocalFlags)
stateSinkObject.Save(4, &t.LineDiscipline)
stateSinkObject.Save(5, &t.ControlCharacters)
stateSinkObject.Save(6, &t.InputSpeed)
stateSinkObject.Save(7, &t.OutputSpeed)
}
func (t *KernelTermios) afterLoad(context.Context) {}
// +checklocksignore
func (t *KernelTermios) StateLoad(ctx context.Context, stateSourceObject state.Source) {
stateSourceObject.Load(0, &t.InputFlags)
stateSourceObject.Load(1, &t.OutputFlags)
stateSourceObject.Load(2, &t.ControlFlags)
stateSourceObject.Load(3, &t.LocalFlags)
stateSourceObject.Load(4, &t.LineDiscipline)
stateSourceObject.Load(5, &t.ControlCharacters)
stateSourceObject.Load(6, &t.InputSpeed)
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((*FUSEHeaderIn)(nil))
state.Register((*FUSEHeaderOut)(nil))
state.Register((*IOUringCqe)(nil))
state.Register((*IOUring)(nil))
state.Register((*IORings)(nil))
state.Register((*IOUringSqe)(nil))
state.Register((*SigAction)(nil))
state.Register((*SignalStack)(nil))
state.Register((*SignalInfo)(nil))
state.Register((*ControlMessageIPPacketInfo)(nil))
state.Register((*ControlMessageIPv6PacketInfo)(nil))
state.Register((*ICMP6Filter)(nil))
state.Register((*KernelTermios)(nil))
state.Register((*WindowSize)(nil))
}

View file

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

View file

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

View file

@ -0,0 +1,34 @@
// Copyright 2020 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
// membarrier(2) commands, from include/uapi/linux/membarrier.h.
const (
MEMBARRIER_CMD_QUERY = 0
MEMBARRIER_CMD_GLOBAL = (1 << 0)
MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1)
MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2)
MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3)
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4)
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5)
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6)
MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7)
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8)
)
// membarrier(2) flags, from include/uapi/linux/membarrier.h.
const (
MEMBARRIER_CMD_FLAG_CPU = (1 << 0)
)

160
pkg/abi/linux/mm.go Normal file
View file

@ -0,0 +1,160 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"fmt"
"golang.org/x/sys/unix"
)
// Protections for mmap(2).
const (
PROT_NONE = 0
PROT_READ = 1 << 0
PROT_WRITE = 1 << 1
PROT_EXEC = 1 << 2
PROT_SEM = 1 << 3
PROT_GROWSDOWN = 1 << 24
PROT_GROWSUP = 1 << 25
)
// Flags for mmap(2).
const (
MAP_SHARED = 1 << 0
MAP_PRIVATE = 1 << 1
MAP_DROPPABLE = 1 << 3
MAP_FIXED = 1 << 4
MAP_ANONYMOUS = 1 << 5
MAP_32BIT = 1 << 6 // arch/x86/include/uapi/asm/mman.h
MAP_GROWSDOWN = 1 << 8
MAP_DENYWRITE = 1 << 11
MAP_EXECUTABLE = 1 << 12
MAP_LOCKED = 1 << 13
MAP_NORESERVE = 1 << 14
MAP_POPULATE = 1 << 15
MAP_NONBLOCK = 1 << 16
MAP_STACK = 1 << 17
MAP_HUGETLB = 1 << 18
)
// Flags for mremap(2).
const (
MREMAP_MAYMOVE = 1 << 0
MREMAP_FIXED = 1 << 1
)
// Flags for mlock2(2).
const (
MLOCK_ONFAULT = 0x01
)
// Flags for mlockall(2).
const (
MCL_CURRENT = 1
MCL_FUTURE = 2
MCL_ONFAULT = 4
)
// Advice for madvise(2).
const (
MADV_NORMAL = 0
MADV_RANDOM = 1
MADV_SEQUENTIAL = 2
MADV_WILLNEED = 3
MADV_DONTNEED = 4
MADV_REMOVE = 9
MADV_DONTFORK = 10
MADV_DOFORK = 11
MADV_MERGEABLE = 12
MADV_UNMERGEABLE = 13
MADV_HUGEPAGE = 14
MADV_NOHUGEPAGE = 15
MADV_DONTDUMP = 16
MADV_DODUMP = 17
MADV_HWPOISON = 100
MADV_SOFT_OFFLINE = 101
MADV_NOMAJFAULT = 200
MADV_DONTCHGME = 201
)
// Flags for msync(2).
const (
MS_ASYNC = 1 << 0
MS_INVALIDATE = 1 << 1
MS_SYNC = 1 << 2
)
// NumaPolicy is the NUMA memory policy for a memory range. See numa(7).
//
// +marshal
type NumaPolicy int32
// Policies for get_mempolicy(2)/set_mempolicy(2).
const (
MPOL_DEFAULT NumaPolicy = 0
MPOL_PREFERRED NumaPolicy = 1
MPOL_BIND NumaPolicy = 2
MPOL_INTERLEAVE NumaPolicy = 3
MPOL_LOCAL NumaPolicy = 4
MPOL_MAX NumaPolicy = 5
)
// Flags for get_mempolicy(2).
const (
MPOL_F_NODE = 1 << 0
MPOL_F_ADDR = 1 << 1
MPOL_F_MEMS_ALLOWED = 1 << 2
)
// Flags for set_mempolicy(2).
const (
MPOL_F_RELATIVE_NODES = 1 << 14
MPOL_F_STATIC_NODES = 1 << 15
MPOL_MODE_FLAGS = (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
)
// Flags for mbind(2).
const (
MPOL_MF_STRICT = 1 << 0
MPOL_MF_MOVE = 1 << 1
MPOL_MF_MOVE_ALL = 1 << 2
MPOL_MF_VALID = MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL
)
// TaskSize is the address space size.
var TaskSize = func() uintptr {
pageSize := uintptr(unix.Getpagesize())
for _, s := range feasibleTaskSizes {
// mmap returns ENOMEM if addr is greater than TASK_SIZE,
// otherwise it returns EINVAL, because addr isn't aligned to
// the page size.
_, _, errno := unix.RawSyscall6(
unix.SYS_MMAP,
s-pageSize-1,
512,
uintptr(unix.PROT_NONE),
uintptr(unix.MAP_ANONYMOUS|unix.MAP_PRIVATE|unix.MAP_FIXED), 0, 0)
if errno == unix.EINVAL {
return s
}
if errno != unix.ENOMEM {
panic(fmt.Sprintf("mmap returned unexpected error: %d", errno))
}
}
panic("None of the address space sizes could be successfully mmaped")
}()

33
pkg/abi/linux/mm_amd64.go Normal file
View file

@ -0,0 +1,33 @@
// Copyright 2023 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.
//go:build amd64
// +build amd64
package linux
// TASK_SIZE can be one of two values, corresponding to 4-level and 5-level
// paging.
//
// The array has to be sorted in decreasing order.
var feasibleTaskSizes = []uintptr{0xfffffffffff000, 0x7ffffffff000}
// Page fault error codes
const (
X86_PF_PROT = 1 << iota
X86_PF_WRITE
X86_PF_USER
X86_PF_RSVD
X86_PF_INSTR
)

25
pkg/abi/linux/mm_arm64.go Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2023 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.
//go:build arm64
// +build arm64
package linux
// Only 4K page size is supported on arm64. In this case, TASK_SIZE can
// be one of three values, corresponding to 3-level, 4-level and
// 5-level paging.
//
// The array has to be sorted in decreasing order.
var feasibleTaskSizes = []uintptr{1 << 52, 1 << 48, 1 << 39}

55
pkg/abi/linux/mqueue.go Normal file
View file

@ -0,0 +1,55 @@
// Copyright 2021 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
// Default values for POSIX message queues. Source:
// include/linux/ipc_namespace.h
const (
DFLT_QUEUESMAX = 256
MIN_MSGMAX = 1
DFLT_MSG uint = 10
DFLT_MSGMAX = 10
HARD_MSGMAX = 65536
MIN_MSGSIZEMAX = 128
DFLT_MSGSIZE uint = 8192
DFLT_MSGSIZEMAX = 8192
HARD_MSGSIZEMAX = (16 * 1024 * 1024)
)
// Maximum values for a message queue. Source: include/uapi/linux/mqueue.h
const (
MQ_PRIO_MAX = 32768
MQ_BYTES_MAX = 819200
)
// Codes used by mq_notify. Source: include/uapi/linux/mqueue.h
const (
NOTIFY_NONE = 0
NOTIFY_WOKENUP = 1
NOTIFY_REMOVED = 2
NOTIFY_COOKIE_LEN = 32
)
// MqAttr is equivalent to struct mq_attr. Source: include/uapi/linux/mqueue.h
//
// +marshal
type MqAttr struct {
MqFlags int64 // Message queue flags.
MqMaxmsg int64 // Maximum number of messages.
MqMsgsize int64 // Maximum message size.
MqCurmsgs int64 // Number of messages currently queued.
_ [4]int64 // Ignored for input, zeroed for output.
}

108
pkg/abi/linux/msgqueue.go Normal file
View file

@ -0,0 +1,108 @@
// Copyright 2021 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 (
"github.com/sagernet/gvisor/pkg/marshal/primitive"
)
// Linux-specific control commands. Source: include/uapi/linux/msg.h
const (
MSG_STAT = 11
MSG_INFO = 12
MSG_STAT_ANY = 13
)
// msgrcv(2) options. Source: include/uapi/linux/msg.h
const (
MSG_NOERROR = 0o10000 // No error if message is too big.
MSG_EXCEPT = 0o20000 // Receive any message except of specified type.
MSG_COPY = 0o40000 // Copy (not remove) all queue messages.
)
// System-wide limits for message queues. Source: include/uapi/linux/msg.h
const (
MSGMNI = 32000 // Maximum number of message queue identifiers.
MSGMAX = 8192 // Maximum size of message (bytes).
MSGMNB = 16384 // Default max size of a message queue.
)
// System-wide limits. Unused. Source: include/uapi/linux/msg.h
const (
MSGPOOL = (MSGMNI * MSGMNB / 1024)
MSGTQL = MSGMNB
MSGMAP = MSGMNB
MSGSSZ = 16
// MSGSEG is simplified due to the inexistance of a ternary operator.
MSGSEG = 0xffff
)
// MsqidDS is equivalent to struct msqid64_ds. Source:
// include/uapi/asm-generic/shmbuf.h
//
// +marshal
type MsqidDS struct {
MsgPerm IPCPerm // IPC permissions.
MsgStime TimeT // Last msgsnd time.
MsgRtime TimeT // Last msgrcv time.
MsgCtime TimeT // Last change time.
MsgCbytes uint64 // Current number of bytes on the queue.
MsgQnum uint64 // Number of messages in the queue.
MsgQbytes uint64 // Max number of bytes in the queue.
MsgLspid int32 // PID of last msgsnd.
MsgLrpid int32 // PID of last msgrcv.
unused4 uint64
unused5 uint64
}
// MsgBuf is equivalent to struct msgbuf. Source: include/uapi/linux/msg.h
//
// +marshal dynamic
type MsgBuf struct {
Type primitive.Int64
Text primitive.ByteSlice
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (b *MsgBuf) SizeBytes() int {
return b.Type.SizeBytes() + b.Text.SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (b *MsgBuf) MarshalBytes(dst []byte) []byte {
dst = b.Type.MarshalUnsafe(dst)
return b.Text.MarshalBytes(dst)
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (b *MsgBuf) UnmarshalBytes(src []byte) []byte {
src = b.Type.UnmarshalUnsafe(src)
return b.Text.UnmarshalBytes(src)
}
// MsgInfo is equivalent to struct msginfo. Source: include/uapi/linux/msg.h
//
// +marshal
type MsgInfo struct {
MsgPool int32
MsgMap int32
MsgMax int32
MsgMnb int32
MsgMni int32
MsgSsz int32
MsgTql int32
MsgSeg uint16 `marshal:"unaligned"`
}

128
pkg/abi/linux/netdevice.go Normal file
View file

@ -0,0 +1,128 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
const (
// IFNAMSIZ is the size of the name field for IFReq.
IFNAMSIZ = 16
)
// IFReq is an interface request.
//
// +marshal
type IFReq struct {
// IFName is an encoded name, normally null-terminated. This should be
// accessed via the Name and SetName functions.
IFName [IFNAMSIZ]byte
// Data is the union of the following structures:
//
// struct sockaddr ifr_addr;
// struct sockaddr ifr_dstaddr;
// struct sockaddr ifr_broadaddr;
// struct sockaddr ifr_netmask;
// struct sockaddr ifr_hwaddr;
// short ifr_flags;
// int ifr_ifindex;
// int ifr_metric;
// int ifr_mtu;
// struct ifmap ifr_map;
// char ifr_slave[IFNAMSIZ];
// char ifr_newname[IFNAMSIZ];
// char *ifr_data;
Data [24]byte
}
// Name returns the name.
func (ifr *IFReq) Name() string {
for c := 0; c < len(ifr.IFName); c++ {
if ifr.IFName[c] == 0 {
return string(ifr.IFName[:c])
}
}
return string(ifr.IFName[:])
}
// SetName sets the name.
func (ifr *IFReq) SetName(name string) {
n := copy(ifr.IFName[:], []byte(name))
clear(ifr.IFName[n:])
}
// SizeOfIFReq is the binary size of an IFReq struct (40 bytes).
var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
// IFMap contains interface hardware parameters.
type IFMap struct {
MemStart uint64
MemEnd uint64
BaseAddr int16
IRQ byte
DMA byte
Port byte
_ [3]byte // Pad to sizeof(struct ifmap).
}
// IFConf is used to return a list of interfaces and their addresses. See
// netdevice(7) and struct ifconf for more detail on its use.
//
// +marshal
type IFConf struct {
Len int32
_ [4]byte // Pad to sizeof(struct ifconf).
Ptr uint64
}
// SizeOfIFConf is the binary size of an IFConf struct (16 bytes).
var SizeOfIFConf = (*IFConf)(nil).SizeBytes()
// EthtoolCmd is a marshallable type to be able to easily copyin the
// the command for an SIOCETHTOOL ioctl.
//
// +marshal
type EthtoolCmd uint32
const (
// ETHTOOL_GFEATURES is the command to SIOCETHTOOL to query device
// features.
// See: <linux/ethtool.h>
ETHTOOL_GFEATURES EthtoolCmd = 0x3a
)
// EthtoolGFeatures is used to return a list of device features.
// See: <linux/ethtool.h>
//
// +marshal
type EthtoolGFeatures struct {
Cmd uint32
Size uint32
}
// EthtoolGetFeaturesBlock is used to return state of upto 32 device
// features.
// See: <linux/ethtool.h>
//
// +marshal
type EthtoolGetFeaturesBlock struct {
Available uint32
Requested uint32
Active uint32
NeverChanged uint32
}
const (
// LOOPBACK_IFINDEX is defined in include/net/flow.h.
LOOPBACK_IFINDEX = 1
)

796
pkg/abi/linux/netfilter.go Normal file
View file

@ -0,0 +1,796 @@
// Copyright 2019 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 (
"github.com/sagernet/gvisor/pkg/marshal"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
)
// This file contains structures required to support netfilter, specifically
// the iptables tool.
// Hooks into the network stack. These correspond to values in
// include/uapi/linux/netfilter.h.
const (
NF_INET_PRE_ROUTING = 0
NF_INET_LOCAL_IN = 1
NF_INET_FORWARD = 2
NF_INET_LOCAL_OUT = 3
NF_INET_POST_ROUTING = 4
NF_INET_NUMHOOKS = 5
NF_INET_INGRESS = NF_INET_NUMHOOKS
)
const (
NF_NETDEV_INGRESS = iota
NF_NETDEV_EGRESS
NF_NETDEV_NUMHOOKS
)
// Protocol families (address families). These correspond to values in
// include/uapi/linux/netfilter.h.
const (
NFPROTO_UNSPEC = 0
NFPROTO_INET = 1
NFPROTO_IPV4 = 2
NFPROTO_ARP = 3
NFPROTO_NETDEV = 5
NFPROTO_BRIDGE = 7
NFPROTO_IPV6 = 10
)
// Verdicts that can be returned by targets. These correspond to values in
// include/uapi/linux/netfilter.h
const (
NF_DROP = 0
NF_ACCEPT = 1
NF_STOLEN = 2
NF_QUEUE = 3
NF_REPEAT = 4
NF_STOP = 5
NF_MAX_VERDICT = NF_STOP
// NF_RETURN is defined in include/uapi/linux/netfilter/x_tables.h.
NF_RETURN = -NF_REPEAT - 1
)
// VerdictStrings maps int verdicts to the strings they represent. It is used
// for debugging.
var VerdictStrings = map[int32]string{
-NF_DROP - 1: "DROP",
-NF_ACCEPT - 1: "ACCEPT",
-NF_QUEUE - 1: "QUEUE",
NF_RETURN: "RETURN",
}
// Socket options for SOL_SOCKET. These correspond to values in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
const (
IPT_BASE_CTL = 64
IPT_SO_SET_REPLACE = IPT_BASE_CTL
IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
IPT_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
IPT_SO_GET_INFO = IPT_BASE_CTL
IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1
IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2
IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3
IPT_SO_GET_MAX = IPT_SO_GET_REVISION_TARGET
)
// Socket option for SOL_IP. This corresponds to the value in
// include/uapi/linux/netfilter_ipv4.h.
const (
SO_ORIGINAL_DST = 80
)
// Name lengths. These correspond to values in
// include/uapi/linux/netfilter/x_tables.h.
const (
XT_FUNCTION_MAXNAMELEN = 30
XT_EXTENSION_MAXNAMELEN = 29
XT_TABLE_MAXNAMELEN = 32
)
// IPTEntry is an iptable rule. It corresponds to struct ipt_entry in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
//
// +marshal
type IPTEntry struct {
// IP is used to filter packets based on the IP header.
IP IPTIP
// NFCache relates to kernel-internal caching and isn't used by
// userspace.
NFCache uint32
// TargetOffset is the byte offset from the beginning of this IPTEntry
// to the start of the entry's target.
TargetOffset uint16
// NextOffset is the byte offset from the beginning of this IPTEntry to
// the start of the next entry. It is thus also the size of the entry.
NextOffset uint16
// Comeback is a return pointer. It is not used by userspace.
Comeback uint32
// Counters holds the packet and byte counts for this rule.
Counters XTCounters
// 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 is omitted here because it would cause IPTEntry to be an extra
// byte larger (see http://www.catb.org/esr/structure-packing/).
//
// Elems [0]byte
}
// SizeOfIPTEntry is the size of an IPTEntry.
const SizeOfIPTEntry = 112
// KernelIPTEntry is identical to IPTEntry, but includes the Elems field.
//
// +marshal dynamic
type KernelIPTEntry struct {
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
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (ke *KernelIPTEntry) SizeBytes() int {
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (ke *KernelIPTEntry) MarshalBytes(dst []byte) []byte {
dst = ke.Entry.MarshalUnsafe(dst)
return ke.Elems.MarshalBytes(dst)
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) []byte {
src = ke.Entry.UnmarshalUnsafe(src)
return ke.Elems.UnmarshalBytes(src)
}
var _ marshal.Marshallable = (*KernelIPTEntry)(nil)
// IPTIP contains information for matching a packet's IP header.
// It corresponds to struct ipt_ip in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
//
// +marshal
type IPTIP struct {
// Src is the source IP address.
Src InetAddr
// Dst is the destination IP address.
Dst InetAddr
// SrcMask is the source IP mask.
SrcMask InetAddr
// DstMask is the destination IP mask.
DstMask InetAddr
// InputInterface is the input network interface.
InputInterface [IFNAMSIZ]byte
// OutputInterface is the output network interface.
OutputInterface [IFNAMSIZ]byte
// InputInterfaceMask is the input interface mask.
InputInterfaceMask [IFNAMSIZ]byte
// OuputInterfaceMask is the output interface mask.
OutputInterfaceMask [IFNAMSIZ]byte
// Protocol is the transport protocol.
Protocol uint16
// Flags define matching behavior for the IP header.
Flags uint8
// InverseFlags invert the meaning of fields in struct IPTIP. See the
// IPT_INV_* flags.
InverseFlags uint8
}
// Flags in IPTIP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
const (
// Invert the meaning of InputInterface.
IPT_INV_VIA_IN = 0x01
// Invert the meaning of OutputInterface.
IPT_INV_VIA_OUT = 0x02
// Unclear what this is, as no references to it exist in the kernel.
IPT_INV_TOS = 0x04
// Invert the meaning of Src.
IPT_INV_SRCIP = 0x08
// Invert the meaning of Dst.
IPT_INV_DSTIP = 0x10
// Invert the meaning of the IPT_F_FRAG flag.
IPT_INV_FRAG = 0x20
// Invert the meaning of the Protocol field.
IPT_INV_PROTO = 0x40
// Enable all flags.
IPT_INV_MASK = 0x7F
)
// SizeOfIPTIP is the size of an IPTIP.
const SizeOfIPTIP = 84
// XTCounters holds packet and byte counts for a rule. It corresponds to struct
// xt_counters in include/uapi/linux/netfilter/x_tables.h.
//
// +marshal
type XTCounters struct {
// Pcnt is the packet count.
Pcnt uint64
// Bcnt is the byte count.
Bcnt uint64
}
// SizeOfXTCounters is the size of an XTCounters.
const SizeOfXTCounters = 16
// XTEntryMatch holds a match for a rule. For example, a user using the
// addrtype iptables match extension would put the data for that match into an
// XTEntryMatch. iptables-extensions(8) has a list of possible matches.
//
// XTEntryMatch corresponds to struct xt_entry_match in
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
// exposing different data to the user and kernel, but this struct holds only
// the user data.
//
// +marshal
type XTEntryMatch struct {
MatchSize uint16
Name ExtensionName
Revision uint8
// Data is omitted here because it would cause XTEntryMatch to be an
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
// Data [0]byte
}
// SizeOfXTEntryMatch is the size of an XTEntryMatch.
const SizeOfXTEntryMatch = 32
// KernelXTEntryMatch is identical to XTEntryMatch, but contains
// variable-length Data field.
type KernelXTEntryMatch struct {
XTEntryMatch
Data []byte
}
// XTGetRevision corresponds to xt_get_revision in
// include/uapi/linux/netfilter/x_tables.h
//
// +marshal
type XTGetRevision struct {
Name ExtensionName
Revision uint8
}
// SizeOfXTGetRevision is the size of an XTGetRevision.
const SizeOfXTGetRevision = 30
// XTEntryTarget holds a target for a rule. For example, it can specify that
// packets matching the rule should DROP, ACCEPT, or use an extension target.
// iptables-extension(8) has a list of possible targets.
//
// XTEntryTarget corresponds to struct xt_entry_target in
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
// exposing different data to the user and kernel, but this struct holds only
// the user data.
//
// +marshal
type XTEntryTarget struct {
TargetSize uint16
Name ExtensionName
Revision uint8
// Data is omitted here because it would cause XTEntryTarget to be an
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
// Data [0]byte
}
// SizeOfXTEntryTarget is the size of an XTEntryTarget.
const SizeOfXTEntryTarget = 32
// KernelXTEntryTarget is identical to XTEntryTarget, but contains a
// variable-length Data field.
type KernelXTEntryTarget struct {
XTEntryTarget
Data []byte
}
// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
// RETURN, or jump. It corresponds to struct xt_standard_target in
// include/uapi/linux/netfilter/x_tables.h.
//
// +marshal
type XTStandardTarget struct {
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
// other built-in targets.
Verdict int32
_ [4]byte
}
// SizeOfXTStandardTarget is the size of an XTStandardTarget.
const SizeOfXTStandardTarget = 40
// XTErrorTarget triggers an error when reached. It is also used to mark the
// beginning of user-defined chains by putting the name of the chain in
// ErrorName. It corresponds to struct xt_error_target in
// include/uapi/linux/netfilter/x_tables.h.
//
// +marshal
type XTErrorTarget struct {
Target XTEntryTarget
Name ErrorName
_ [2]byte
}
// SizeOfXTErrorTarget is the size of an XTErrorTarget.
const SizeOfXTErrorTarget = 64
// Flag values for NfNATIPV4Range. The values indicate whether to map
// protocol specific part(ports) or IPs. It corresponds to values in
// include/uapi/linux/netfilter/nf_nat.h.
const (
NF_NAT_RANGE_MAP_IPS = 1 << 0
NF_NAT_RANGE_PROTO_SPECIFIED = 1 << 1
NF_NAT_RANGE_PROTO_RANDOM = 1 << 2
NF_NAT_RANGE_PERSISTENT = 1 << 3
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 1 << 4
NF_NAT_RANGE_PROTO_RANDOM_ALL = (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
NF_NAT_RANGE_MASK = (NF_NAT_RANGE_MAP_IPS |
NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM |
NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
)
// NfNATIPV4Range corresponds to struct nf_nat_ipv4_range
// in include/uapi/linux/netfilter/nf_nat.h. The fields are in
// network byte order.
//
// +marshal
type NfNATIPV4Range struct {
Flags uint32
MinIP [4]byte
MaxIP [4]byte
MinPort uint16
MaxPort uint16
}
// NfNATIPV4MultiRangeCompat corresponds to struct
// nf_nat_ipv4_multi_range_compat in include/uapi/linux/netfilter/nf_nat.h.
//
// +marshal
type NfNATIPV4MultiRangeCompat struct {
RangeSize uint32
RangeIPV4 NfNATIPV4Range
}
// XTRedirectTarget triggers a redirect when reached.
// Adding 4 bytes of padding to make the struct 8 byte aligned.
//
// +marshal
type XTRedirectTarget struct {
Target XTEntryTarget
NfRange NfNATIPV4MultiRangeCompat
_ [4]byte
}
// SizeOfXTRedirectTarget is the size of an XTRedirectTarget.
const SizeOfXTRedirectTarget = 56
// XTNATTargetV0 triggers NAT when reached.
// Adding 4 bytes of padding to make the struct 8 byte aligned.
//
// +marshal
type XTNATTargetV0 struct {
Target XTEntryTarget
NfRange NfNATIPV4MultiRangeCompat
_ [4]byte
}
// SizeOfXTNATTargetV0 is the size of an XTNATTargetV0.
const SizeOfXTNATTargetV0 = 56
// XTNATTargetV1 triggers NAT when reached.
//
// +marshal
type XTNATTargetV1 struct {
Target XTEntryTarget
Range NFNATRange
}
// SizeOfXTNATTargetV1 is the size of an XTNATTargetV1.
const SizeOfXTNATTargetV1 = SizeOfXTEntryTarget + SizeOfNFNATRange
// XTNATTargetV2 triggers NAT when reached.
//
// +marshal
type XTNATTargetV2 struct {
Target XTEntryTarget
Range NFNATRange2
}
// SizeOfXTNATTargetV2 is the size of an XTNATTargetV2.
const SizeOfXTNATTargetV2 = SizeOfXTEntryTarget + SizeOfNFNATRange2
// 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 {
Name TableName
ValidHooks uint32
HookEntry [NF_INET_NUMHOOKS]uint32
Underflow [NF_INET_NUMHOOKS]uint32
NumEntries uint32
Size uint32
}
// SizeOfIPTGetinfo is the size of an IPTGetinfo.
const SizeOfIPTGetinfo = 84
// IPTGetEntries is the argument for the IPT_SO_GET_ENTRIES sockopt. It
// corresponds to struct ipt_get_entries in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
//
// +marshal
type IPTGetEntries struct {
Name TableName
Size uint32
_ [4]byte
// Entrytable is omitted here because it would cause IPTGetEntries to
// be an extra byte longer (see
// http://www.catb.org/esr/structure-packing/).
// Entrytable [0]IPTEntry
}
// SizeOfIPTGetEntries is the size of an IPTGetEntries.
const SizeOfIPTGetEntries = 40
// KernelIPTGetEntries is identical to IPTGetEntries, but includes the
// Entrytable field.
//
// +marshal dynamic
type KernelIPTGetEntries struct {
IPTGetEntries
Entrytable []KernelIPTEntry
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (ke *KernelIPTGetEntries) SizeBytes() int {
res := ke.IPTGetEntries.SizeBytes()
for _, entry := range ke.Entrytable {
res += entry.SizeBytes()
}
return res
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (ke *KernelIPTGetEntries) MarshalBytes(dst []byte) []byte {
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
for i := range ke.Entrytable {
dst = ke.Entrytable[i].MarshalBytes(dst)
}
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) []byte {
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
for i := range ke.Entrytable {
src = ke.Entrytable[i].UnmarshalBytes(src)
}
return src
}
var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It
// corresponds to struct ipt_replace in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
//
// +marshal
type IPTReplace struct {
Name TableName
ValidHooks uint32
NumEntries uint32
Size uint32
HookEntry [NF_INET_NUMHOOKS]uint32
Underflow [NF_INET_NUMHOOKS]uint32
NumCounters uint32
Counters uint64 // This is really a *XTCounters.
// Entries is omitted here because it would cause IPTReplace to be an
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
// Entries [0]IPTEntry
}
// SizeOfIPTReplace is the size of an IPTReplace.
const SizeOfIPTReplace = 96
// ExtensionName holds the name of a netfilter extension.
//
// +marshal
type ExtensionName [XT_EXTENSION_MAXNAMELEN]byte
// String implements fmt.Stringer.
func (en ExtensionName) String() string {
return goString(en[:])
}
// TableName holds the name of a netfilter table.
//
// +marshal
type TableName [XT_TABLE_MAXNAMELEN]byte
// String implements fmt.Stringer.
func (tn TableName) String() string {
return goString(tn[:])
}
// ErrorName holds the name of a netfilter error. These can also hold
// user-defined chains.
//
// +marshal
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte
// String implements fmt.Stringer.
func (en ErrorName) String() string {
return goString(en[:])
}
func goString(cstring []byte) string {
for i, c := range cstring {
if c == 0 {
return string(cstring[:i])
}
}
return string(cstring)
}
// XTTCP holds data for matching TCP packets. It corresponds to struct xt_tcp
// in include/uapi/linux/netfilter/xt_tcpudp.h.
//
// +marshal
type XTTCP struct {
// SourcePortStart specifies the inclusive start of the range of source
// ports to which the matcher applies.
SourcePortStart uint16
// SourcePortEnd specifies the inclusive end of the range of source ports
// to which the matcher applies.
SourcePortEnd uint16
// DestinationPortStart specifies the start of the destination port
// range to which the matcher applies.
DestinationPortStart uint16
// DestinationPortEnd specifies the end of the destination port
// range to which the matcher applies.
DestinationPortEnd uint16
// Option specifies that a particular TCP option must be set.
Option uint8
// FlagMask masks TCP flags when comparing to the FlagCompare byte. It allows
// for specification of which flags are important to the matcher.
FlagMask uint8
// FlagCompare, in combination with FlagMask, is used to match only packets
// that have certain flags set.
FlagCompare uint8
// InverseFlags flips the meaning of certain fields. See the
// TX_TCP_INV_* flags.
InverseFlags uint8
}
// SizeOfXTTCP is the size of an XTTCP.
const SizeOfXTTCP = 12
// Flags in XTTCP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter/xt_tcpudp.h.
const (
// Invert the meaning of SourcePortStart/End.
XT_TCP_INV_SRCPT = 0x01
// Invert the meaning of DestinationPortStart/End.
XT_TCP_INV_DSTPT = 0x02
// Invert the meaning of FlagCompare.
XT_TCP_INV_FLAGS = 0x04
// Invert the meaning of Option.
XT_TCP_INV_OPTION = 0x08
// Enable all flags.
XT_TCP_INV_MASK = 0x0F
)
// XTUDP holds data for matching UDP packets. It corresponds to struct xt_udp
// in include/uapi/linux/netfilter/xt_tcpudp.h.
//
// +marshal
type XTUDP struct {
// SourcePortStart is the inclusive start of the range of source ports
// to which the matcher applies.
SourcePortStart uint16
// SourcePortEnd is the inclusive end of the range of source ports to
// which the matcher applies.
SourcePortEnd uint16
// DestinationPortStart is the inclusive start of the destination port
// range to which the matcher applies.
DestinationPortStart uint16
// DestinationPortEnd is the inclusive end of the destination port
// range to which the matcher applies.
DestinationPortEnd uint16
// InverseFlags flips the meaning of certain fields. See the
// TX_UDP_INV_* flags.
InverseFlags uint8
_ uint8
}
// SizeOfXTUDP is the size of an XTUDP.
const SizeOfXTUDP = 10
// Flags in XTUDP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter/xt_tcpudp.h.
const (
// Invert the meaning of SourcePortStart/End.
XT_UDP_INV_SRCPT = 0x01
// Invert the meaning of DestinationPortStart/End.
XT_UDP_INV_DSTPT = 0x02
// Enable all flags.
XT_UDP_INV_MASK = 0x03
)
// IPTOwnerInfo holds data for matching packets with the owner v0 matcher. It
// corresponds to struct ipt_owner_info in libxt_owner.c of iptables binary.
//
// +marshal
type IPTOwnerInfo struct {
// UID is user id which created the packet.
UID uint32
// GID is group id which created the packet.
GID uint32
// PID is process id of the process which created the packet.
PID uint32
// SID is session id which created the packet.
SID uint32
// Comm is the command name which created the packet.
Comm [16]byte
// Match is used to match UID/GID of the socket. See the
// XT_OWNER_* flags below.
Match uint8
// Invert flips the meaning of Match field.
Invert uint8 `marshal:"unaligned"`
}
// SizeOfIPTOwnerInfo is the size of an IPTOwnerInfo.
const SizeOfIPTOwnerInfo = 34
// XTOwnerMatchInfo holds data for matching packets with the owner v1 matcher.
// It corresponds to struct xt_owner_match_info in
// include/uapi/linux/netfilter/xt_owner.h
//
// +marshal
type XTOwnerMatchInfo struct {
UIDMin uint32
UIDMax uint32
GIDMin uint32
GIDMax uint32
Match uint8
Invert uint8
_ [2]byte
}
// SizeOfXTOwnerMatchInfo is the size of an XTOwnerMatchInfo.
const SizeOfXTOwnerMatchInfo = 20
// Flags in IPTOwnerInfo.Match and XTOwnerMatchInfo.Match. Corresponding
// constants are in include/uapi/linux/netfilter/xt_owner.h.
const (
// Match the UID of the packet.
XT_OWNER_UID = 1 << 0
// Match the GID of the packet.
XT_OWNER_GID = 1 << 1
// Match if the socket exists for the packet. Forwarded
// packets do not have an associated socket.
XT_OWNER_SOCKET = 1 << 2
)
// XT_MULTI_PORTS is the maximum number of ports that the
// multiport match can handle.
const XT_MULTI_PORTS = 15
// Flags in XTMultiport{,V1}.Flags; values from "enum xt_multiport_flags"
// in "include/uapi/linux/netfilter/xt_multiport.h".
const (
XT_MULTIPORT_SOURCE uint8 = 0x0 // Match against source ports.
XT_MULTIPORT_DESTINATION uint8 = 0x1 // Match against destination ports.
XT_MULTIPORT_EITHER uint8 = 0x2 // Match against either ports.
)
// XTMultiport holds data for matching packets against a set
// of ports. It corresponds to "struct xt_multiport" defined
// in "include/uapi/linux/netfilter/xt_multiport.h".
//
// +marshal
type XTMultiport struct {
// Flags indicates whether the match applies to
// source ports, destination ports, or either, as
// defined by "enum xt_multiport_flags".
Flags uint8
// Count is the number of ports in the "Ports"
// slice that the match will check. It must be
// between 1 and "XT_MULTI_PORTS" (inclusive).
Count uint8
// Ports is the set of ports that will be matched.
// Only the first "Count" entries are considered.
Ports [XT_MULTI_PORTS]uint16
}
// XTMultiportV1 holds data for matching packets against a set
// of ports. It corresponds to "struct xt_multiport_v1" defined
// in "include/uapi/linux/netfilter/xt_multiport.h".
//
// +marshal
type XTMultiportV1 struct {
// Fields same as "XTMultiport".
Flags uint8
Count uint8
Ports [XT_MULTI_PORTS]uint16
// Pflags is an array of port-specific flags. Each entry
// in "Pflags" corresponds to the port at the same index
// in "Ports".
Pflags [XT_MULTI_PORTS]uint8
// Invert is a flag that, if nonzero, indicates
// that the match result should be inverted.
Invert uint8
}
// SizeOfXTMultiport is the size of XTMultiport (in bytes).
const SizeOfXTMultiport = 2 + (XT_MULTI_PORTS * 2)
// SizeOfXTMultiportV1 is the size of XTMultiportV1 (in bytes).
const SizeOfXTMultiportV1 = SizeOfXTMultiport + XT_MULTI_PORTS + 1

View file

@ -0,0 +1,24 @@
// Copyright 2025 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
// These constants show the hooks ARP packets can be evaluated at.
// From include/uapi/linux/netfilter_arp.h.
const (
NF_ARP_IN = iota
NF_ARP_OUT
NF_ARP_FORWARD
NF_ARP_NUMHOOKS
)

View file

@ -0,0 +1,41 @@
// Copyright 2024 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 "math"
// Netfilter Bridge Standard Hook Points, from uapi/linux/netfilter_bridge.h.
const (
NF_BR_PRE_ROUTING = iota
NF_BR_LOCAL_IN
NF_BR_FORWARD
NF_BR_LOCAL_OUT
NF_BR_POST_ROUTING
NF_BR_BROUTING
NF_BR_NUMHOOKS
)
// Netfilter Bridge Standard Hook Priorities, from
// uapi/linux/netfilter_bridge.h.
const (
NF_BR_PRI_FIRST = math.MinInt
NF_BR_PRI_NAT_DST_BRIDGED = -300
NF_BR_PRI_FILTER_BRIDGED = -200
NF_BR_PRI_BRNF = 0
NF_BR_PRI_NAT_DST_OTHER = 100
NF_BR_PRI_FILTER_OTHER = 200
NF_BR_PRI_NAT_SRC = 300
NF_BR_PRI_LAST = math.MaxInt
)

View file

@ -0,0 +1,36 @@
// Copyright 2024 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 "math"
// Netfilter IPv4 Standard Hook Priorities, from uapi/linux/netfilter_ipv4.h.
const (
NF_IP_PRI_FIRST = math.MinInt
NF_IP_PRI_RAW_BEFORE_DEFRAG = -450
NF_IP_PRI_CONNTRACK_DEFRAG = -400
NF_IP_PRI_RAW = -300
NF_IP_PRI_SELINUX_FIRST = -225
NF_IP_PRI_CONNTRACK = -200
NF_IP_PRI_MANGLE = -150
NF_IP_PRI_NAT_DST = -100
NF_IP_PRI_FILTER = 0
NF_IP_PRI_SECURITY = 50
NF_IP_PRI_NAT_SRC = 100
NF_IP_PRI_SELINUX_LAST = 225
NF_IP_PRI_CONNTRACK_HELPER = 300
NF_IP_PRI_CONNTRACK_CONFIRM = math.MaxInt
NF_IP_PRI_LAST = math.MaxInt
)

View file

@ -0,0 +1,314 @@
// Copyright 2020 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 (
"math"
"github.com/sagernet/gvisor/pkg/marshal"
"github.com/sagernet/gvisor/pkg/marshal/primitive"
)
// This file contains structures required to support IPv6 netfilter and
// ip6tables. Some constants and structs are equal to their IPv4 analogues, and
// are only distinguished by context (e.g. whether used on an IPv4 of IPv6
// socket).
// Netfilter IPv6 Standard Hook Priorities, from uapi/linux/netfilter_ipv6.h.
const (
NF_IP6_PRI_FIRST = math.MinInt
NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450
NF_IP6_PRI_CONNTRACK_DEFRAG = -400
NF_IP6_PRI_RAW = -300
NF_IP6_PRI_SELINUX_FIRST = -225
NF_IP6_PRI_CONNTRACK = -200
NF_IP6_PRI_MANGLE = -150
NF_IP6_PRI_NAT_DST = -100
NF_IP6_PRI_FILTER = 0
NF_IP6_PRI_SECURITY = 50
NF_IP6_PRI_NAT_SRC = 100
NF_IP6_PRI_SELINUX_LAST = 225
NF_IP6_PRI_CONNTRACK_HELPER = 300
NF_IP6_PRI_LAST = math.MaxInt
)
// Socket options for SOL_SOCLET. These correspond to values in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
const (
IP6T_BASE_CTL = 64
IP6T_SO_SET_REPLACE = IPT_BASE_CTL
IP6T_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
IP6T_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
IP6T_SO_GET_INFO = IPT_BASE_CTL
IP6T_SO_GET_ENTRIES = IPT_BASE_CTL + 1
IP6T_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 4
IP6T_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 5
IP6T_SO_GET_MAX = IP6T_SO_GET_REVISION_TARGET
)
// IP6T_ORIGINAL_DST is the ip6tables SOL_IPV6 socket option. Corresponds to
// the value in include/uapi/linux/netfilter_ipv6/ip6_tables.h.
const IP6T_ORIGINAL_DST = 80
// IP6TReplace is the argument for the IP6T_SO_SET_REPLACE sockopt. It
// corresponds to struct ip6t_replace in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
//
// +marshal
type IP6TReplace struct {
Name TableName
ValidHooks uint32
NumEntries uint32
Size uint32
HookEntry [NF_INET_NUMHOOKS]uint32
Underflow [NF_INET_NUMHOOKS]uint32
NumCounters uint32
Counters uint64 // This is really a *XTCounters.
// Entries is omitted here because it would cause IP6TReplace to be an
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
// Entries [0]IP6TEntry
}
// SizeOfIP6TReplace is the size of an IP6TReplace.
const SizeOfIP6TReplace = 96
// KernelIP6TGetEntries is identical to IP6TGetEntries, but includes the
// Entrytable field.
//
// +marshal dynamic
type KernelIP6TGetEntries struct {
IPTGetEntries
Entrytable []KernelIP6TEntry
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (ke *KernelIP6TGetEntries) SizeBytes() int {
res := ke.IPTGetEntries.SizeBytes()
for _, entry := range ke.Entrytable {
res += entry.SizeBytes()
}
return res
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (ke *KernelIP6TGetEntries) MarshalBytes(dst []byte) []byte {
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
for i := range ke.Entrytable {
dst = ke.Entrytable[i].MarshalBytes(dst)
}
return dst
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (ke *KernelIP6TGetEntries) UnmarshalBytes(src []byte) []byte {
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
for i := range ke.Entrytable {
src = ke.Entrytable[i].UnmarshalBytes(src)
}
return src
}
var _ marshal.Marshallable = (*KernelIP6TGetEntries)(nil)
// IP6TEntry is an iptables rule. It corresponds to struct ip6t_entry in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
//
// +marshal
type IP6TEntry struct {
// IPv6 is used to filter packets based on the IPv6 header.
IPv6 IP6TIP
// NFCache relates to kernel-internal caching and isn't used by
// userspace.
NFCache uint32
// TargetOffset is the byte offset from the beginning of this IPTEntry
// to the start of the entry's target.
TargetOffset uint16
// NextOffset is the byte offset from the beginning of this IPTEntry to
// the start of the next entry. It is thus also the size of the entry.
NextOffset uint16
// Comeback is a return pointer. It is not used by userspace.
Comeback uint32
_ [4]byte
// Counters holds the packet and byte counts for this rule.
Counters XTCounters
// 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 is omitted here because it would cause IPTEntry to be an extra
// byte larger (see http://www.catb.org/esr/structure-packing/).
//
// Elems [0]byte
}
// SizeOfIP6TEntry is the size of an IP6TEntry.
const SizeOfIP6TEntry = 168
// KernelIP6TEntry is identical to IP6TEntry, but includes the Elems field.
//
// +marshal dynamic
type KernelIP6TEntry struct {
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
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (ke *KernelIP6TEntry) SizeBytes() int {
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
}
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
func (ke *KernelIP6TEntry) MarshalBytes(dst []byte) []byte {
dst = ke.Entry.MarshalUnsafe(dst)
return ke.Elems.MarshalBytes(dst)
}
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
func (ke *KernelIP6TEntry) UnmarshalBytes(src []byte) []byte {
src = ke.Entry.UnmarshalUnsafe(src)
return ke.Elems.UnmarshalBytes(src)
}
var _ marshal.Marshallable = (*KernelIP6TEntry)(nil)
// IP6TIP contains information for matching a packet's IP header.
// It corresponds to struct ip6t_ip6 in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
//
// +marshal
type IP6TIP struct {
// Src is the source IP address.
Src Inet6Addr
// Dst is the destination IP address.
Dst Inet6Addr
// SrcMask is the source IP mask.
SrcMask Inet6Addr
// DstMask is the destination IP mask.
DstMask Inet6Addr
// InputInterface is the input network interface.
InputInterface [IFNAMSIZ]byte
// OutputInterface is the output network interface.
OutputInterface [IFNAMSIZ]byte
// InputInterfaceMask is the input interface mask.
InputInterfaceMask [IFNAMSIZ]byte
// OuputInterfaceMask is the output interface mask.
OutputInterfaceMask [IFNAMSIZ]byte
// Protocol is the transport protocol.
Protocol uint16
// TOS matches TOS flags when Flags indicates filtering by TOS.
TOS uint8
// Flags define matching behavior for the IP header.
Flags uint8
// InverseFlags invert the meaning of fields in struct IPTIP. See the
// IP6T_INV_* flags.
InverseFlags uint8
// Linux defines in6_addr (Inet6Addr for us) as the union of a
// 16-element byte array and a 4-element 32-bit integer array, so the
// whole struct is 4-byte aligned.
_ [3]byte
}
// SizeOfIP6TIP is the size of an IP6 header.
const SizeOfIP6TIP = 136
// Flags in IP6TIP.Flags. Corresponding constants are in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
const (
// Whether to check the Protocol field.
IP6T_F_PROTO = 0x01
// Whether to match the TOS field.
IP6T_F_TOS = 0x02
// Indicates that the jump target is an absolute GOTO, not an offset.
IP6T_F_GOTO = 0x04
// Enables all flags.
IP6T_F_MASK = 0x07
)
// Flags in IP6TIP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
const (
// Invert the meaning of InputInterface.
IP6T_INV_VIA_IN = 0x01
// Invert the meaning of OutputInterface.
IP6T_INV_VIA_OUT = 0x02
// Invert the meaning of TOS.
IP6T_INV_TOS = 0x04
// Invert the meaning of Src.
IP6T_INV_SRCIP = 0x08
// Invert the meaning of Dst.
IP6T_INV_DSTIP = 0x10
// Invert the meaning of the IPT_F_FRAG flag.
IP6T_INV_FRAG = 0x20
// Enable all flags.
IP6T_INV_MASK = 0x7F
)
// NFNATRange corresponds to struct nf_nat_range in
// include/uapi/linux/netfilter/nf_nat.h.
//
// +marshal
type NFNATRange struct {
Flags uint32
MinAddr Inet6Addr
MaxAddr Inet6Addr
MinProto uint16 // Network byte order.
MaxProto uint16 // Network byte order.
}
// SizeOfNFNATRange is the size of NFNATRange.
const SizeOfNFNATRange = 40
// NFNATRange2 corresponds to struct nf_nat_range2 in
// include/uapi/linux/netfilter/nf_nat.h.
//
// +marshal
type NFNATRange2 struct {
Flags uint32
MinAddr Inet6Addr
MaxAddr Inet6Addr
MinProto uint16 // Network byte order.
MaxProto uint16 // Network byte order.
BaseProto uint16 // Network byte order.
_ [6]byte
}
// SizeOfNFNATRange2 is the size of NFNATRange2.
const SizeOfNFNATRange2 = 48

159
pkg/abi/linux/netlink.go Normal file
View file

@ -0,0 +1,159 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Netlink protocols, from uapi/linux/netlink.h.
const (
NETLINK_ROUTE = 0
NETLINK_UNUSED = 1
NETLINK_USERSOCK = 2
NETLINK_FIREWALL = 3
NETLINK_SOCK_DIAG = 4
NETLINK_NFLOG = 5
NETLINK_XFRM = 6
NETLINK_SELINUX = 7
NETLINK_ISCSI = 8
NETLINK_AUDIT = 9
NETLINK_FIB_LOOKUP = 10
NETLINK_CONNECTOR = 11
NETLINK_NETFILTER = 12
NETLINK_IP6_FW = 13
NETLINK_DNRTMSG = 14
NETLINK_KOBJECT_UEVENT = 15
NETLINK_GENERIC = 16
NETLINK_SCSITRANSPORT = 18
NETLINK_ECRYPTFS = 19
NETLINK_RDMA = 20
NETLINK_CRYPTO = 21
)
// SockAddrNetlink is struct sockaddr_nl, from uapi/linux/netlink.h.
//
// +marshal
type SockAddrNetlink struct {
Family uint16
_ uint16
PortID uint32
Groups uint32
}
// SockAddrNetlinkSize is the size of SockAddrNetlink.
const SockAddrNetlinkSize = 12
// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h.
//
// +marshal
type NetlinkMessageHeader struct {
Length uint32
Type uint16
Flags uint16
Seq uint32
PortID uint32
}
// NetlinkMessageHeaderSize is the size of NetlinkMessageHeader.
const NetlinkMessageHeaderSize = 16
// Netlink message header flag values, from uapi/linux/netlink.h.
const (
NLM_F_REQUEST = 0x1
NLM_F_MULTI = 0x2
NLM_F_ACK = 0x4
NLM_F_ECHO = 0x8
NLM_F_DUMP_INTR = 0x10
)
// Netlink message header flags for GET requests, from uapi/linux/netlink.h.
const (
NLM_F_ROOT = 0x100
NLM_F_MATCH = 0x200
NLM_F_ATOMIC = 0x400
NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH
)
// Netlink message header flags for NEW requests, from uapi/linux/netlink.h.
const (
NLM_F_REPLACE = 0x100
NLM_F_EXCL = 0x200
NLM_F_CREATE = 0x400
NLM_F_APPEND = 0x800
)
// Netlink message header flags for DELETE requests, from uapi/linux/netlink.h.
const (
NLM_F_NONREC = 0x100
NLM_F_BULK = 0x200
)
// Standard netlink message types, from uapi/linux/netlink.h.
const (
NLMSG_NOOP = 0x1
NLMSG_ERROR = 0x2
NLMSG_DONE = 0x3
NLMSG_OVERRUN = 0x4
// NLMSG_MIN_TYPE is the first value for protocol-level types.
NLMSG_MIN_TYPE = 0x10
)
// NLMSG_ALIGNTO is the alignment of netlink messages, from
// uapi/linux/netlink.h.
const NLMSG_ALIGNTO = 4
// NetlinkAttrHeader is the header of a netlink attribute, followed by payload.
//
// This is struct nlattr, from uapi/linux/netlink.h.
//
// +marshal
type NetlinkAttrHeader struct {
Length uint16
Type uint16
}
// Netlink attribute flags, from uapi/linux/netlink.h.
const (
NLA_F_NESTED uint16 = 1 << 15
NLA_F_NET_BYTEORDER = 1 << 14
NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
)
// NetlinkAttrHeaderSize is the size of NetlinkAttrHeader.
const NetlinkAttrHeaderSize = 4
// NLA_ALIGNTO is the alignment of netlink attributes, from
// uapi/linux/netlink.h.
const NLA_ALIGNTO = 4
// Socket options, from uapi/linux/netlink.h.
const (
NETLINK_ADD_MEMBERSHIP = 1
NETLINK_DROP_MEMBERSHIP = 2
NETLINK_PKTINFO = 3
NETLINK_BROADCAST_ERROR = 4
NETLINK_NO_ENOBUFS = 5
NETLINK_LISTEN_ALL_NSID = 8
NETLINK_LIST_MEMBERSHIPS = 9
NETLINK_CAP_ACK = 10
NETLINK_EXT_ACK = 11
NETLINK_DUMP_STRICT_CHK = 12
)
// NetlinkErrorMessage is struct nlmsgerr, from uapi/linux/netlink.h.
//
// +marshal
type NetlinkErrorMessage struct {
Error int32
Header NetlinkMessageHeader
}

View file

@ -0,0 +1,92 @@
// Copyright 2025 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
// 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
// Netlink Netfilter groups.
const (
NFNLGPR_NONE Group = iota
NFNLGRP_CONNTRACK_NEW
NFNLGRP_CONNTRACK_UPDATE
NFNLGRP_CONNTRACK_DESTROY
NFNLGRP_CONNTRACK_EXP_NEW
NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY
NFNLGRP_NFTABLES
NFNLGRP_ACCT_QUOTA
NFNLGRP_NFTRACE
__NFNLGRP_MAX
NFNLGRP_MAX = __NFNLGRP_MAX - 1
)
// NetFilterGenMsg describes the netlink netfilter genmsg message, from uapi/linux/netfilter/nfnetlink.h.
//
// +marshal
type NetFilterGenMsg struct {
Family uint8
Version uint8
ResourceID uint16
}
// SizeOfNetfilterGenMsg is the size of the netlink netfilter genmsg message.
const SizeOfNetfilterGenMsg = 4
// NFNETLINK_V0 is the default version of the netlink netfilter.
const NFNETLINK_V0 = 0
// Netlink Netfilter subsystem IDs, from uapi/linux/netfilter/nfnetlink.h.
const (
NFNL_SUBSYS_NONE = iota
NFNL_SUBSYS_CTNETLINK
NFNL_SUBSYS_CTNETLINK_EXP
NFNL_SUBSYS_QUEUE
NFNL_SUBSYS_ULOG
NFNL_SUBSYS_OSF
NFNL_SUBSYS_IPSET
NFNL_SUBSYS_ACCT
NFNL_SUBSYS_CTNETLINK_TIMEOUT
NFNL_SUBSYS_CTHELPER
NFNL_SUBSYS_NFTABLES
NFNL_SUBSYS_NFT_COMPAT
NFNL_SUBSYS_HOOK
NFNL_SUBSYS_COUNT
)
// NetFilterSubsysID returns the Netfilter Subsystem ID from the netlink message header.
func (hdr *NetlinkMessageHeader) NetFilterSubsysID() uint16 {
return (hdr.Type & 0xff00) >> 8
}
// NetFilterMsgType returns the Netfilter Message Type from the netlink message header.
func (hdr *NetlinkMessageHeader) NetFilterMsgType() NfTableMsgType {
return NfTableMsgType(hdr.Type & 0x00ff)
}
// Reserved control Netlink Netfilter messages, from uapi/linux/netfilter/nfnetlink.h.
const (
NFNL_MSG_BATCH_BEGIN = NLMSG_MIN_TYPE
NFNL_MSG_BATCH_END = NLMSG_MIN_TYPE + 1
)
// Netlink Netfilter batch attributes.
const (
NFNL_BATCH_UNSPEC = iota
NFNL_BATCH_GENID
__NFNL_BATCH_MAX
NFNL_BATCH_MAX = __NFNL_BATCH_MAX - 1
)

View file

@ -0,0 +1,377 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Netlink message types for NETLINK_ROUTE sockets, from uapi/linux/rtnetlink.h.
const (
RTM_NEWLINK = 16
RTM_DELLINK = 17
RTM_GETLINK = 18
RTM_SETLINK = 19
RTM_NEWADDR = 20
RTM_DELADDR = 21
RTM_GETADDR = 22
RTM_NEWROUTE = 24
RTM_DELROUTE = 25
RTM_GETROUTE = 26
RTM_NEWNEIGH = 28
RTM_DELNEIGH = 29
RTM_GETNEIGH = 30
RTM_NEWRULE = 32
RTM_DELRULE = 33
RTM_GETRULE = 34
RTM_NEWQDISC = 36
RTM_DELQDISC = 37
RTM_GETQDISC = 38
RTM_NEWTCLASS = 40
RTM_DELTCLASS = 41
RTM_GETTCLASS = 42
RTM_NEWTFILTER = 44
RTM_DELTFILTER = 45
RTM_GETTFILTER = 46
RTM_NEWACTION = 48
RTM_DELACTION = 49
RTM_GETACTION = 50
RTM_NEWPREFIX = 52
RTM_GETMULTICAST = 58
RTM_GETANYCAST = 62
RTM_NEWNEIGHTBL = 64
RTM_GETNEIGHTBL = 66
RTM_SETNEIGHTBL = 67
RTM_NEWNDUSEROPT = 68
RTM_NEWADDRLABEL = 72
RTM_DELADDRLABEL = 73
RTM_GETADDRLABEL = 74
RTM_GETDCB = 78
RTM_SETDCB = 79
RTM_NEWNETCONF = 80
RTM_GETNETCONF = 82
RTM_NEWMDB = 84
RTM_DELMDB = 85
RTM_GETMDB = 86
RTM_NEWNSID = 88
RTM_DELNSID = 89
RTM_GETNSID = 90
)
// InterfaceInfoMessage is struct ifinfomsg, from uapi/linux/rtnetlink.h.
//
// +marshal
type InterfaceInfoMessage struct {
Family uint8
_ uint8
Type uint16
Index int32
Flags uint32
Change uint32
}
// InterfaceInfoMessageSize is the size of InterfaceInfoMessage.
const InterfaceInfoMessageSize = 16
// Interface flags, from uapi/linux/if.h.
const (
IFF_UP = 1 << 0
IFF_BROADCAST = 1 << 1
IFF_DEBUG = 1 << 2
IFF_LOOPBACK = 1 << 3
IFF_POINTOPOINT = 1 << 4
IFF_NOTRAILERS = 1 << 5
IFF_RUNNING = 1 << 6
IFF_NOARP = 1 << 7
IFF_PROMISC = 1 << 8
IFF_ALLMULTI = 1 << 9
IFF_MASTER = 1 << 10
IFF_SLAVE = 1 << 11
IFF_MULTICAST = 1 << 12
IFF_PORTSEL = 1 << 13
IFF_AUTOMEDIA = 1 << 14
IFF_DYNAMIC = 1 << 15
IFF_LOWER_UP = 1 << 16
IFF_DORMANT = 1 << 17
IFF_ECHO = 1 << 18
)
// Interface link attributes, from uapi/linux/if_link.h.
const (
IFLA_UNSPEC = 0
IFLA_ADDRESS = 1
IFLA_BROADCAST = 2
IFLA_IFNAME = 3
IFLA_MTU = 4
IFLA_LINK = 5
IFLA_QDISC = 6
IFLA_STATS = 7
IFLA_COST = 8
IFLA_PRIORITY = 9
IFLA_MASTER = 10
IFLA_WIRELESS = 11
IFLA_PROTINFO = 12
IFLA_TXQLEN = 13
IFLA_MAP = 14
IFLA_WEIGHT = 15
IFLA_OPERSTATE = 16
IFLA_LINKMODE = 17
IFLA_LINKINFO = 18
IFLA_NET_NS_PID = 19
IFLA_IFALIAS = 20
IFLA_NUM_VF = 21
IFLA_VFINFO_LIST = 22
IFLA_STATS64 = 23
IFLA_VF_PORTS = 24
IFLA_PORT_SELF = 25
IFLA_AF_SPEC = 26
IFLA_GROUP = 27
IFLA_NET_NS_FD = 28
IFLA_EXT_MASK = 29
IFLA_PROMISCUITY = 30
IFLA_NUM_TX_QUEUES = 31
IFLA_NUM_RX_QUEUES = 32
IFLA_CARRIER = 33
IFLA_PHYS_PORT_ID = 34
IFLA_CARRIER_CHANGES = 35
IFLA_PHYS_SWITCH_ID = 36
IFLA_LINK_NETNSID = 37
IFLA_PHYS_PORT_NAME = 38
IFLA_PROTO_DOWN = 39
IFLA_GSO_MAX_SEGS = 40
IFLA_GSO_MAX_SIZE = 41
)
// Interface link info attributes, from uapi/linux/if_link.h.
const (
IFLA_INFO_UNSPEC = 0
IFLA_INFO_KIND = 1
IFLA_INFO_DATA = 2
IFLA_INFO_XSTATS = 3
IFLA_INFO_SLAVE_KIND = 4
IFLA_INFO_SLAVE_DATA = 5
)
// Virtuall ethernet attributes, from uapi/linux/veth.h.
const (
VETH_INFO_PEER = 1
)
// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h.
//
// +marshal
type InterfaceAddrMessage struct {
Family uint8
PrefixLen uint8
Flags uint8
Scope uint8
Index uint32
}
// InterfaceAddrMessageSize is the size of InterfaceAddrMessage.
const InterfaceAddrMessageSize = 8
// Interface attributes, from uapi/linux/if_addr.h.
const (
IFA_UNSPEC = 0
IFA_ADDRESS = 1
IFA_LOCAL = 2
IFA_LABEL = 3
IFA_BROADCAST = 4
IFA_ANYCAST = 5
IFA_CACHEINFO = 6
IFA_MULTICAST = 7
IFA_FLAGS = 8
)
// Device types, from uapi/linux/if_arp.h.
const (
ARPHRD_NONE = 65534
ARPHRD_ETHER = 1
ARPHRD_LOOPBACK = 772
)
// RouteMessage is struct rtmsg, from uapi/linux/rtnetlink.h.
//
// +marshal
type RouteMessage struct {
Family uint8
DstLen uint8
SrcLen uint8
TOS uint8
Table uint8
Protocol uint8
Scope uint8
Type uint8
Flags uint32
}
// SizeOfRouteMessage is the size of RouteMessage.
const SizeOfRouteMessage = 12
// Route types, from uapi/linux/rtnetlink.h.
const (
// RTN_UNSPEC represents an unspecified route type.
RTN_UNSPEC = 0
// RTN_UNICAST represents a unicast route.
RTN_UNICAST = 1
// RTN_LOCAL represents a route that is accepted locally.
RTN_LOCAL = 2
// RTN_BROADCAST represents a broadcast route (Traffic is accepted locally
// as broadcast, and sent as broadcast).
RTN_BROADCAST = 3
// RTN_ANYCAST represents a anycast route (Traffic is accepted locally as
// broadcast but sent as unicast).
RTN_ANYCAST = 6
// RTN_MULTICAST represents a multicast route.
RTN_MULTICAST = 5
// RTN_BLACKHOLE represents a route where all traffic is dropped.
RTN_BLACKHOLE = 6
// RTN_UNREACHABLE represents a route where the destination is unreachable.
RTN_UNREACHABLE = 7
RTN_PROHIBIT = 8
RTN_THROW = 9
RTN_NAT = 10
RTN_XRESOLVE = 11
)
// Route protocols/origins, from uapi/linux/rtnetlink.h.
const (
RTPROT_UNSPEC = 0
RTPROT_REDIRECT = 1
RTPROT_KERNEL = 2
RTPROT_BOOT = 3
RTPROT_STATIC = 4
RTPROT_GATED = 8
RTPROT_RA = 9
RTPROT_MRT = 10
RTPROT_ZEBRA = 11
RTPROT_BIRD = 12
RTPROT_DNROUTED = 13
RTPROT_XORP = 14
RTPROT_NTK = 15
RTPROT_DHCP = 16
RTPROT_MROUTED = 17
RTPROT_BABEL = 42
RTPROT_BGP = 186
RTPROT_ISIS = 187
RTPROT_OSPF = 188
RTPROT_RIP = 189
RTPROT_EIGRP = 192
)
// Route scopes, from uapi/linux/rtnetlink.h.
const (
RT_SCOPE_UNIVERSE = 0
RT_SCOPE_SITE = 200
RT_SCOPE_LINK = 253
RT_SCOPE_HOST = 254
RT_SCOPE_NOWHERE = 255
)
// Route flags, from uapi/linux/rtnetlink.h.
const (
RTM_F_NOTIFY = 0x100
RTM_F_CLONED = 0x200
RTM_F_EQUALIZE = 0x400
RTM_F_PREFIX = 0x800
RTM_F_LOOKUP_TABLE = 0x1000
RTM_F_FIB_MATCH = 0x2000
)
// Route tables, from uapi/linux/rtnetlink.h.
const (
RT_TABLE_UNSPEC = 0
RT_TABLE_COMPAT = 252
RT_TABLE_DEFAULT = 253
RT_TABLE_MAIN = 254
RT_TABLE_LOCAL = 255
)
// Route attributes, from uapi/linux/rtnetlink.h.
const (
RTA_UNSPEC = 0
RTA_DST = 1
RTA_SRC = 2
RTA_IIF = 3
RTA_OIF = 4
RTA_GATEWAY = 5
RTA_PRIORITY = 6
RTA_PREFSRC = 7
RTA_METRICS = 8
RTA_MULTIPATH = 9
RTA_PROTOINFO = 10
RTA_FLOW = 11
RTA_CACHEINFO = 12
RTA_SESSION = 13
RTA_MP_ALGO = 14
RTA_TABLE = 15
RTA_MARK = 16
RTA_MFC_STATS = 17
RTA_VIA = 18
RTA_NEWDST = 19
RTA_PREF = 20
RTA_ENCAP_TYPE = 21
RTA_ENCAP = 22
RTA_EXPIRES = 23
RTA_PAD = 24
RTA_UID = 25
RTA_TTL_PROPAGATE = 26
RTA_IP_PROTO = 27
RTA_SPORT = 28
RTA_DPORT = 29
)
// Route flags, from include/uapi/linux/route.h.
const (
RTF_GATEWAY = 0x2
RTF_UP = 0x1
)
// RtAttr is the header of optional addition route information, as a netlink
// attribute. From include/uapi/linux/rtnetlink.h.
//
// +marshal
type RtAttr struct {
Len uint16
Type uint16
}
// SizeOfRtAttr is the size of RtAttr.
const SizeOfRtAttr = 4

464
pkg/abi/linux/nf_tables.go Normal file
View file

@ -0,0 +1,464 @@
// Copyright 2024 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
// This file contains constants required to support nf_tables.
const NFT_MAX_HOOKS = NF_INET_NUMHOOKS + 1
// Name length constants for nf_table structures. These correspond to values in
// include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_NAME_MAXLEN = 256
NFT_TABLE_MAXNAMELEN = NFT_NAME_MAXLEN
NFT_CHAIN_MAXNAMELEN = NFT_NAME_MAXLEN
NFT_SET_MAXNAMELEN = NFT_NAME_MAXLEN
NFT_OBJ_MAXNAMELEN = NFT_NAME_MAXLEN
NFT_USERDATA_MAXLEN = 256
NFT_OSF_MAXGENRELEN = 16
)
// 16-byte Registers that can be used to maintain state for rules.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_REG_VERDICT = iota
NFT_REG_1
NFT_REG_2
NFT_REG_3
NFT_REG_4
__NFT_REG_MAX
)
// 4-byte Registers that can be used to maintain state for rules.
// Note that these overlap with the 16-byte registers in memory.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_REG32_00 = 8 + iota
NFT_REG32_01
NFT_REG32_02
NFT_REG32_03
NFT_REG32_04
NFT_REG32_05
NFT_REG32_06
NFT_REG32_07
NFT_REG32_08
NFT_REG32_09
NFT_REG32_10
NFT_REG32_11
NFT_REG32_12
NFT_REG32_13
NFT_REG32_14
NFT_REG32_15
)
// Other register constants, corresponding to values in
// include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_REG_MAX = __NFT_REG_MAX - 1 // Maximum register value
NFT_REG_SIZE = 16 // Size of NFT_REG
NFT_REG32_SIZE = 4 // Size of NFT_REG32
NFT_REG32_COUNT = NFT_REG32_15 - NFT_REG32_00 + 1 // Count of 4-byte registers
)
// Internal nf table verdicts. These are used for ruleset evaluation and
// are not returned to userspace.
//
// These also share their numeric name space with the netfilter verdicts. When
// used these values are converted to uint32 (purposefully overflowing the int).
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
// Continue evaluation of the current rule.
NFT_CONTINUE int32 = -1
// Terminate evaluation of the current rule.
NFT_BREAK int32 = -2
// Push the current chain on the jump stack and jump to a chain.
NFT_JUMP int32 = -3
// Jump to a chain without pushing the current chain on the jump stack.
NFT_GOTO int32 = -4
// Return to the topmost chain on the jump stack.
NFT_RETURN int32 = -5
)
// NfTableMsgType values map to operations within the nftables api.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
type NfTableMsgType uint16
// Netlink Netfilter table message types.
const (
NFT_MSG_NEWTABLE NfTableMsgType = iota
NFT_MSG_GETTABLE
NFT_MSG_DELTABLE
NFT_MSG_NEWCHAIN
NFT_MSG_GETCHAIN
NFT_MSG_DELCHAIN
NFT_MSG_NEWRULE
NFT_MSG_GETRULE
NFT_MSG_DELRULE
NFT_MSG_NEWSET
NFT_MSG_GETSET
NFT_MSG_DELSET
NFT_MSG_NEWSETELEM
NFT_MSG_GETSETELEM
NFT_MSG_DELSETELEM
NFT_MSG_NEWGEN
NFT_MSG_GETGEN
NFT_MSG_TRACE
NFT_MSG_NEWOBJ
NFT_MSG_GETOBJ
NFT_MSG_DELOBJ
NFT_MSG_GETOBJ_RESET
NFT_MSG_NEWFLOWTABLE
NFT_MSG_GETFLOWTABLE
NFT_MSG_DELFLOWTABLE
NFT_MSG_GETRULE_RESET
NFT_MSG_DESTROYTABLE
NFT_MSG_DESTROYCHAIN
NFT_MSG_DESTROYRULE
NFT_MSG_DESTROYSET
NFT_MSG_DESTROYSETELEM
NFT_MSG_DESTROYOBJ
NFT_MSG_DESTROYFLOWTABLE
NFT_MSG_GETSETELEM_RESET
NFT_MSG_MAX
)
var nfTableMsgTypeStrings = [...]string{
NFT_MSG_NEWTABLE: "NFT_MSG_NEWTABLE",
NFT_MSG_GETTABLE: "NFT_MSG_GETTABLE",
NFT_MSG_DELTABLE: "NFT_MSG_DELTABLE",
NFT_MSG_NEWCHAIN: "NFT_MSG_NEWCHAIN",
NFT_MSG_GETCHAIN: "NFT_MSG_GETCHAIN",
NFT_MSG_DELCHAIN: "NFT_MSG_DELCHAIN",
NFT_MSG_NEWRULE: "NFT_MSG_NEWRULE",
NFT_MSG_GETRULE: "NFT_MSG_GETRULE",
NFT_MSG_DELRULE: "NFT_MSG_DELRULE",
NFT_MSG_NEWSET: "NFT_MSG_NEWSET",
NFT_MSG_GETSET: "NFT_MSG_GETSET",
NFT_MSG_DELSET: "NFT_MSG_DELSET",
NFT_MSG_NEWSETELEM: "NFT_MSG_NEWSETELEM",
NFT_MSG_GETSETELEM: "NFT_MSG_GETSETELEM",
NFT_MSG_DELSETELEM: "NFT_MSG_DELSETELEM",
NFT_MSG_NEWGEN: "NFT_MSG_NEWGEN",
NFT_MSG_GETGEN: "NFT_MSG_GETGEN",
NFT_MSG_TRACE: "NFT_MSG_TRACE",
NFT_MSG_NEWOBJ: "NFT_MSG_NEWOBJ",
NFT_MSG_GETOBJ: "NFT_MSG_GETOBJ",
NFT_MSG_DELOBJ: "NFT_MSG_DELOBJ",
NFT_MSG_GETOBJ_RESET: "NFT_MSG_GETOBJ_RESET",
NFT_MSG_NEWFLOWTABLE: "NFT_MSG_NEWFLOWTABLE",
NFT_MSG_GETFLOWTABLE: "NFT_MSG_GETFLOWTABLE",
NFT_MSG_DELFLOWTABLE: "NFT_MSG_DELFLOWTABLE",
NFT_MSG_GETRULE_RESET: "NFT_MSG_GETRULE_RESET",
NFT_MSG_DESTROYTABLE: "NFT_MSG_DESTROYTABLE",
NFT_MSG_DESTROYCHAIN: "NFT_MSG_DESTROYCHAIN",
NFT_MSG_DESTROYRULE: "NFT_MSG_DESTROYRULE",
NFT_MSG_DESTROYSET: "NFT_MSG_DESTROYSET",
NFT_MSG_DESTROYSETELEM: "NFT_MSG_DESTROYSETELEM",
NFT_MSG_DESTROYOBJ: "NFT_MSG_DESTROYOBJ",
NFT_MSG_DESTROYFLOWTABLE: "NFT_MSG_DESTROYFLOWTABLE",
NFT_MSG_GETSETELEM_RESET: "NFT_MSG_GETSETELEM_RESET",
NFT_MSG_MAX: "NFT_MSG_MAX",
}
// String returns the string representation of the NfTableMsgType.
func (msg NfTableMsgType) String() string {
if int(msg) < len(nfTableMsgTypeStrings) {
return nfTableMsgTypeStrings[msg]
}
return "UNKNOWN"
}
// NfTableListAttributes represents the netfilter attributes for lists of data.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_LIST_UNSPEC uint16 = iota
NFTA_LIST_ELEM
__NFTA_LIST_MAX
NFTA_LIST_MAX = __NFTA_LIST_MAX - 1
)
// NfTableHookAttributes represents the netfilter hook attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_HOOK_UNSPEC uint16 = iota
NFTA_HOOK_HOOKNUM
NFTA_HOOK_PRIORITY
NFTA_HOOK_DEV
NFTA_HOOK_DEVS
__NFTA_HOOK_MAX
NFTA_HOOK_MAX = __NFTA_HOOK_MAX - 1
)
// NfTableFlags represents table flags that can be set for a table, namely dormant.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_TABLE_F_DORMANT uint32 = 0x1
NFT_TABLE_F_OWNER = 0x2
NFT_TABLE_F_PERSIST = 0x4
NFT_TABLE_F_MASK = NFT_TABLE_F_DORMANT | NFT_TABLE_F_OWNER | NFT_TABLE_F_PERSIST
)
// NfTableAttributes represents the netfilter table attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_TABLE_UNSPEC uint16 = iota
NFTA_TABLE_NAME
NFTA_TABLE_FLAGS
NFTA_TABLE_USE
NFTA_TABLE_HANDLE
NFTA_TABLE_PAD
NFTA_TABLE_USERDATA
NFTA_TABLE_OWNER
__NFTA_TABLE_MAX
)
// NFTA_TABLE_MAX is the maximum netfilter table attribute.
const NFTA_TABLE_MAX = __NFTA_TABLE_MAX - 1
// NfTableChainFlags represents chain flags that can be set for a chain.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_CHAIN_BASE uint32 = (1 << 0)
NFT_CHAIN_HW_OFFLOAD = (1 << 1)
NFT_CHAIN_BINDING = (1 << 2)
NFT_CHAIN_FLAGS = (NFT_CHAIN_BASE | NFT_CHAIN_HW_OFFLOAD | NFT_CHAIN_BINDING)
)
// NfTableChainAttributes represents the netfilter chain attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_CHAIN_UNSPEC uint16 = iota
NFTA_CHAIN_TABLE
NFTA_CHAIN_HANDLE
NFTA_CHAIN_NAME
NFTA_CHAIN_HOOK
NFTA_CHAIN_POLICY
NFTA_CHAIN_USE
NFTA_CHAIN_TYPE
NFTA_CHAIN_COUNTERS
NFTA_CHAIN_PAD
NFTA_CHAIN_FLAGS
NFTA_CHAIN_ID
NFTA_CHAIN_USERDATA
__NFTA_CHAIN_MAX
NFTA_CHAIN_MAX = __NFTA_CHAIN_MAX - 1
)
// NfTableRuleAttributes represents the netfilter rule attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_RULE_UNSPEC uint16 = iota
NFTA_RULE_TABLE
NFTA_RULE_CHAIN
NFTA_RULE_HANDLE
NFTA_RULE_EXPRESSIONS
NFTA_RULE_COMPAT
NFTA_RULE_POSITION
NFTA_RULE_USERDATA
NFTA_RULE_PAD
NFTA_RULE_ID
NFTA_RULE_POSITION_ID
NFTA_RULE_CHAIN_ID
__NFTA_RULE_MAX
NFTA_RULE_MAX = __NFTA_RULE_MAX - 1
)
// NfTableDataTypes represents the netfilter data types.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_DATA_VALUE = iota
NFT_DATA_VERDICT = 0xffffff00
)
// NfTableDataReservedMask represents the netfilter data reserved mask for internally used types.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_DATA_RESERVED_MASK = 0xffffff00
)
// NfTableDataAttributes represents the netfilter data attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_DATA_UNSPEC uint16 = iota
NFTA_DATA_VALUE
NFTA_DATA_VERDICT
__NFTA_DATA_MAX
NFTA_DATA_MAX = __NFTA_DATA_MAX - 1
)
// NFT_DATA_VALUE_MAXLEN is the maximum length of a netfilter data value.
const NFT_DATA_VALUE_MAXLEN = 64
// NfTableVerdictAttributes represents the netfilter verdict attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_VERDICT_UNSPEC uint16 = iota
NFTA_VERDICT_CODE
NFTA_VERDICT_CHAIN
NFTA_VERDICT_CHAIN_ID
__NFTA_VERDICT_MAX
NFTA_VERDICT_MAX = __NFTA_VERDICT_MAX - 1
)
// NfTableExprAttributes represents the netfilter expression attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_EXPR_UNSPEC uint16 = iota
NFTA_EXPR_NAME
NFTA_EXPR_DATA
__NFTA_EXPR_MAX
NFTA_EXPR_MAX = __NFTA_EXPR_MAX - 1
)
// NfTableImmediateAttributes represents the netfilter immediate attributes.
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFTA_IMMEDIATE_UNSPEC uint16 = iota
NFTA_IMMEDIATE_DREG
NFTA_IMMEDIATE_DATA
__NFTA_IMMEDIATE_MAX
NFTA_IMMEDIATE_MAX = __NFTA_IMMEDIATE_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.
const (
NFT_CMP_EQ = iota // equal
NFT_CMP_NEQ // not equal
NFT_CMP_LT // less than
NFT_CMP_LTE // less than or equal to
NFT_CMP_GT // greater than
NFT_CMP_GTE // greater than or equal to
)
// 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.
const (
NFT_RANGE_EQ = iota
NFT_RANGE_NEQ
)
// Nf table payload expression offset bases.
// Used by the nft payload operations to access appropriate data in the packet.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_PAYLOAD_LL_HEADER = iota // link layer header
NFT_PAYLOAD_NETWORK_HEADER // network header
NFT_PAYLOAD_TRANSPORT_HEADER // transport header
NFT_PAYLOAD_INNER_HEADER // inner header / payload
NFT_PAYLOAD_TUN_HEADER // tunneling protocol header
)
// Nf table payload expression checksum types.
// Used by the nft payload set operation to mark the type of checksum to use.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_PAYLOAD_CSUM_NONE = iota // no checksumming
NFT_PAYLOAD_CSUM_INET // internet checksum (RFC 791)
NFT_PAYLOAD_CSUM_SCTP // CRC-32c, for use in SCTP header (RFC 3309)
)
// Nf table payload expression checksum flags.
// Used by the nft payload set operation to mark the flags for checksumming.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0) // use pseudoheader for L4 checksum
)
// Nf table bitwise operators.
// Used by the nft bitwise operation to perform bitwise math over register data.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_BITWISE_BOOL = iota // mask-and-xor operation for NOT, AND, OR, & XOR
NFT_BITWISE_LSHIFT // left-shift operation
NFT_BITWISE_RSHIFT // right-shift operation
)
// 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.
const (
// Traffic Class Identifier (Realm) associated with route
NFT_RT_CLASSID = iota
// Routing nexthop for IPv4 (next IPv4 address to jump to)
NFT_RT_NEXTHOP4
// Routing nexthop for IPv6 (next IPv6 address to jump to)
NFT_RT_NEXTHOP6
// Maximum Segment Size for TCP connections (largest size for a single packet)
NFT_RT_TCPMSS
// Bool for whether packet route involves a IPsec transform st xfrm is applied
NFT_RT_XFRM
)
// Nf table byteorder operators.
// Used by the nft byteorder operation to convert data in a register to a
// specific byte order.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_BYTEORDER_NTOH = iota // network to host operator
NFT_BYTEORDER_HTON // host to network operator
)
// Nf tables meta expression keys.
// Used by the nft meta operation to retrieve meta data from the packet.
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
const (
NFT_META_LEN = iota // Packet length
NFT_META_PROTOCOL // Packet ethertype protocol, invalid in OUTPUT
NFT_META_PRIORITY // Packet priority
NFT_META_MARK // Packet mark
NFT_META_IIF // Packet input interface index
NFT_META_OIF // Packet output interface index
NFT_META_IIFNAME // Packet input interface name
NFT_META_OIFNAME // Packet output interface name
NFT_META_IIFTYPE // Packet input interface type
NFT_META_OIFTYPE // Packet output interface type
NFT_META_SKUID // Originating socket UID
NFT_META_SKGID // Originating socket GID
NFT_META_NFTRACE // Packet nftrace bit
NFT_META_RTCLASSID // Realm value of packet's route
NFT_META_SECMARK // Packet secmark
NFT_META_NFPROTO // Netfilter protocol
NFT_META_L4PROTO // Layer 4 protocol number
NFT_META_BRI_IIFNAME // Packet input bridge interface name
NFT_META_BRI_OIFNAME // Packet output bridge interface name
NFT_META_PKTTYPE // Packet type, special handling for loopback
NFT_META_CPU // CPU id through smp_processor_id()
NFT_META_IIFGROUP // Packet input interface group
NFT_META_OIFGROUP // Packet output interface group
NFT_META_CGROUP // Socket control group
NFT_META_PRANDOM // A 32bit pseudo-random number
NFT_META_SECPATH // Boolean, secpath_exists
NFT_META_IIFKIND // Packet input interface kind name
NFT_META_OIFKIND // Packet output interface kind name
NFT_META_BRI_IIFPVID // Packet input bridge port pvid
NFT_META_BRI_IIFVPROTO // Packet input bridge vlan proto
NFT_META_TIME_NS // Time since epoch (in nanoseconds)
NFT_META_TIME_DAY // Day of week (from 0 = Sunday to 6 = Saturday)
NFT_META_TIME_HOUR // Hour of day (in sec), secs since start of day
NFT_META_SDIF // Slave device interface index
NFT_META_SDIFNAME // Slave device interface name
NFT_META_BRI_BROUTE // Packet br_netfilter_broute bit
)

44
pkg/abi/linux/poll.go Normal file
View file

@ -0,0 +1,44 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// PollFD is struct pollfd, used by poll(2)/ppoll(2), from uapi/asm-generic/poll.h.
//
// +marshal slice:PollFDSlice
type PollFD struct {
FD int32
Events int16
REvents int16
}
// Poll event flags, used by poll(2)/ppoll(2) and/or
// epoll_ctl(2)/epoll_wait(2), from uapi/asm-generic/poll.h.
const (
POLLIN = 0x0001
POLLPRI = 0x0002
POLLOUT = 0x0004
POLLERR = 0x0008
POLLHUP = 0x0010
POLLNVAL = 0x0020
POLLRDNORM = 0x0040
POLLRDBAND = 0x0080
POLLWRNORM = 0x0100
POLLWRBAND = 0x0200
POLLMSG = 0x0400
POLLREMOVE = 0x1000
POLLRDHUP = 0x2000
POLLFREE = 0x4000
POLL_BUSY_LOOP = 0x8000
)

179
pkg/abi/linux/prctl.go Normal file
View file

@ -0,0 +1,179 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// PR_* flags, from <linux/pcrtl.h> for prctl(2).
const (
// PR_SET_PDEATHSIG sets the process' death signal.
PR_SET_PDEATHSIG = 1
// PR_GET_PDEATHSIG gets the process' death signal.
PR_GET_PDEATHSIG = 2
// PR_GET_DUMPABLE gets the process' dumpable flag.
PR_GET_DUMPABLE = 3
// PR_SET_DUMPABLE sets the process' dumpable flag.
PR_SET_DUMPABLE = 4
// PR_GET_KEEPCAPS gets the value of the keep capabilities flag.
PR_GET_KEEPCAPS = 7
// PR_SET_KEEPCAPS sets the value of the keep capabilities flag.
PR_SET_KEEPCAPS = 8
// PR_GET_TIMING gets the process' timing method.
PR_GET_TIMING = 13
// PR_SET_TIMING sets the process' timing method.
PR_SET_TIMING = 14
// PR_SET_NAME sets the process' name.
PR_SET_NAME = 15
// PR_GET_NAME gets the process' name.
PR_GET_NAME = 16
// PR_GET_SECCOMP gets a process' seccomp mode.
PR_GET_SECCOMP = 21
// PR_SET_SECCOMP sets a process' seccomp mode.
PR_SET_SECCOMP = 22
// PR_CAPBSET_READ gets the capability bounding set.
PR_CAPBSET_READ = 23
// PR_CAPBSET_DROP sets the capability bounding set.
PR_CAPBSET_DROP = 24
// PR_GET_TSC gets the value of the flag determining whether the
// timestamp counter can be read.
PR_GET_TSC = 25
// PR_SET_TSC sets the value of the flag determining whether the
// timestamp counter can be read.
PR_SET_TSC = 26
// PR_SET_TIMERSLACK sets the process' time slack.
PR_SET_TIMERSLACK = 29
// PR_GET_TIMERSLACK gets the process' time slack.
PR_GET_TIMERSLACK = 30
// PR_TASK_PERF_EVENTS_DISABLE disables all performance counters
// attached to the calling process.
PR_TASK_PERF_EVENTS_DISABLE = 31
// PR_TASK_PERF_EVENTS_ENABLE enables all performance counters attached
// to the calling process.
PR_TASK_PERF_EVENTS_ENABLE = 32
// PR_MCE_KILL sets the machine check memory corruption kill policy for
// the calling thread.
PR_MCE_KILL = 33
// PR_MCE_KILL_GET gets the machine check memory corruption kill policy
// for the calling thread.
PR_MCE_KILL_GET = 34
// PR_SET_MM modifies certain kernel memory map descriptor fields of
// the calling process. See prctl(2) for more information.
PR_SET_MM = 35
PR_SET_MM_START_CODE = 1
PR_SET_MM_END_CODE = 2
PR_SET_MM_START_DATA = 3
PR_SET_MM_END_DATA = 4
PR_SET_MM_START_STACK = 5
PR_SET_MM_START_BRK = 6
PR_SET_MM_BRK = 7
PR_SET_MM_ARG_START = 8
PR_SET_MM_ARG_END = 9
PR_SET_MM_ENV_START = 10
PR_SET_MM_ENV_END = 11
PR_SET_MM_AUXV = 12
// PR_SET_MM_EXE_FILE supersedes the /proc/pid/exe symbolic link with a
// new one pointing to a new executable file identified by the file
// descriptor provided in arg3 argument. See prctl(2) for more
// information.
PR_SET_MM_EXE_FILE = 13
PR_SET_MM_MAP = 14
PR_SET_MM_MAP_SIZE = 15
// PR_SET_CHILD_SUBREAPER sets the "child subreaper" attribute of the
// calling process.
PR_SET_CHILD_SUBREAPER = 36
// PR_GET_CHILD_SUBREAPER gets the "child subreaper" attribute of the
// calling process.
PR_GET_CHILD_SUBREAPER = 37
// PR_SET_NO_NEW_PRIVS sets the calling thread's no_new_privs bit.
PR_SET_NO_NEW_PRIVS = 38
// PR_GET_NO_NEW_PRIVS gets the calling thread's no_new_privs bit.
PR_GET_NO_NEW_PRIVS = 39
// PR_GET_TID_ADDRESS retrieves the clear_child_tid address.
PR_GET_TID_ADDRESS = 40
// PR_SET_THP_DISABLE sets the state of the "THP disable" flag for the
// calling thread.
PR_SET_THP_DISABLE = 41
// PR_GET_THP_DISABLE gets the state of the "THP disable" flag for the
// calling thread.
PR_GET_THP_DISABLE = 42
// PR_MPX_ENABLE_MANAGEMENT enables kernel management of Memory
// Protection eXtensions (MPX) bounds tables.
PR_MPX_ENABLE_MANAGEMENT = 43
// PR_MPX_DISABLE_MANAGEMENT disables kernel management of Memory
// Protection eXtensions (MPX) bounds tables.
PR_MPX_DISABLE_MANAGEMENT = 44
// The following constants are used to control thread scheduling on cores.
PR_SCHED_CORE_SCOPE_THREAD = 0
PR_SCHED_CORE_SCOPE_THREAD_GROUP = 1
// PR_SET_VMA sets VMA attributes.
PR_SET_VMA = 0x53564d41
PR_SET_VMA_ANON_NAME = 0
// From kernel/sys.c:
ANON_VMA_NAME_MAX_LEN = 80
// PR_SET_PTRACER allows a specific process (or any, if PR_SET_PTRACER_ANY is
// specified) to ptrace the current task.
PR_SET_PTRACER = 0x59616d61
PR_SET_PTRACER_ANY = -1
)
// From <asm/prctl.h>
// Flags are used in syscall arch_prctl(2).
const (
ARCH_SET_GS = 0x1001
ARCH_SET_FS = 0x1002
ARCH_GET_FS = 0x1003
ARCH_GET_GS = 0x1004
ARCH_SET_CPUID = 0x1012
)
// Flags for prctl(PR_SET_DUMPABLE), defined in include/linux/sched/coredump.h.
const (
SUID_DUMP_DISABLE = 0
SUID_DUMP_USER = 1
SUID_DUMP_ROOT = 2
)

95
pkg/abi/linux/ptrace.go Normal file
View file

@ -0,0 +1,95 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// ptrace commands from include/uapi/linux/ptrace.h.
const (
PTRACE_TRACEME = 0
PTRACE_PEEKTEXT = 1
PTRACE_PEEKDATA = 2
PTRACE_PEEKUSR = 3
PTRACE_POKETEXT = 4
PTRACE_POKEDATA = 5
PTRACE_POKEUSR = 6
PTRACE_CONT = 7
PTRACE_KILL = 8
PTRACE_SINGLESTEP = 9
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
PTRACE_SYSCALL = 24
PTRACE_SETOPTIONS = 0x4200
PTRACE_GETEVENTMSG = 0x4201
PTRACE_GETSIGINFO = 0x4202
PTRACE_SETSIGINFO = 0x4203
PTRACE_GETREGSET = 0x4204
PTRACE_SETREGSET = 0x4205
PTRACE_SEIZE = 0x4206
PTRACE_INTERRUPT = 0x4207
PTRACE_LISTEN = 0x4208
PTRACE_PEEKSIGINFO = 0x4209
PTRACE_GETSIGMASK = 0x420a
PTRACE_SETSIGMASK = 0x420b
PTRACE_SECCOMP_GET_FILTER = 0x420c
PTRACE_SECCOMP_GET_METADATA = 0x420d
)
// ptrace commands from arch/x86/include/uapi/asm/ptrace-abi.h.
const (
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_GETFPREGS = 14
PTRACE_SETFPREGS = 15
PTRACE_GETFPXREGS = 18
PTRACE_SETFPXREGS = 19
PTRACE_OLDSETOPTIONS = 21
PTRACE_GET_THREAD_AREA = 25
PTRACE_SET_THREAD_AREA = 26
PTRACE_ARCH_PRCTL = 30
PTRACE_SYSEMU = 31
PTRACE_SYSEMU_SINGLESTEP = 32
PTRACE_SINGLEBLOCK = 33
)
// ptrace event codes from include/uapi/linux/ptrace.h.
const (
PTRACE_EVENT_FORK = 1
PTRACE_EVENT_VFORK = 2
PTRACE_EVENT_CLONE = 3
PTRACE_EVENT_EXEC = 4
PTRACE_EVENT_VFORK_DONE = 5
PTRACE_EVENT_EXIT = 6
PTRACE_EVENT_SECCOMP = 7
PTRACE_EVENT_STOP = 128
)
// PTRACE_SETOPTIONS options from include/uapi/linux/ptrace.h.
const (
PTRACE_O_TRACESYSGOOD = 1
PTRACE_O_TRACEFORK = 1 << PTRACE_EVENT_FORK
PTRACE_O_TRACEVFORK = 1 << PTRACE_EVENT_VFORK
PTRACE_O_TRACECLONE = 1 << PTRACE_EVENT_CLONE
PTRACE_O_TRACEEXEC = 1 << PTRACE_EVENT_EXEC
PTRACE_O_TRACEVFORKDONE = 1 << PTRACE_EVENT_VFORK_DONE
PTRACE_O_TRACEEXIT = 1 << PTRACE_EVENT_EXIT
PTRACE_O_TRACESECCOMP = 1 << PTRACE_EVENT_SECCOMP
PTRACE_O_EXITKILL = 1 << 20
PTRACE_O_SUSPEND_SECCOMP = 1 << 21
)
// YAMA ptrace_scope levels from security/yama/yama_lsm.c.
const (
YAMA_SCOPE_DISABLED = 0
YAMA_SCOPE_RELATIONAL = 1
)

View file

@ -0,0 +1,69 @@
// Copyright 2020 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.
//go:build amd64
// +build amd64
package linux
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
// syscall.PtraceRegs.
//
// +marshal
// +stateify savable
type PtraceRegs struct {
R15 uint64
R14 uint64
R13 uint64
R12 uint64
Rbp uint64
Rbx uint64
R11 uint64
R10 uint64
R9 uint64
R8 uint64
Rax uint64
Rcx uint64
Rdx uint64
Rsi uint64
Rdi uint64
Orig_rax uint64
Rip uint64
Cs uint64
Eflags uint64
Rsp uint64
Ss uint64
Fs_base uint64
Gs_base uint64
Ds uint64
Es uint64
Fs uint64
Gs uint64
}
// InstructionPointer returns the address of the next instruction to
// be executed.
func (p *PtraceRegs) InstructionPointer() uint64 {
return p.Rip
}
// StackPointer returns the address of the Stack pointer.
func (p *PtraceRegs) StackPointer() uint64 {
return p.Rsp
}
// SetStackPointer sets the stack pointer to the specified value.
func (p *PtraceRegs) SetStackPointer(sp uint64) {
p.Rsp = sp
}

View file

@ -0,0 +1,77 @@
// Copyright 2019 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.
//go:build arm64
// +build arm64
package linux
const (
// PSR bits
PSR_MODE_EL0t = 0x00000000
PSR_MODE_EL1t = 0x00000004
PSR_MODE_EL1h = 0x00000005
PSR_MODE_EL2t = 0x00000008
PSR_MODE_EL2h = 0x00000009
PSR_MODE_EL3t = 0x0000000c
PSR_MODE_EL3h = 0x0000000d
PSR_MODE_MASK = 0x0000000f
// AArch32 CPSR bits
PSR_MODE32_BIT = 0x00000010
// AArch64 SPSR bits
PSR_F_BIT = 0x00000040
PSR_I_BIT = 0x00000080
PSR_A_BIT = 0x00000100
PSR_D_BIT = 0x00000200
PSR_BTYPE_MASK = 0x00000c00
PSR_SSBS_BIT = 0x00001000
PSR_PAN_BIT = 0x00400000
PSR_UAO_BIT = 0x00800000
PSR_DIT_BIT = 0x01000000
PSR_TCO_BIT = 0x02000000
PSR_V_BIT = 0x10000000
PSR_C_BIT = 0x20000000
PSR_Z_BIT = 0x40000000
PSR_N_BIT = 0x80000000
)
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
// syscall.PtraceRegs.
//
// +marshal
// +stateify savable
type PtraceRegs struct {
Regs [31]uint64
Sp uint64
Pc uint64
Pstate uint64
}
// InstructionPointer returns the address of the next instruction to be
// executed.
func (p *PtraceRegs) InstructionPointer() uint64 {
return p.Pc
}
// StackPointer returns the address of the Stack pointer.
func (p *PtraceRegs) StackPointer() uint64 {
return p.Sp
}
// SetStackPointer sets the stack pointer to the specified value.
func (p *PtraceRegs) SetStackPointer(sp uint64) {
p.Sp = sp
}

130
pkg/abi/linux/rseq.go Normal file
View file

@ -0,0 +1,130 @@
// Copyright 2019 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
// Flags passed to rseq(2).
//
// Defined in include/uapi/linux/rseq.h.
const (
// RSEQ_FLAG_UNREGISTER unregisters the current thread.
RSEQ_FLAG_UNREGISTER = 1 << 0
)
// Critical section flags used in RSeqCriticalSection.Flags and RSeq.Flags.
//
// Defined in include/uapi/linux/rseq.h.
const (
// RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT inhibits restart on preemption.
RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = 1 << 0
// RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL inhibits restart on signal
// delivery.
RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = 1 << 1
// RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE inhibits restart on CPU
// migration.
RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = 1 << 2
)
// RSeqCriticalSection describes a restartable sequences critical section. It
// is equivalent to struct rseq_cs, defined in include/uapi/linux/rseq.h.
//
// In userspace, this structure is always aligned to 32 bytes.
//
// +marshal
type RSeqCriticalSection struct {
// Version is the version of this structure. Version 0 is defined here.
Version uint32
// Flags are the critical section flags, defined above.
Flags uint32
// Start is the start address of the critical section.
Start uint64
// PostCommitOffset is the offset from Start of the first instruction
// outside of the critical section.
PostCommitOffset uint64
// Abort is the abort address. It must be outside the critical section,
// and the 4 bytes prior must match the abort signature.
Abort uint64
}
const (
// SizeOfRSeqCriticalSection is the size of RSeqCriticalSection.
SizeOfRSeqCriticalSection = 32
// SizeOfRSeqSignature is the size of the signature immediately
// preceding RSeqCriticalSection.Abort.
SizeOfRSeqSignature = 4
)
// Special values for RSeq.CPUID, defined in include/uapi/linux/rseq.h.
const (
// RSEQ_CPU_ID_UNINITIALIZED indicates that this thread has not
// performed rseq initialization.
RSEQ_CPU_ID_UNINITIALIZED = ^uint32(0) // -1
// RSEQ_CPU_ID_REGISTRATION_FAILED indicates that rseq initialization
// failed.
RSEQ_CPU_ID_REGISTRATION_FAILED = ^uint32(1) // -2
)
// RSeq is the thread-local restartable sequences config/status. It
// is equivalent to struct rseq, defined in include/uapi/linux/rseq.h.
//
// In userspace, this structure is always aligned to 32 bytes.
type RSeq struct {
// CPUIDStart contains the current CPU ID if rseq is initialized.
//
// This field should only be read by the thread which registered this
// structure, and must be read atomically.
CPUIDStart uint32
// CPUID contains the current CPU ID or one of the CPU ID special
// values defined above.
//
// This field should only be read by the thread which registered this
// structure, and must be read atomically.
CPUID uint32
// RSeqCriticalSection is a pointer to the current RSeqCriticalSection
// block, or NULL. It is reset to NULL by the kernel on restart or
// non-restarting preempt/signal.
//
// This field should only be written by the thread which registered
// this structure, and must be written atomically.
RSeqCriticalSection uint64
// Flags are the critical section flags that apply to all critical
// sections on this thread, defined above.
Flags uint32
}
const (
// SizeOfRSeq is the size of RSeq.
//
// Note that RSeq is naively 24 bytes. However, it has 32-byte
// alignment, which in C increases sizeof to 32. That is the size that
// the Linux kernel uses.
SizeOfRSeq = 32
// AlignOfRSeq is the standard alignment of RSeq.
AlignOfRSeq = 32
// OffsetOfRSeqCriticalSection is the offset of RSeqCriticalSection in RSeq.
OffsetOfRSeqCriticalSection = 8
)

48
pkg/abi/linux/rusage.go Normal file
View file

@ -0,0 +1,48 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Flags that may be used with wait4(2) and getrusage(2).
const (
// wait4(2) uses this to aggregate RUSAGE_SELF and RUSAGE_CHILDREN.
RUSAGE_BOTH = -0x2
// getrusage(2) flags.
RUSAGE_CHILDREN = -0x1
RUSAGE_SELF = 0x0
RUSAGE_THREAD = 0x1
)
// Rusage represents the Linux struct rusage.
//
// +marshal
type Rusage struct {
UTime Timeval
STime Timeval
MaxRSS int64
IXRSS int64
IDRSS int64
ISRSS int64
MinFlt int64
MajFlt int64
NSwap int64
InBlock int64
OuBlock int64
MsgSnd int64
MsgRcv int64
NSignals int64
NVCSw int64
NIvCSw int64
}

37
pkg/abi/linux/sched.go Normal file
View file

@ -0,0 +1,37 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Scheduling policies, exposed by sched_getscheduler(2)/sched_setscheduler(2).
const (
SCHED_NORMAL = 0
SCHED_FIFO = 1
SCHED_RR = 2
SCHED_BATCH = 3
SCHED_IDLE = 5
SCHED_DEADLINE = 6
SCHED_MICROQ = 16
// SCHED_RESET_ON_FORK is a flag that indicates that the process is
// reverted back to SCHED_NORMAL on fork.
SCHED_RESET_ON_FORK = 0x40000000
)
// Scheduling priority group selectors.
const (
PRIO_PGRP = 0x1
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
)

173
pkg/abi/linux/seccomp.go Normal file
View file

@ -0,0 +1,173 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import "fmt"
// Seccomp constants taken from <linux/seccomp.h>.
const (
SECCOMP_MODE_NONE = 0
SECCOMP_MODE_FILTER = 2
SECCOMP_RET_ACTION_FULL = 0xffff0000
SECCOMP_RET_ACTION = 0x7fff0000
SECCOMP_RET_DATA = 0x0000ffff
SECCOMP_SET_MODE_FILTER = 1
SECCOMP_GET_ACTION_AVAIL = 2
SECCOMP_GET_NOTIF_SIZES = 3
SECCOMP_FILTER_FLAG_TSYNC = 1
SECCOMP_FILTER_FLAG_NEW_LISTENER = 1 << 3
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 1
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 1
)
// BPFAction is an action for a BPF filter.
type BPFAction uint32
// BPFAction definitions.
const (
SECCOMP_RET_KILL_PROCESS BPFAction = 0x80000000
SECCOMP_RET_KILL_THREAD BPFAction = 0x00000000
SECCOMP_RET_TRAP BPFAction = 0x00030000
SECCOMP_RET_ERRNO BPFAction = 0x00050000
SECCOMP_RET_TRACE BPFAction = 0x7ff00000
SECCOMP_RET_USER_NOTIF BPFAction = 0x7fc00000
SECCOMP_RET_ALLOW BPFAction = 0x7fff0000
)
func (a BPFAction) String() string {
switch a & SECCOMP_RET_ACTION_FULL {
case SECCOMP_RET_KILL_PROCESS:
return "kill process"
case SECCOMP_RET_KILL_THREAD:
return "kill thread"
case SECCOMP_RET_TRAP:
data := a.Data()
if data == 0 {
return "trap"
}
return fmt.Sprintf("trap (data=%#x)", data)
case SECCOMP_RET_ERRNO:
return fmt.Sprintf("return errno=%#x", a.Data())
case SECCOMP_RET_TRACE:
data := a.Data()
if data == 0 {
return "trace"
}
return fmt.Sprintf("trace (data=%#x)", data)
case SECCOMP_RET_ALLOW:
return "allow"
case SECCOMP_RET_USER_NOTIF:
return "unotify"
}
return fmt.Sprintf("invalid action: %#x", uint32(a))
}
// Data returns the SECCOMP_RET_DATA portion of the action.
func (a BPFAction) Data() uint16 {
return uint16(a & SECCOMP_RET_DATA)
}
// WithReturnCode sets the lower 16 bits of the SECCOMP_RET_ERRNO or
// SECCOMP_RET_TRACE actions to the provided return code, overwriting the previous
// action, and returns a new BPFAction. If not SECCOMP_RET_ERRNO or
// SECCOMP_RET_TRACE then this panics.
func (a BPFAction) WithReturnCode(code uint16) BPFAction {
// mask out the previous return value
baseAction := a & SECCOMP_RET_ACTION_FULL
if baseAction == SECCOMP_RET_ERRNO || baseAction == SECCOMP_RET_TRACE {
return BPFAction(uint32(baseAction) | uint32(code))
}
panic("WithReturnCode only valid for SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE")
}
// SockFprog is sock_fprog taken from <linux/filter.h>.
type SockFprog struct {
Len uint16
pad [6]byte
Filter *BPFInstruction
}
// SeccompData is equivalent to struct seccomp_data, which contains the data
// passed to seccomp-bpf filters.
//
// +marshal
type SeccompData struct {
// Nr is the system call number.
Nr int32
// Arch is an AUDIT_ARCH_* value indicating the system call convention.
Arch uint32
// InstructionPointer is the value of the instruction pointer at the time
// of the system call.
InstructionPointer uint64
// Args contains the first 6 system call arguments.
Args [6]uint64
}
// SeccompNotifResp is equivalent to struct seccomp_notif_resp.
//
// +marshal
type SeccompNotifResp struct {
ID uint64
Val int64
Error int32
Flags uint32
}
// SeccompNotifSizes is equivalent to struct seccomp_notif_sizes.
//
// +marshal
type SeccompNotifSizes struct {
Notif uint16
Notif_resp uint16
Data uint16
}
// SeccompNotif is equivalent to struct seccomp_notif.
//
// +marshal
type SeccompNotif struct {
ID uint64
Pid int32
Flags uint32
Data SeccompData
}
// String returns a human-friendly representation of this `SeccompData`.
func (sd SeccompData) String() string {
return fmt.Sprintf(
"sysno=%d arch=%#x rip=%#x args=[%#x %#x %#x %#x %#x %#x]",
sd.Nr,
sd.Arch,
sd.InstructionPointer,
sd.Args[0],
sd.Args[1],
sd.Args[2],
sd.Args[3],
sd.Args[4],
sd.Args[5],
)
}

82
pkg/abi/linux/sem.go Normal file
View file

@ -0,0 +1,82 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// semctl Command Definitions. Source: include/uapi/linux/sem.h
const (
GETPID = 11
GETVAL = 12
GETALL = 13
GETNCNT = 14
GETZCNT = 15
SETVAL = 16
SETALL = 17
)
// ipcs ctl cmds. Source: include/uapi/linux/sem.h
const (
SEM_STAT = 18
SEM_INFO = 19
SEM_STAT_ANY = 20
)
// Information about system-wide semaphore limits and parameters.
//
// Source: include/uapi/linux/sem.h
const (
SEMMNI = 32000
SEMMSL = 32000
SEMMNS = SEMMNI * SEMMSL
SEMOPM = 500
SEMVMX = 32767
SEMAEM = SEMVMX
SEMUME = SEMOPM
SEMMNU = SEMMNS
SEMMAP = SEMMNS
SEMUSZ = 20
)
// Semaphore flags.
const (
SEM_UNDO = 0x1000
)
// Sembuf is equivalent to struct sembuf.
//
// +marshal slice:SembufSlice
type Sembuf struct {
SemNum uint16
SemOp int16
SemFlg int16
}
// SemInfo is equivalent to struct seminfo.
//
// Source: include/uapi/linux/sem.h
//
// +marshal
type SemInfo struct {
SemMap uint32
SemMni uint32
SemMns uint32
SemMnu uint32
SemMsl uint32
SemOpm uint32
SemUme uint32
SemUsz uint32
SemVmx uint32
SemAem uint32
}

View file

@ -0,0 +1,34 @@
// Copyright 2020 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.
//go:build amd64
// +build amd64
package linux
// SemidDS is equivalent to struct semid64_ds.
//
// Source: arch/x86/include/uapi/asm/sembuf.h
//
// +marshal
type SemidDS struct {
SemPerm IPCPerm
SemOTime TimeT
unused1 uint64
SemCTime TimeT
unused2 uint64
SemNSems uint64
unused3 uint64
unused4 uint64
}

View file

@ -0,0 +1,32 @@
// Copyright 2020 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.
//go:build arm64
// +build arm64
package linux
// SemidDS is equivalent to struct semid64_ds.
//
// Source: include/uapi/asm-generic/sembuf.h
//
// +marshal
type SemidDS struct {
SemPerm IPCPerm
SemOTime TimeT
SemCTime TimeT
SemNSems uint64
unused3 uint64
unused4 uint64
}

92
pkg/abi/linux/shm.go Normal file
View file

@ -0,0 +1,92 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import "math"
// shmat(2) flags. Source: include/uapi/linux/shm.h
const (
SHM_RDONLY = 0o10000 // Read-only access.
SHM_RND = 0o20000 // Round attach address to SHMLBA boundary.
SHM_REMAP = 0o40000 // Take-over region on attach.
SHM_EXEC = 0o100000 // Execution access.
)
// IPCPerm.Mode upper byte flags. Source: include/linux/shm.h
const (
SHM_DEST = 0o1000 // Segment will be destroyed on last detach.
SHM_LOCKED = 0o2000 // Segment will not be swapped.
SHM_HUGETLB = 0o4000 // Segment will use huge TLB pages.
SHM_NORESERVE = 0o10000 // Don't check for reservations.
)
// Additional Linux-only flags for shmctl(2). Source: include/uapi/linux/shm.h
const (
SHM_LOCK = 11
SHM_UNLOCK = 12
SHM_STAT = 13
SHM_INFO = 14
)
// SHM defaults as specified by linux. Source: include/uapi/linux/shm.h
const (
SHMMIN = 1
SHMMNI = 4096
SHMMAX = math.MaxUint64 - 1<<24
SHMALL = math.MaxUint64 - 1<<24
SHMSEG = 4096
)
// ShmidDS is equivalent to struct shmid64_ds. Source:
// include/uapi/asm-generic/shmbuf.h
//
// +marshal
type ShmidDS struct {
ShmPerm IPCPerm
ShmSegsz uint64
ShmAtime TimeT
ShmDtime TimeT
ShmCtime TimeT
ShmCpid int32
ShmLpid int32
ShmNattach uint64
Unused4 uint64
Unused5 uint64
}
// ShmParams is equivalent to struct shminfo. Source: include/uapi/linux/shm.h
//
// +marshal
type ShmParams struct {
ShmMax uint64
ShmMin uint64
ShmMni uint64
ShmSeg uint64
ShmAll uint64
}
// ShmInfo is equivalent to struct shm_info. Source: include/uapi/linux/shm.h
//
// +marshal
type ShmInfo struct {
UsedIDs int32 // Number of currently existing segments.
_ [4]byte
ShmTot uint64 // Total number of shared memory pages.
ShmRss uint64 // Number of resident shared memory pages.
ShmSwp uint64 // Number of swapped shared memory pages.
SwapAttempts uint64 // Unused since Linux 2.4.
SwapSuccesses uint64 // Unused since Linux 2.4.
}

552
pkg/abi/linux/signal.go Normal file
View file

@ -0,0 +1,552 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"github.com/sagernet/gvisor/pkg/bits"
"github.com/sagernet/gvisor/pkg/hostarch"
)
const (
// SignalMaximum is the highest valid signal number.
SignalMaximum = 64
// FirstStdSignal is the lowest standard signal number.
FirstStdSignal = 1
// LastStdSignal is the highest standard signal number.
LastStdSignal = 31
// FirstRTSignal is the lowest real-time signal number.
//
// 32 (SIGCANCEL) and 33 (SIGSETXID) are used internally by glibc.
FirstRTSignal = 32
// LastRTSignal is the highest real-time signal number.
LastRTSignal = 64
// NumStdSignals is the number of standard signals.
NumStdSignals = LastStdSignal - FirstStdSignal + 1
// NumRTSignals is the number of realtime signals.
NumRTSignals = LastRTSignal - FirstRTSignal + 1
)
// Signal is a signal number.
type Signal int
// IsValid returns true if s is a valid standard or realtime signal. (0 is not
// considered valid; interfaces special-casing signal number 0 should check for
// 0 first before asserting validity.)
func (s Signal) IsValid() bool {
return s > 0 && s <= SignalMaximum
}
// IsStandard returns true if s is a standard signal.
//
// Preconditions: s.IsValid().
func (s Signal) IsStandard() bool {
return s <= LastStdSignal
}
// IsRealtime returns true if s is a realtime signal.
//
// Preconditions: s.IsValid().
func (s Signal) IsRealtime() bool {
return s >= FirstRTSignal
}
// Index returns the index for signal s into arrays of both standard and
// realtime signals (e.g. signal masks).
//
// Preconditions: s.IsValid().
func (s Signal) Index() int {
return int(s - 1)
}
// Signals.
const (
SIGABRT = Signal(6)
SIGALRM = Signal(14)
SIGBUS = Signal(7)
SIGCHLD = Signal(17)
SIGCLD = Signal(17)
SIGCONT = Signal(18)
SIGFPE = Signal(8)
SIGHUP = Signal(1)
SIGILL = Signal(4)
SIGINT = Signal(2)
SIGIO = Signal(29)
SIGIOT = Signal(6)
SIGKILL = Signal(9)
SIGPIPE = Signal(13)
SIGPOLL = Signal(29)
SIGPROF = Signal(27)
SIGPWR = Signal(30)
SIGQUIT = Signal(3)
SIGSEGV = Signal(11)
SIGSTKFLT = Signal(16)
SIGSTOP = Signal(19)
SIGSYS = Signal(31)
SIGTERM = Signal(15)
SIGTRAP = Signal(5)
SIGTSTP = Signal(20)
SIGTTIN = Signal(21)
SIGTTOU = Signal(22)
SIGUNUSED = Signal(31)
SIGURG = Signal(23)
SIGUSR1 = Signal(10)
SIGUSR2 = Signal(12)
SIGVTALRM = Signal(26)
SIGWINCH = Signal(28)
SIGXCPU = Signal(24)
SIGXFSZ = Signal(25)
)
// SignalSet is a signal mask with a bit corresponding to each signal.
//
// +marshal
type SignalSet uint64
// SignalSetSize is the size in bytes of a SignalSet.
const SignalSetSize = 8
// MakeSignalSet returns SignalSet with the bit corresponding to each of the
// given signals set.
func MakeSignalSet(sigs ...Signal) SignalSet {
indices := make([]int, len(sigs))
for i, sig := range sigs {
indices[i] = sig.Index()
}
return SignalSet(bits.Mask64(indices...))
}
// SignalSetOf returns a SignalSet with a single signal set.
func SignalSetOf(sig Signal) SignalSet {
return SignalSet(bits.MaskOf64(sig.Index()))
}
// ForEachSignal invokes f for each signal set in the given mask.
func ForEachSignal(mask SignalSet, f func(sig Signal)) {
bits.ForEachSetBit64(uint64(mask), func(i int) {
f(Signal(i + 1))
})
}
// 'how' values for rt_sigprocmask(2).
const (
// SIG_BLOCK blocks the signals in the set.
SIG_BLOCK = 0
// SIG_UNBLOCK blocks the signals in the set.
SIG_UNBLOCK = 1
// SIG_SETMASK sets the signal mask to set.
SIG_SETMASK = 2
)
// Signal actions for rt_sigaction(2), from uapi/asm-generic/signal-defs.h.
const (
// SIG_DFL performs the default action.
SIG_DFL = 0
// SIG_IGN ignores the signal.
SIG_IGN = 1
)
// Signal action flags for rt_sigaction(2), from uapi/asm-generic/signal.h.
const (
SA_NOCLDSTOP = 0x00000001
SA_NOCLDWAIT = 0x00000002
SA_SIGINFO = 0x00000004
SA_RESTORER = 0x04000000
SA_ONSTACK = 0x08000000
SA_RESTART = 0x10000000
SA_NODEFER = 0x40000000
SA_RESETHAND = 0x80000000
SA_NOMASK = SA_NODEFER
SA_ONESHOT = SA_RESETHAND
)
// Signal stack flags for signalstack(2), from include/uapi/linux/signal.h.
const (
SS_ONSTACK = 1
SS_DISABLE = 2
)
// SIGPOLL si_codes.
const (
// SI_POLL is defined as __SI_POLL in Linux 2.6.
SI_POLL = 2 << 16
// POLL_IN indicates that data input available.
POLL_IN = SI_POLL | 1
// POLL_OUT indicates that output buffers available.
POLL_OUT = SI_POLL | 2
// POLL_MSG indicates that an input message available.
POLL_MSG = SI_POLL | 3
// POLL_ERR indicates that there was an i/o error.
POLL_ERR = SI_POLL | 4
// POLL_PRI indicates that a high priority input available.
POLL_PRI = SI_POLL | 5
// POLL_HUP indicates that a device disconnected.
POLL_HUP = SI_POLL | 6
)
// Possible values for si_code.
const (
// SI_USER is sent by kill, sigsend, raise.
SI_USER = 0
// SI_KERNEL is sent by the kernel from somewhere.
SI_KERNEL = 0x80
// SI_QUEUE is sent by sigqueue.
SI_QUEUE = -1
// SI_TIMER is sent by timer expiration.
SI_TIMER = -2
// SI_MESGQ is sent by real time mesq state change.
SI_MESGQ = -3
// SI_ASYNCIO is sent by AIO completion.
SI_ASYNCIO = -4
// SI_SIGIO is sent by queued SIGIO.
SI_SIGIO = -5
// SI_TKILL is sent by tkill system call.
SI_TKILL = -6
// SI_DETHREAD is sent by execve() killing subsidiary threads.
SI_DETHREAD = -7
// SI_ASYNCNL is sent by glibc async name lookup completion.
SI_ASYNCNL = -60
)
// CLD_* codes are only meaningful for SIGCHLD.
const (
// CLD_EXITED indicates that a task exited.
CLD_EXITED = 1
// CLD_KILLED indicates that a task was killed by a signal.
CLD_KILLED = 2
// CLD_DUMPED indicates that a task was killed by a signal and then dumped
// core.
CLD_DUMPED = 3
// CLD_TRAPPED indicates that a task was stopped by ptrace.
CLD_TRAPPED = 4
// CLD_STOPPED indicates that a thread group completed a group stop.
CLD_STOPPED = 5
// CLD_CONTINUED indicates that a group-stopped thread group was continued.
CLD_CONTINUED = 6
)
// SYS_* codes are only meaningful for SIGSYS.
const (
// SYS_SECCOMP indicates that a signal originates from seccomp.
SYS_SECCOMP = 1
)
// Possible values for Sigevent.Notify, aka struct sigevent::sigev_notify.
const (
SIGEV_SIGNAL = 0
SIGEV_NONE = 1
SIGEV_THREAD = 2
SIGEV_THREAD_ID = 4
)
// SIGTRAP si_codes
const (
TRAP_BRKPT = 1
TRAP_TRACE = 2
TRAP_BRANCH = 3
TRAP_HWBKPT = 4
)
// Sigevent represents struct sigevent.
//
// +marshal
type Sigevent struct {
Value uint64 // union sigval {int, void*}
Signo int32
Notify int32
// struct sigevent here contains 48-byte union _sigev_un. However, only
// member _tid is significant to the kernel.
Tid int32
UnRemainder [44]byte
}
// SigAction represents struct sigaction.
//
// +marshal
// +stateify savable
type SigAction struct {
Handler uint64
Flags uint64
Restorer uint64
Mask SignalSet
}
// SignalStack represents information about a user stack, and is equivalent to
// stack_t.
//
// +marshal
// +stateify savable
type SignalStack struct {
Addr uint64
Flags uint32
_ uint32
Size uint64
}
// Contains checks if the stack pointer is within this stack.
func (s *SignalStack) Contains(sp hostarch.Addr) bool {
return hostarch.Addr(s.Addr) < sp && sp <= hostarch.Addr(s.Addr+s.Size)
}
// Top returns the stack's top address.
func (s *SignalStack) Top() hostarch.Addr {
return hostarch.Addr(s.Addr + s.Size)
}
// IsEnabled returns true iff this signal stack is marked as enabled.
func (s *SignalStack) IsEnabled() bool {
return s.Flags&SS_DISABLE == 0
}
// SignalInfo represents information about a signal being delivered, and is
// equivalent to struct siginfo in linux kernel(linux/include/uapi/asm-generic/siginfo.h).
//
// +marshal
// +stateify savable
type SignalInfo struct {
Signo int32 // Signal number
Errno int32 // Errno value
Code int32 // Signal code
_ uint32
// struct siginfo::_sifields is a union. In SignalInfo, fields in the union
// are accessed through methods.
//
// For reference, here is the definition of _sifields: (_sigfault._trapno,
// which does not exist on x86, omitted for clarity)
//
// union {
// int _pad[SI_PAD_SIZE];
//
// /* kill() */
// struct {
// __kernel_pid_t _pid; /* sender's pid */
// __ARCH_SI_UID_T _uid; /* sender's uid */
// } _kill;
//
// /* POSIX.1b timers */
// struct {
// __kernel_timer_t _tid; /* timer id */
// int _overrun; /* overrun count */
// char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
// sigval_t _sigval; /* same as below */
// int _sys_private; /* not to be passed to user */
// } _timer;
//
// /* POSIX.1b signals */
// struct {
// __kernel_pid_t _pid; /* sender's pid */
// __ARCH_SI_UID_T _uid; /* sender's uid */
// sigval_t _sigval;
// } _rt;
//
// /* SIGCHLD */
// struct {
// __kernel_pid_t _pid; /* which child */
// __ARCH_SI_UID_T _uid; /* sender's uid */
// int _status; /* exit code */
// __ARCH_SI_CLOCK_T _utime;
// __ARCH_SI_CLOCK_T _stime;
// } _sigchld;
//
// /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
// struct {
// void *_addr; /* faulting insn/memory ref. */
// short _addr_lsb; /* LSB of the reported address */
// } _sigfault;
//
// /* SIGPOLL */
// struct {
// __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
// int _fd;
// } _sigpoll;
//
// /* SIGSYS */
// struct {
// void *_call_addr; /* calling user insn */
// int _syscall; /* triggering system call number */
// unsigned int _arch; /* AUDIT_ARCH_* of syscall */
// } _sigsys;
// } _sifields;
//
// _sifields is padded so that the size of siginfo is SI_MAX_SIZE = 128
// bytes.
Fields [128 - 16]byte
}
// FixSignalCodeForUser fixes up si_code.
//
// The si_code we get from Linux may contain the kernel-specific code in the
// top 16 bits if it's positive (e.g., from ptrace). Linux's
// copy_siginfo_to_user does:
// err |= __put_user((short)from->si_code, &to->si_code);
// to mask out those bits and we need to do the same.
func (s *SignalInfo) FixSignalCodeForUser() {
if s.Code > 0 {
s.Code &= 0x0000ffff
}
}
// PID returns the si_pid field.
func (s *SignalInfo) PID() int32 {
return int32(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
}
// SetPID mutates the si_pid field.
func (s *SignalInfo) SetPID(val int32) {
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
}
// UID returns the si_uid field.
func (s *SignalInfo) UID() int32 {
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
}
// SetUID mutates the si_uid field.
func (s *SignalInfo) SetUID(val int32) {
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
}
// Sigval returns the sigval field, which is aliased to both si_int and si_ptr.
func (s *SignalInfo) Sigval() uint64 {
return hostarch.ByteOrder.Uint64(s.Fields[8:16])
}
// SetSigval mutates the sigval field.
func (s *SignalInfo) SetSigval(val uint64) {
hostarch.ByteOrder.PutUint64(s.Fields[8:16], val)
}
// TimerID returns the si_timerid field.
func (s *SignalInfo) TimerID() TimerID {
return TimerID(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
}
// SetTimerID sets the si_timerid field.
func (s *SignalInfo) SetTimerID(val TimerID) {
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
}
// Overrun returns the si_overrun field.
func (s *SignalInfo) Overrun() int32 {
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
}
// SetOverrun sets the si_overrun field.
func (s *SignalInfo) SetOverrun(val int32) {
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
}
// Addr returns the si_addr field.
func (s *SignalInfo) Addr() uint64 {
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
}
// SetAddr sets the si_addr field.
func (s *SignalInfo) SetAddr(val uint64) {
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
}
// Status returns the si_status field.
func (s *SignalInfo) Status() int32 {
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
}
// SetStatus mutates the si_status field.
func (s *SignalInfo) SetStatus(val int32) {
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
}
// CallAddr returns the si_call_addr field.
func (s *SignalInfo) CallAddr() uint64 {
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
}
// SetCallAddr mutates the si_call_addr field.
func (s *SignalInfo) SetCallAddr(val uint64) {
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
}
// Syscall returns the si_syscall field.
func (s *SignalInfo) Syscall() int32 {
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
}
// SetSyscall mutates the si_syscall field.
func (s *SignalInfo) SetSyscall(val int32) {
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
}
// Arch returns the si_arch field.
func (s *SignalInfo) Arch() uint32 {
return hostarch.ByteOrder.Uint32(s.Fields[12:16])
}
// SetArch mutates the si_arch field.
func (s *SignalInfo) SetArch(val uint32) {
hostarch.ByteOrder.PutUint32(s.Fields[12:16], val)
}
// Band returns the si_band field.
func (s *SignalInfo) Band() int64 {
return int64(hostarch.ByteOrder.Uint64(s.Fields[0:8]))
}
// SetBand mutates the si_band field.
func (s *SignalInfo) SetBand(val int64) {
// Note: this assumes the platform uses `long` as `__ARCH_SI_BAND_T`.
// On some platforms, which gVisor doesn't support, `__ARCH_SI_BAND_T` is
// `int`. See siginfo.h.
hostarch.ByteOrder.PutUint64(s.Fields[0:8], uint64(val))
}
// FD returns the si_fd field.
func (s *SignalInfo) FD() uint32 {
return hostarch.ByteOrder.Uint32(s.Fields[8:12])
}
// SetFD mutates the si_fd field.
func (s *SignalInfo) SetFD(val uint32) {
hostarch.ByteOrder.PutUint32(s.Fields[8:12], val)
}

47
pkg/abi/linux/signalfd.go Normal file
View file

@ -0,0 +1,47 @@
// Copyright 2019 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
const (
// SFD_NONBLOCK is a signalfd(2) flag.
SFD_NONBLOCK = 0o0004000
// SFD_CLOEXEC is a signalfd(2) flag.
SFD_CLOEXEC = 0o2000000
)
// SignalfdSiginfo is the siginfo encoding for signalfds.
//
// +marshal
type SignalfdSiginfo struct {
Signo uint32
Errno int32
Code int32
PID uint32
UID uint32
FD int32
TID uint32
Band uint32
Overrun uint32
TrapNo uint32
Status int32
Int int32
Ptr uint64
UTime uint64
STime uint64
Addr uint64
AddrLSB uint16
_ [48]uint8 `marshal:"unaligned"`
}

740
pkg/abi/linux/socket.go Normal file
View file

@ -0,0 +1,740 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"github.com/sagernet/gvisor/pkg/marshal"
)
// Address families, from linux/socket.h.
const (
AF_UNSPEC = 0
AF_UNIX = 1
AF_INET = 2
AF_AX25 = 3
AF_IPX = 4
AF_APPLETALK = 5
AF_NETROM = 6
AF_BRIDGE = 7
AF_ATMPVC = 8
AF_X25 = 9
AF_INET6 = 10
AF_ROSE = 11
AF_DECnet = 12
AF_NETBEUI = 13
AF_SECURITY = 14
AF_KEY = 15
AF_NETLINK = 16
AF_PACKET = 17
AF_ASH = 18
AF_ECONET = 19
AF_ATMSVC = 20
AF_RDS = 21
AF_SNA = 22
AF_IRDA = 23
AF_PPPOX = 24
AF_WANPIPE = 25
AF_LLC = 26
AF_IB = 27
AF_MPLS = 28
AF_CAN = 29
AF_TIPC = 30
AF_BLUETOOTH = 31
AF_IUCV = 32
AF_RXRPC = 33
AF_ISDN = 34
AF_PHONET = 35
AF_IEEE802154 = 36
AF_CAIF = 37
AF_ALG = 38
AF_NFC = 39
AF_VSOCK = 40
)
// sendmsg(2)/recvmsg(2) flags, from linux/socket.h.
const (
MSG_OOB = 0x1
MSG_PEEK = 0x2
MSG_DONTROUTE = 0x4
MSG_TRYHARD = 0x4
MSG_CTRUNC = 0x8
MSG_PROBE = 0x10
MSG_TRUNC = 0x20
MSG_DONTWAIT = 0x40
MSG_EOR = 0x80
MSG_WAITALL = 0x100
MSG_FIN = 0x200
MSG_EOF = MSG_FIN
MSG_SYN = 0x400
MSG_CONFIRM = 0x800
MSG_RST = 0x1000
MSG_ERRQUEUE = 0x2000
MSG_NOSIGNAL = 0x4000
MSG_MORE = 0x8000
MSG_WAITFORONE = 0x10000
MSG_SENDPAGE_NOTLAST = 0x20000
MSG_ZEROCOPY = 0x4000000
MSG_FASTOPEN = 0x20000000
MSG_CMSG_CLOEXEC = 0x40000000
)
// Set/get socket option levels, from socket.h.
const (
SOL_IP = 0
SOL_SOCKET = 1
SOL_TCP = 6
SOL_UDP = 17
SOL_IPV6 = 41
SOL_ICMPV6 = 58
SOL_RAW = 255
SOL_PACKET = 263
SOL_NETLINK = 270
)
// A SockType is a type (as opposed to family) of sockets. These are enumerated
// below as SOCK_* constants.
type SockType int
// Socket types, from linux/net.h.
const (
SOCK_STREAM SockType = 1
SOCK_DGRAM SockType = 2
SOCK_RAW SockType = 3
SOCK_RDM SockType = 4
SOCK_SEQPACKET SockType = 5
SOCK_DCCP SockType = 6
SOCK_PACKET SockType = 10
)
// SOCK_TYPE_MASK covers all of the above socket types. The remaining bits are
// flags. From linux/net.h.
const SOCK_TYPE_MASK = 0xf
// socket(2)/socketpair(2)/accept4(2) flags, from linux/net.h.
const (
SOCK_CLOEXEC = O_CLOEXEC
SOCK_NONBLOCK = O_NONBLOCK
)
// shutdown(2) how commands, from <linux/net.h>.
const (
SHUT_RD = 0
SHUT_WR = 1
SHUT_RDWR = 2
)
// Packet types from <linux/if_packet.h>
const (
PACKET_HOST = 0 // To us
PACKET_BROADCAST = 1 // To all
PACKET_MULTICAST = 2 // To group
PACKET_OTHERHOST = 3 // To someone else
PACKET_OUTGOING = 4 // Outgoing of any type
)
// Packet socket options from <linux/if_packet.h>
const (
PACKET_ADD_MEMBERSHIP = 1
PACKET_RX_RING = 5
PACKET_STATISTICS = 6
PACKET_AUXDATA = 8
PACKET_VERSION = 10
PACKET_HDRLEN = 11
PACKET_RESERVE = 12
)
// Statuses for a frame in a packet_mmap ring buffer from <linux/if_packet.h>.
const (
TP_STATUS_KERNEL = 0
TP_STATUS_USER = 0x1
TP_STATUS_COPY = 0x2
TP_STATUS_LOSING = 0x4
TP_STATUS_CSUM_NOT_READY = 0x8
TP_STATUS_VLAN_VALID = 0x10
TP_STATUS_BLK_TMO = 0x20
TP_STATUS_VLAN_TPID_VALID = 0x40
TP_STATUS_CSUM_VALID = 0x80
TP_STATUS_GSO_TCP = 0x100
)
// TpacketReq is the request for a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type TpacketReq struct {
TpBlockSize uint32
TpBlockNr uint32
TpFrameSize uint32
TpFrameNr uint32
}
// TpacketHdr is the header for a frame in a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type TpacketHdr struct {
TpStatus uint64
TpLen uint32
TpSnaplen uint32
TpMac uint16
TpNet uint16
TpSec uint32
TpUsec uint32
_ [4]uint8
}
// Tpacket2Hdr is the header for a frame in a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type Tpacket2Hdr struct {
TpStatus uint32
TpLen uint32
TpSnaplen uint32
TpMac uint16
TpNet uint16
TpSec uint32
TpNSec uint32
TpVlanTci uint16
TpVlanTpid uint16
_ [4]uint8
}
// TpacketStats is the statistics for a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type TpacketStats struct {
Packets uint32
Dropped uint32
}
// TpacketAlignment is the alignment of a frame in a packet_mmap ring buffer
// from <linux/if_packet.h>.
const (
TPACKET_ALIGNMENT = 16
)
// TPACKET_V1 is the version of a packet_mmap ring buffer from
// <linux/if_packet.h> that is implemented in gVisor.
const (
// TPACKET_V1 is the default version of PACKET_MMAP.
TPACKET_V1 = iota
// TPACKET_V2 is the version of PACKET_MMAP for tpacket2_hdr.
TPACKET_V2
)
var (
// TPACKET_HDRLEN is the length of a TpacketHdr from <linux/if_packet.h>.
TPACKET_HDRLEN = TPacketAlign(uint32((*TpacketHdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
// TPACKET2_HDRLEN is the length of a Tpacket2Hdr from <linux/if_packet.h>.
TPACKET2_HDRLEN = TPacketAlign(uint32((*Tpacket2Hdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
)
// TPacketAlign aligns a value to the alignment of a TPacket.
func TPacketAlign(x uint32) uint32 {
return (x + TPACKET_ALIGNMENT - 1) &^ (TPACKET_ALIGNMENT - 1)
}
// Socket options from socket.h.
const (
SO_DEBUG = 1
SO_REUSEADDR = 2
SO_TYPE = 3
SO_ERROR = 4
SO_DONTROUTE = 5
SO_BROADCAST = 6
SO_SNDBUF = 7
SO_RCVBUF = 8
SO_KEEPALIVE = 9
SO_OOBINLINE = 10
SO_NO_CHECK = 11
SO_PRIORITY = 12
SO_LINGER = 13
SO_BSDCOMPAT = 14
SO_REUSEPORT = 15
SO_PASSCRED = 16
SO_PEERCRED = 17
SO_RCVLOWAT = 18
SO_SNDLOWAT = 19
SO_RCVTIMEO = 20
SO_SNDTIMEO = 21
SO_BINDTODEVICE = 25
SO_ATTACH_FILTER = 26
SO_DETACH_FILTER = 27
SO_GET_FILTER = SO_ATTACH_FILTER
SO_PEERNAME = 28
SO_TIMESTAMP = 29
SO_ACCEPTCONN = 30
SO_PEERSEC = 31
SO_SNDBUFFORCE = 32
SO_RCVBUFFORCE = 33
SO_PASSSEC = 34
SO_TIMESTAMPNS = 35
SO_MARK = 36
SO_TIMESTAMPING = 37
SO_PROTOCOL = 38
SO_DOMAIN = 39
SO_RXQ_OVFL = 40
SO_WIFI_STATUS = 41
SO_PEEK_OFF = 42
SO_NOFCS = 43
SO_LOCK_FILTER = 44
SO_SELECT_ERR_QUEUE = 45
SO_BUSY_POLL = 46
SO_MAX_PACING_RATE = 47
SO_BPF_EXTENSIONS = 48
SO_INCOMING_CPU = 49
SO_ATTACH_BPF = 50
SO_ATTACH_REUSEPORT_CBPF = 51
SO_ATTACH_REUSEPORT_EBPF = 52
SO_CNX_ADVICE = 53
SO_MEMINFO = 55
SO_INCOMING_NAPI_ID = 56
SO_COOKIE = 57
SO_PEERGROUPS = 59
SO_ZEROCOPY = 60
SO_TXTIME = 61
SO_BINDTOIFINDEX = 62
SO_TIMESTAMP_OLD = 29
SO_TIMESTAMPNS_OLD = 35
SO_TIMESTAMPING_OLD = 37
SO_TIMESTAMP_NEW = 63
SO_TIMESTAMPNS_NEW = 64
SO_TIMESTAMPING_NEW = 65
SO_RCVTIMEO_NEW = 66
SO_SNDTIMEO_NEW = 67
SO_DETACH_REUSEPORT_BPF = 68
SO_PREFER_BUSY_POLL = 69
SO_BUSY_POLL_BUDGET = 70
SO_NETNS_COOKIE = 71
SO_BUF_LOCK = 72
SO_RESERVE_MEM = 73
SO_TXREHASH = 74
SO_RCVMARK = 75
SO_PASSPIDFD = 76
SO_PEERPIDFD = 77
SO_DEVMEM_LINEAR = 78
SO_DEVMEM_DMABUF = 79
SO_DEVMEM_DONTNEED = 80
SO_RCVPRIORITY = 82
)
// enum socket_state, from uapi/linux/net.h.
const (
SS_FREE = 0 // Not allocated.
SS_UNCONNECTED = 1 // Unconnected to any socket.
SS_CONNECTING = 2 // In process of connecting.
SS_CONNECTED = 3 // Connected to socket.
SS_DISCONNECTING = 4 // In process of disconnecting.
)
// TCP protocol states, from include/net/tcp_states.h.
const (
TCP_ESTABLISHED uint32 = iota + 1
TCP_SYN_SENT
TCP_SYN_RECV
TCP_FIN_WAIT1
TCP_FIN_WAIT2
TCP_TIME_WAIT
TCP_CLOSE
TCP_CLOSE_WAIT
TCP_LAST_ACK
TCP_LISTEN
TCP_CLOSING
TCP_NEW_SYN_RECV
)
// SockAddrMax is the maximum size of a struct sockaddr, from
// uapi/linux/socket.h.
const SockAddrMax = 128
// InetAddr is struct in_addr, from uapi/linux/in.h.
//
// +marshal
type InetAddr [4]byte
// SizeOfInetAddr is the size of InetAddr.
var SizeOfInetAddr = uint32((*InetAddr)(nil).SizeBytes())
// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h.
//
// +marshal
type SockAddrInet struct {
Family uint16
Port uint16
Addr InetAddr
_ [8]uint8 // pad to sizeof(struct sockaddr).
}
// Inet6MulticastRequest is struct ipv6_mreq, from uapi/linux/in6.h.
//
// +marshal
type Inet6MulticastRequest struct {
MulticastAddr Inet6Addr
InterfaceIndex int32
}
// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h.
//
// +marshal
type InetMulticastRequest struct {
MulticastAddr InetAddr
InterfaceAddr InetAddr
}
// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h.
//
// +marshal
type InetMulticastRequestWithNIC struct {
InetMulticastRequest
InterfaceIndex int32
}
// Inet6Addr is struct in6_addr, from uapi/linux/in6.h.
//
// +marshal
type Inet6Addr [16]byte
// SockAddrInet6 is struct sockaddr_in6, from uapi/linux/in6.h.
//
// +marshal
type SockAddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte
Scope_id uint32
}
// SockAddrLink is a struct sockaddr_ll, from uapi/linux/if_packet.h.
//
// +marshal
type SockAddrLink struct {
Family uint16
Protocol uint16
InterfaceIndex int32
ARPHardwareType uint16
PacketType byte
HardwareAddrLen byte
HardwareAddr [8]byte
}
// UnixPathMax is the maximum length of the path in an AF_UNIX socket.
//
// From uapi/linux/un.h.
const UnixPathMax = 108
// SockAddrUnix is struct sockaddr_un, from uapi/linux/un.h.
//
// +marshal
type SockAddrUnix struct {
Family uint16
Path [UnixPathMax]int8
}
// SockAddr represents a union of valid socket address types. This is logically
// equivalent to struct sockaddr. SockAddr ensures that a well-defined set of
// types can be used as socket addresses.
type SockAddr interface {
marshal.Marshallable
// implementsSockAddr exists purely to allow a type to indicate that they
// implement this interface. This method is a no-op and shouldn't be called.
implementsSockAddr()
}
func (s *SockAddrInet) implementsSockAddr() {}
func (s *SockAddrInet6) implementsSockAddr() {}
func (s *SockAddrLink) implementsSockAddr() {}
func (s *SockAddrUnix) implementsSockAddr() {}
func (s *SockAddrNetlink) implementsSockAddr() {}
// Linger is struct linger, from include/linux/socket.h.
//
// +marshal
type Linger struct {
OnOff int32
Linger int32
}
// SizeOfLinger is the binary size of a Linger struct.
const SizeOfLinger = 8
// TCPInfo is a collection of TCP statistics.
//
// From uapi/linux/tcp.h. Newer versions of Linux continue to add new fields to
// the end of this struct or within existing unused space, so its size grows
// over time. The current iteration is based on linux v4.17. New versions are
// always backwards compatible.
//
// +marshal
type TCPInfo struct {
// State is the state of the connection.
State uint8
// CaState is the congestion control state.
CaState uint8
// Retransmits is the number of retransmissions triggered by RTO.
Retransmits uint8
// Probes is the number of unanswered zero window probes.
Probes uint8
// BackOff indicates exponential backoff.
Backoff uint8
// Options indicates the options enabled for the connection.
Options uint8
// WindowScale is the combination of snd_wscale (first 4 bits) and
// rcv_wscale (second 4 bits)
WindowScale uint8
// DeliveryRateAppLimited is a boolean and only the first bit is
// meaningful.
DeliveryRateAppLimited uint8
// RTO is the retransmission timeout.
RTO uint32
// ATO is the acknowledgement timeout interval.
ATO uint32
// SndMss is the send maximum segment size.
SndMss uint32
// RcvMss is the receive maximum segment size.
RcvMss uint32
// Unacked is the number of packets sent but not acknowledged.
Unacked uint32
// Sacked is the number of packets which are selectively acknowledged.
Sacked uint32
// Lost is the number of packets marked as lost.
Lost uint32
// Retrans is the number of retransmitted packets.
Retrans uint32
// Fackets is not used and is always zero.
Fackets uint32
// Times.
LastDataSent uint32
LastAckSent uint32
LastDataRecv uint32
LastAckRecv uint32
// Metrics.
PMTU uint32
RcvSsthresh uint32
RTT uint32
RTTVar uint32
SndSsthresh uint32
SndCwnd uint32
Advmss uint32
Reordering uint32
// RcvRTT is the receiver round trip time.
RcvRTT uint32
// RcvSpace is the current buffer space available for receiving data.
RcvSpace uint32
// TotalRetrans is the total number of retransmits seen since the start
// of the connection.
TotalRetrans uint32
// PacingRate is the pacing rate in bytes per second.
PacingRate uint64
// MaxPacingRate is the maximum pacing rate.
MaxPacingRate uint64
// BytesAcked is RFC4898 tcpEStatsAppHCThruOctetsAcked.
BytesAcked uint64
// BytesReceived is RFC4898 tcpEStatsAppHCThruOctetsReceived.
BytesReceived uint64
// SegsOut is RFC4898 tcpEStatsPerfSegsOut.
SegsOut uint32
// SegsIn is RFC4898 tcpEStatsPerfSegsIn.
SegsIn uint32
// NotSentBytes is the amount of bytes in the write queue that are not
// yet sent.
NotSentBytes uint32
// MinRTT is the minimum round trip time seen in the connection.
MinRTT uint32
// DataSegsIn is RFC4898 tcpEStatsDataSegsIn.
DataSegsIn uint32
// DataSegsOut is RFC4898 tcpEStatsDataSegsOut.
DataSegsOut uint32
// DeliveryRate is the most recent delivery rate in bytes per second.
DeliveryRate uint64
// BusyTime is the time in microseconds busy sending data.
BusyTime uint64
// RwndLimited is the time in microseconds limited by receive window.
RwndLimited uint64
// SndBufLimited is the time in microseconds limited by send buffer.
SndBufLimited uint64
// Delivered is the total data packets delivered including retransmits.
Delivered uint32
// DeliveredCE is the total ECE marked data packets delivered including
// retransmits.
DeliveredCE uint32
// BytesSent is RFC4898 tcpEStatsPerfHCDataOctetsOut.
BytesSent uint64
// BytesRetrans is RFC4898 tcpEStatsPerfOctetsRetrans.
BytesRetrans uint64
// DSACKDups is RFC4898 tcpEStatsStackDSACKDups.
DSACKDups uint32
// ReordSeen is the number of reordering events seen since the start of
// the connection.
ReordSeen uint32
}
// SizeOfTCPInfo is the binary size of a TCPInfo struct.
var SizeOfTCPInfo = (*TCPInfo)(nil).SizeBytes()
// Control message types, from linux/socket.h.
const (
SCM_CREDENTIALS = 0x2
SCM_RIGHTS = 0x1
)
// A ControlMessageHeader is the header for a socket control message.
//
// ControlMessageHeader represents struct cmsghdr from linux/socket.h.
//
// +marshal
type ControlMessageHeader struct {
Length uint64
Level int32
Type int32
}
// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader
// struct.
var SizeOfControlMessageHeader = (*ControlMessageHeader)(nil).SizeBytes()
// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message.
//
// ControlMessageCredentials represents struct ucred from linux/socket.h.
//
// +marshal
type ControlMessageCredentials struct {
PID int32
UID uint32
GID uint32
}
// A ControlMessageIPPacketInfo is IP_PKTINFO socket control message.
//
// ControlMessageIPPacketInfo represents struct in_pktinfo from linux/in.h.
//
// +marshal
// +stateify savable
type ControlMessageIPPacketInfo struct {
NIC int32
LocalAddr InetAddr
DestinationAddr InetAddr
}
// ControlMessageIPv6PacketInfo represents struct in6_pktinfo from linux/ipv6.h.
//
// +marshal
// +stateify savable
type ControlMessageIPv6PacketInfo struct {
Addr Inet6Addr
NIC uint32
}
// SizeOfControlMessageCredentials is the binary size of a
// ControlMessageCredentials struct.
var SizeOfControlMessageCredentials = (*ControlMessageCredentials)(nil).SizeBytes()
// SizeOfControlMessageRight is the size of a single element in
// ControlMessageRights.
const SizeOfControlMessageRight = 4
// SizeOfControlMessageInq is the size of a TCP_INQ control message.
const SizeOfControlMessageInq = 4
// SizeOfControlMessageTOS is the size of an IP_TOS control message.
const SizeOfControlMessageTOS = 1
// SizeOfControlMessageTTL is the size of an IP_TTL control message.
const SizeOfControlMessageTTL = 4
// SizeOfControlMessageTClass is the size of an IPV6_TCLASS control message.
const SizeOfControlMessageTClass = 4
// SizeOfControlMessageHopLimit is the size of an IPV6_HOPLIMIT control message.
const SizeOfControlMessageHopLimit = 4
// SizeOfControlMessageIPPacketInfo is the size of an IP_PKTINFO control
// message.
const SizeOfControlMessageIPPacketInfo = 12
// SizeOfControlMessageIPv6PacketInfo is the size of a
// ControlMessageIPv6PacketInfo.
const SizeOfControlMessageIPv6PacketInfo = 20
// SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call.
// From net/scm.h.
const SCM_MAX_FD = 253
// SO_ACCEPTCON is defined as __SO_ACCEPTCON in
// include/uapi/linux/net.h, which represents a listening socket
// state. Note that this is distinct from SO_ACCEPTCONN, which is a
// socket option for querying whether a socket is in a listening
// state.
const SO_ACCEPTCON = 1 << 16
// ICMP6Filter represents struct icmp6_filter from linux/icmpv6.h.
//
// +marshal
// +stateify savable
type ICMP6Filter struct {
Filter [8]uint32
}
// Size of corresponding structs.
var (
ICMP6FilterSize = (*ICMP6Filter)(nil).SizeBytes()
SockAddrInetSize = (*SockAddrInet)(nil).SizeBytes()
SockAddrInet6Size = (*SockAddrInet6)(nil).SizeBytes()
SockAddrLinkSize = (*SockAddrLink)(nil).SizeBytes()
)

23
pkg/abi/linux/splice.go Normal file
View file

@ -0,0 +1,23 @@
// Copyright 2019 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
// Constants for splice(2), sendfile(2) and tee(2).
const (
SPLICE_F_MOVE = 1 << iota
SPLICE_F_NONBLOCK
SPLICE_F_MORE
SPLICE_F_GIFT
)

71
pkg/abi/linux/tcp.go Normal file
View file

@ -0,0 +1,71 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// Socket options from uapi/linux/tcp.h.
const (
TCP_NODELAY = 1
TCP_MAXSEG = 2
TCP_CORK = 3
TCP_KEEPIDLE = 4
TCP_KEEPINTVL = 5
TCP_KEEPCNT = 6
TCP_SYNCNT = 7
TCP_LINGER2 = 8
TCP_DEFER_ACCEPT = 9
TCP_WINDOW_CLAMP = 10
TCP_INFO = 11
TCP_QUICKACK = 12
TCP_CONGESTION = 13
TCP_MD5SIG = 14
TCP_THIN_LINEAR_TIMEOUTS = 16
TCP_THIN_DUPACK = 17
TCP_USER_TIMEOUT = 18
TCP_REPAIR = 19
TCP_REPAIR_QUEUE = 20
TCP_QUEUE_SEQ = 21
TCP_REPAIR_OPTIONS = 22
TCP_FASTOPEN = 23
TCP_TIMESTAMP = 24
TCP_NOTSENT_LOWAT = 25
TCP_CC_INFO = 26
TCP_SAVE_SYN = 27
TCP_SAVED_SYN = 28
TCP_REPAIR_WINDOW = 29
TCP_FASTOPEN_CONNECT = 30
TCP_ULP = 31
TCP_MD5SIG_EXT = 32
TCP_FASTOPEN_KEY = 33
TCP_FASTOPEN_NO_COOKIE = 34
TCP_ZEROCOPY_RECEIVE = 35
TCP_INQ = 36
TCP_TX_DELAY = 37
)
// Socket constants from include/net/tcp.h.
const (
MAX_TCP_KEEPIDLE = 32767
MAX_TCP_KEEPINTVL = 32767
MAX_TCP_KEEPCNT = 127
)
// Congestion control states from include/uapi/linux/tcp.h.
const (
TCP_CA_Open = 0
TCP_CA_Disorder = 1
TCP_CA_CWR = 2
TCP_CA_Recovery = 3
TCP_CA_Loss = 4
)

288
pkg/abi/linux/time.go Normal file
View file

@ -0,0 +1,288 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"math"
"time"
)
const (
// ClockTick is the length of time represented by a single clock tick, as
// used by times(2) and /proc/[pid]/stat.
ClockTick = time.Second / CLOCKS_PER_SEC
// CLOCKS_PER_SEC is the number of ClockTicks per second.
//
// Linux defines this to be 100 on most architectures, irrespective of
// CONFIG_HZ. Userspace obtains the value through sysconf(_SC_CLK_TCK),
// which uses the AT_CLKTCK entry in the auxiliary vector if one is
// provided, and assumes 100 otherwise (glibc:
// sysdeps/posix/sysconf.c:__sysconf() =>
// sysdeps/unix/sysv/linux/getclktck.c, elf/dl-support.c:_dl_aux_init()).
//
// Not to be confused with POSIX CLOCKS_PER_SEC, as used by clock(3); "XSI
// requires that [POSIX] CLOCKS_PER_SEC equals 1000000 independent of the
// actual resolution" - clock(3).
CLOCKS_PER_SEC = 100
)
// CPU clock types for use with clock_gettime(2) et al.
//
// The 29 most significant bits of a 32 bit clock ID are either a PID or a FD.
//
// Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
//
// Bit 2 indicates whether a cpu clock refers to a thread or a process.
const (
CPUCLOCK_PROF = 0
CPUCLOCK_VIRT = 1
CPUCLOCK_SCHED = 2
CPUCLOCK_MAX = 3
CLOCKFD = CPUCLOCK_MAX
CPUCLOCK_CLOCK_MASK = 3
CPUCLOCK_PERTHREAD_MASK = 4
)
// Clock identifiers for use with clock_gettime(2), clock_getres(2),
// clock_nanosleep(2).
const (
CLOCK_REALTIME = 0
CLOCK_MONOTONIC = 1
CLOCK_PROCESS_CPUTIME_ID = 2
CLOCK_THREAD_CPUTIME_ID = 3
CLOCK_MONOTONIC_RAW = 4
CLOCK_REALTIME_COARSE = 5
CLOCK_MONOTONIC_COARSE = 6
CLOCK_BOOTTIME = 7
CLOCK_REALTIME_ALARM = 8
CLOCK_BOOTTIME_ALARM = 9
)
// Flags for clock_nanosleep(2).
const (
TIMER_ABSTIME = 1
)
// Flags for timerfd syscalls (timerfd_create(2), timerfd_settime(2)).
const (
// TFD_CLOEXEC is a timerfd_create flag.
TFD_CLOEXEC = O_CLOEXEC
// TFD_NONBLOCK is a timerfd_create flag.
TFD_NONBLOCK = O_NONBLOCK
// TFD_TIMER_ABSTIME is a timerfd_settime flag.
TFD_TIMER_ABSTIME = 1
)
// The safe number of seconds you can represent by int64.
const maxSecInDuration = math.MaxInt64 / int64(time.Second)
// TimeT represents time_t in <time.h>. It represents time in seconds.
//
// +marshal
type TimeT int64
// NsecToTimeT translates nanoseconds to TimeT (seconds).
func NsecToTimeT(nsec int64) TimeT {
return TimeT(nsec / 1e9)
}
// Timespec represents struct timespec in <time.h>.
//
// +marshal slice:TimespecSlice
type Timespec struct {
Sec int64
Nsec int64
}
// Unix returns the second and nanosecond.
func (ts Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
// ToTime returns the Go time.Time representation.
func (ts Timespec) ToTime() time.Time {
return time.Unix(ts.Sec, ts.Nsec)
}
// ToNsec returns the nanosecond representation.
func (ts Timespec) ToNsec() int64 {
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
}
// ToNsecCapped returns the safe nanosecond representation.
func (ts Timespec) ToNsecCapped() int64 {
if ts.Sec > maxSecInDuration {
return math.MaxInt64
}
return ts.ToNsec()
}
// ToDuration returns the safe nanosecond representation as time.Duration.
func (ts Timespec) ToDuration() time.Duration {
return time.Duration(ts.ToNsecCapped())
}
// Valid returns whether the timespec contains valid values.
func (ts Timespec) Valid() bool {
return !(ts.Sec < 0 || ts.Nsec < 0 || ts.Nsec >= int64(time.Second))
}
// NsecToTimespec translates nanoseconds to Timespec.
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
// DurationToTimespec translates time.Duration to Timespec.
func DurationToTimespec(dur time.Duration) Timespec {
return NsecToTimespec(dur.Nanoseconds())
}
// SizeOfTimeval is the size of a Timeval struct in bytes.
const SizeOfTimeval = 16
// Timeval represents struct timeval in <time.h>.
//
// +marshal slice:TimevalSlice
type Timeval struct {
Sec int64
Usec int64
}
// ToNsecCapped returns the safe nanosecond representation.
func (tv Timeval) ToNsecCapped() int64 {
if tv.Sec > maxSecInDuration {
return math.MaxInt64
}
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3
}
// ToDuration returns the safe nanosecond representation as a time.Duration.
func (tv Timeval) ToDuration() time.Duration {
return time.Duration(tv.ToNsecCapped())
}
// ToTime returns the Go time.Time representation.
func (tv Timeval) ToTime() time.Time {
return time.Unix(tv.Sec, tv.Usec*1e3)
}
// NsecToTimeval translates nanosecond to Timeval.
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = nsec % 1e9 / 1e3
return
}
// DurationToTimeval translates time.Duration to Timeval.
func DurationToTimeval(dur time.Duration) Timeval {
return NsecToTimeval(dur.Nanoseconds())
}
// Itimerspec represents struct itimerspec in <time.h>.
//
// +marshal
type Itimerspec struct {
Interval Timespec
Value Timespec
}
// ItimerVal mimics the following struct in <sys/time.h>
//
// struct itimerval {
// struct timeval it_interval; /* next value */
// struct timeval it_value; /* current value */
// };
//
// +marshal
type ItimerVal struct {
Interval Timeval
Value Timeval
}
// ClockT represents type clock_t.
//
// +marshal
type ClockT int64
// ClockTFromDuration converts time.Duration to clock_t.
func ClockTFromDuration(d time.Duration) ClockT {
return ClockT(d / ClockTick)
}
// Tms represents struct tms, used by times(2).
//
// +marshal
type Tms struct {
UTime ClockT
STime ClockT
CUTime ClockT
CSTime ClockT
}
// TimerID represents type timer_t, which identifies a POSIX per-process
// interval timer.
//
// +marshal
type TimerID int32
// StatxTimestamp represents struct statx_timestamp.
//
// +marshal
type StatxTimestamp struct {
Sec int64
Nsec uint32
_ int32
}
// ToNsec returns the nanosecond representation.
func (sxts StatxTimestamp) ToNsec() int64 {
return int64(sxts.Sec)*1e9 + int64(sxts.Nsec)
}
// ToNsecCapped returns the safe nanosecond representation.
func (sxts StatxTimestamp) ToNsecCapped() int64 {
if sxts.Sec > maxSecInDuration {
return math.MaxInt64
}
return sxts.ToNsec()
}
// NsecToStatxTimestamp translates nanoseconds to StatxTimestamp.
func NsecToStatxTimestamp(nsec int64) (ts StatxTimestamp) {
return StatxTimestamp{
Sec: nsec / 1e9,
Nsec: uint32(nsec % 1e9),
}
}
// ToTime returns the Go time.Time representation.
func (sxts StatxTimestamp) ToTime() time.Time {
return time.Unix(sxts.Sec, int64(sxts.Nsec))
}
// Utime represents struct utimbuf used by utimes(2).
//
// +marshal
type Utime struct {
Actime int64
Modtime int64
}

23
pkg/abi/linux/timer.go Normal file
View file

@ -0,0 +1,23 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// itimer types for getitimer(2) and setitimer(2), from
// include/uapi/linux/time.h.
const (
ITIMER_REAL = 0
ITIMER_VIRTUAL = 1
ITIMER_PROF = 2
)

349
pkg/abi/linux/tty.go Normal file
View file

@ -0,0 +1,349 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
const (
// NumControlCharacters is the number of control characters in Termios.
NumControlCharacters = 19
// disabledChar is used to indicate that a control character is
// disabled.
disabledChar = 0
)
// Winsize is struct winsize, defined in uapi/asm-generic/termios.h.
//
// +marshal
type Winsize struct {
Row uint16
Col uint16
Xpixel uint16
Ypixel uint16
}
// Termios is struct termios, defined in uapi/asm-generic/termbits.h.
//
// +marshal
type Termios struct {
InputFlags uint32
OutputFlags uint32
ControlFlags uint32
LocalFlags uint32
LineDiscipline uint8
ControlCharacters [NumControlCharacters]uint8
}
// KernelTermios is struct ktermios/struct termios2, defined in
// uapi/asm-generic/termbits.h.
//
// +stateify savable
type KernelTermios struct {
InputFlags uint32
OutputFlags uint32
ControlFlags uint32
LocalFlags uint32
LineDiscipline uint8
ControlCharacters [NumControlCharacters]uint8
InputSpeed uint32
OutputSpeed uint32
}
// IEnabled returns whether flag is enabled in termios input flags.
func (t *KernelTermios) IEnabled(flag uint32) bool {
return t.InputFlags&flag == flag
}
// OEnabled returns whether flag is enabled in termios output flags.
func (t *KernelTermios) OEnabled(flag uint32) bool {
return t.OutputFlags&flag == flag
}
// CEnabled returns whether flag is enabled in termios control flags.
func (t *KernelTermios) CEnabled(flag uint32) bool {
return t.ControlFlags&flag == flag
}
// LEnabled returns whether flag is enabled in termios local flags.
func (t *KernelTermios) LEnabled(flag uint32) bool {
return t.LocalFlags&flag == flag
}
// ToTermios copies fields that are shared with Termios into a new Termios
// struct.
func (t *KernelTermios) ToTermios() Termios {
return Termios{
InputFlags: t.InputFlags,
OutputFlags: t.OutputFlags,
ControlFlags: t.ControlFlags,
LocalFlags: t.LocalFlags,
LineDiscipline: t.LineDiscipline,
ControlCharacters: t.ControlCharacters,
}
}
// FromTermios copies fields that are shared with Termios into this
// KernelTermios struct.
func (t *KernelTermios) FromTermios(term Termios) {
t.InputFlags = term.InputFlags
t.OutputFlags = term.OutputFlags
t.ControlFlags = term.ControlFlags
t.LocalFlags = term.LocalFlags
t.LineDiscipline = term.LineDiscipline
t.ControlCharacters = term.ControlCharacters
}
// IsTerminating returns whether c is a line terminating character.
func (t *KernelTermios) IsTerminating(cBytes []byte) bool {
// All terminating characters are 1 byte.
if len(cBytes) != 1 {
return false
}
c := cBytes[0]
// Is this the user-set EOF character?
if t.IsEOF(c) {
return true
}
switch c {
case disabledChar:
return false
case '\n', t.ControlCharacters[VEOL]:
return true
case t.ControlCharacters[VEOL2]:
return t.LEnabled(IEXTEN)
}
return false
}
// IsEOF returns whether c is the EOF character.
func (t *KernelTermios) IsEOF(c byte) bool {
return c == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar
}
// Input flags.
const (
IGNBRK = 0o000001
BRKINT = 0o000002
IGNPAR = 0o000004
PARMRK = 0o000010
INPCK = 0o000020
ISTRIP = 0o000040
INLCR = 0o000100
IGNCR = 0o000200
ICRNL = 0o000400
IUCLC = 0o001000
IXON = 0o002000
IXANY = 0o004000
IXOFF = 0o010000
IMAXBEL = 0o020000
IUTF8 = 0o040000
)
// Output flags.
const (
OPOST = 0o000001
OLCUC = 0o000002
ONLCR = 0o000004
OCRNL = 0o000010
ONOCR = 0o000020
ONLRET = 0o000040
OFILL = 0o000100
OFDEL = 0o000200
NLDLY = 0o000400
NL0 = 0o000000
NL1 = 0o000400
CRDLY = 0o003000
CR0 = 0o000000
CR1 = 0o001000
CR2 = 0o002000
CR3 = 0o003000
TABDLY = 0o014000
TAB0 = 0o000000
TAB1 = 0o004000
TAB2 = 0o010000
TAB3 = 0o014000
XTABS = 0o014000
BSDLY = 0o020000
BS0 = 0o000000
BS1 = 0o020000
VTDLY = 0o040000
VT0 = 0o000000
VT1 = 0o040000
FFDLY = 0o100000
FF0 = 0o000000
FF1 = 0o100000
)
// Control flags.
const (
CBAUD = 0o010017
B0 = 0o000000
B50 = 0o000001
B75 = 0o000002
B110 = 0o000003
B134 = 0o000004
B150 = 0o000005
B200 = 0o000006
B300 = 0o000007
B600 = 0o000010
B1200 = 0o000011
B1800 = 0o000012
B2400 = 0o000013
B4800 = 0o000014
B9600 = 0o000015
B19200 = 0o000016
B38400 = 0o000017
EXTA = B19200
EXTB = B38400
CSIZE = 0o000060
CS5 = 0o000000
CS6 = 0o000020
CS7 = 0o000040
CS8 = 0o000060
CSTOPB = 0o000100
CREAD = 0o000200
PARENB = 0o000400
PARODD = 0o001000
HUPCL = 0o002000
CLOCAL = 0o004000
CBAUDEX = 0o010000
BOTHER = 0o010000
B57600 = 0o010001
B115200 = 0o010002
B230400 = 0o010003
B460800 = 0o010004
B500000 = 0o010005
B576000 = 0o010006
B921600 = 0o010007
B1000000 = 0o010010
B1152000 = 0o010011
B1500000 = 0o010012
B2000000 = 0o010013
B2500000 = 0o010014
B3000000 = 0o010015
B3500000 = 0o010016
B4000000 = 0o010017
CIBAUD = 0o02003600000
CMSPAR = 0o10000000000
CRTSCTS = 0o20000000000
// IBSHIFT is the shift from CBAUD to CIBAUD.
IBSHIFT = 16
)
// Local flags.
const (
ISIG = 0o000001
ICANON = 0o000002
XCASE = 0o000004
ECHO = 0o000010
ECHOE = 0o000020
ECHOK = 0o000040
ECHONL = 0o000100
NOFLSH = 0o000200
TOSTOP = 0o000400
ECHOCTL = 0o001000
ECHOPRT = 0o002000
ECHOKE = 0o004000
FLUSHO = 0o010000
PENDIN = 0o040000
IEXTEN = 0o100000
EXTPROC = 0o200000
)
// Control Character indices.
const (
VINTR = 0
VQUIT = 1
VERASE = 2
VKILL = 3
VEOF = 4
VTIME = 5
VMIN = 6
VSWTC = 7
VSTART = 8
VSTOP = 9
VSUSP = 10
VEOL = 11
VREPRINT = 12
VDISCARD = 13
VWERASE = 14
VLNEXT = 15
VEOL2 = 16
)
// ControlCharacter returns the termios-style control character for the passed
// character.
//
// e.g., for Ctrl-C, i.e., ^C, call ControlCharacter('C').
//
// Standard control characters are ASCII bytes 0 through 31.
func ControlCharacter(c byte) uint8 {
// A is 1, B is 2, etc.
return uint8(c - 'A' + 1)
}
// DefaultControlCharacters is the default set of Termios control characters.
var DefaultControlCharacters = [NumControlCharacters]uint8{
ControlCharacter('C'), // VINTR = ^C
ControlCharacter('\\'), // VQUIT = ^\
'\x7f', // VERASE = DEL
ControlCharacter('U'), // VKILL = ^U
ControlCharacter('D'), // VEOF = ^D
0, // VTIME
1, // VMIN
0, // VSWTC
ControlCharacter('Q'), // VSTART = ^Q
ControlCharacter('S'), // VSTOP = ^S
ControlCharacter('Z'), // VSUSP = ^Z
0, // VEOL
ControlCharacter('R'), // VREPRINT = ^R
ControlCharacter('O'), // VDISCARD = ^O
ControlCharacter('W'), // VWERASE = ^W
ControlCharacter('V'), // VLNEXT = ^V
0, // VEOL2
}
// MasterTermios is the terminal configuration of the master end of a Unix98
// pseudoterminal.
var MasterTermios = KernelTermios{
ControlFlags: B38400 | CS8 | CREAD,
ControlCharacters: DefaultControlCharacters,
InputSpeed: 38400,
OutputSpeed: 38400,
}
// DefaultReplicaTermios is the default terminal configuration of the replica
// end of a Unix98 pseudoterminal.
var DefaultReplicaTermios = KernelTermios{
InputFlags: ICRNL | IXON,
OutputFlags: OPOST | ONLCR,
ControlFlags: B38400 | CS8 | CREAD,
LocalFlags: ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
ControlCharacters: DefaultControlCharacters,
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.
}

18
pkg/abi/linux/uio.go Normal file
View file

@ -0,0 +1,18 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
// UIO_MAXIOV is the maximum number of struct iovecs in a struct iovec array.
const UIO_MAXIOV = 1024

51
pkg/abi/linux/utsname.go Normal file
View file

@ -0,0 +1,51 @@
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"bytes"
"fmt"
)
const (
// UTSLen is the maximum length of strings contained in fields of
// UtsName.
UTSLen = 64
)
// UtsName represents struct utsname, the struct returned by uname(2).
//
// +marshal
type UtsName struct {
Sysname [UTSLen + 1]byte
Nodename [UTSLen + 1]byte
Release [UTSLen + 1]byte
Version [UTSLen + 1]byte
Machine [UTSLen + 1]byte
Domainname [UTSLen + 1]byte
}
// utsNameString converts a UtsName entry to a string without NULs.
func utsNameString(s [UTSLen + 1]byte) string {
// The NUL bytes will remain even in a cast to string. We must
// explicitly strip them.
return string(bytes.TrimRight(s[:], "\x00"))
}
func (u UtsName) String() string {
return fmt.Sprintf("{Sysname: %s, Nodename: %s, Release: %s, Version: %s, Machine: %s, Domainname: %s}",
utsNameString(u.Sysname), utsNameString(u.Nodename), utsNameString(u.Release),
utsNameString(u.Version), utsNameString(u.Machine), utsNameString(u.Domainname))
}

215
pkg/abi/linux/vfio.go Normal file
View file

@ -0,0 +1,215 @@
// Copyright 2024 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.
// The package implements VFIOuserspace driver interface.
package linux
// For IOCTLs requests from include/uapi/linux/vfio.h.
const (
VFIO_TYPE = ';'
VFIO_BASE = 100
// VFIO extensions.
VFIO_TYPE1_IOMMU = 1
VFIO_SPAPR_TCE_IOMMU = 2
VFIO_TYPE1v2_IOMMU = 3
)
// VFIO device info flags.
const (
// Device supports reset.
VFIO_DEVICE_FLAGS_RESET = 1 << iota
// VFIO-pci device.
VFIO_DEVICE_FLAGS_PCI
// VFIO-platform device.
VFIO_DEVICE_FLAGS_PLATFORM
// VFIO-amba device.
VFIO_DEVICE_FLAGS_AMBA
// VFIO-ccw device.
VFIO_DEVICE_FLAGS_CCW
// VFIO-ap device.
VFIO_DEVICE_FLAGS_AP
// VFIO-fsl-mc device.
VFIO_DEVICE_FLAGS_FSL_MC
// Info supports caps.
VFIO_DEVICE_FLAGS_CAPS
// VFIO-cdx device.
VFIO_DEVICE_FLAGS_CDX
)
// VFIO region info flags.
const (
// Region supports read.
VFIO_REGION_INFO_FLAG_READ = 1 << iota
// Region supports write.
VFIO_REGION_INFO_FLAG_WRITE
// Region supports mmap.
VFIO_REGION_INFO_FLAG_MMAP
// Info supports caps.
VFIO_REGION_INFO_FLAG_CAPS
)
// VFIOIrqInfo flags.
const (
VFIO_IRQ_INFO_EVENTFD = 1 << iota
VFIO_IRQ_INFO_MASKABLE
VFIO_IRQ_INFO_AUTOMASKED
VFIO_IRQ_INFO_NORESIZE
)
// VFIOIrqSet flags.
const (
VFIO_IRQ_SET_DATA_NONE = 1 << iota
VFIO_IRQ_SET_DATA_BOOL
VFIO_IRQ_SET_DATA_EVENTFD
VFIO_IRQ_SET_ACTION_MASK
VFIO_IRQ_SET_ACTION_UNMASK
VFIO_IRQ_SET_ACTION_TRIGGER
VFIO_IRQ_SET_DATA_TYPE_MASK = VFIO_IRQ_SET_DATA_NONE |
VFIO_IRQ_SET_DATA_BOOL |
VFIO_IRQ_SET_DATA_EVENTFD
VFIO_IRQ_SET_ACTION_TYPE_MASK = VFIO_IRQ_SET_ACTION_MASK |
VFIO_IRQ_SET_ACTION_UNMASK |
VFIO_IRQ_SET_ACTION_TRIGGER
)
// VFIOIrqSet index.
const (
VFIO_PCI_INTX_IRQ_INDEX = iota
VFIO_PCI_MSI_IRQ_INDEX
VFIO_PCI_MSIX_IRQ_INDEX
VFIO_PCI_ERR_IRQ_INDEX
VFIO_PCI_REQ_IRQ_INDEX
VFIO_PCI_NUM_IRQS
)
// VFIOIommuType1DmaMap flags.
const (
// Readable from device.
VFIO_DMA_MAP_FLAG_READ = 1 << iota
// Writable from device.
VFIO_DMA_MAP_FLAG_WRITE
// Update the device's virtual address.
VFIO_DMA_MAP_FLAG_VADDR
)
const (
VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP = 1
)
// IOCTLs for VFIO file descriptor from include/uapi/linux/vfio.h.
var (
VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1)
VFIO_SET_IOMMU = IO(VFIO_TYPE, VFIO_BASE+2)
VFIO_GROUP_SET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+4)
VFIO_GROUP_UNSET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+5)
VFIO_GROUP_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6)
VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7)
VFIO_DEVICE_GET_REGION_INFO = IO(VFIO_TYPE, VFIO_BASE+8)
VFIO_DEVICE_GET_IRQ_INFO = IO(VFIO_TYPE, VFIO_BASE+9)
VFIO_DEVICE_SET_IRQS = IO(VFIO_TYPE, VFIO_BASE+10)
VFIO_DEVICE_RESET = IO(VFIO_TYPE, VFIO_BASE+11)
VFIO_IOMMU_MAP_DMA = IO(VFIO_TYPE, VFIO_BASE+13)
VFIO_IOMMU_UNMAP_DMA = IO(VFIO_TYPE, VFIO_BASE+14)
)
// VFIODeviceInfo is analogous to vfio_device_info
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIODeviceInfo struct {
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
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIORegionInfo struct {
Argsz uint32
Flags uint32
Index uint32
// Offset within info struct of first cap.
capOffset uint32
// Region size in bytes.
Size uint64
// Region offset from start of device fd.
Offset uint64
}
// VFIOIrqInfo is analogous to vfio_irq_info
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIOIrqInfo struct {
Argsz uint32
Flags uint32
Index uint32
Count uint32
}
// VFIOIrqSet is analogous to vfio_irq_set
// from include/uapi/linux/vfio.h.
// The last field `data` from vfio_irq_set is omitted which is an
// flexible array member. It will be handled separately.
//
// +marshal
type VFIOIrqSet struct {
Argsz uint32
Flags uint32
Index uint32
Start uint32
Count uint32
}
// VFIOIommuType1DmaMap is analogous to vfio_iommu_type1_dma_map
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIOIommuType1DmaMap struct {
Argsz uint32
Flags uint32
// Process virtual address.
Vaddr uint64
// IO virtual address.
IOVa uint64
// Size of mapping in bytes.
Size uint64
}
// VFIOIommuType1DmaUnmap is analogous to vfio_iommu_type1_dma_unmap
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIOIommuType1DmaUnmap struct {
Argsz uint32
Flags uint32
// IO virtual address.
IOVa uint64
// Size of mapping in bytes.
Size uint64
// The `data` field from vfio_iommu_type1_dma_unmap is omitted. The
// field is a flexible array member, and is needed only if the flag
// VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP is enabled.
}

View file

@ -0,0 +1,22 @@
// Copyright 2024 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 "unsafe"
// Size returns the number of bytes for a VFIOIrqSet object.
func (vfioIrqSet VFIOIrqSet) Size() uint64 {
return uint64(unsafe.Sizeof(vfioIrqSet))
}

161
pkg/abi/linux/wait.go Normal file
View file

@ -0,0 +1,161 @@
// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"fmt"
)
// Options for waitpid(2), wait4(2), and/or waitid(2), from
// include/uapi/linux/wait.h.
const (
WNOHANG = 0x00000001
WUNTRACED = 0x00000002
WSTOPPED = WUNTRACED
WEXITED = 0x00000004
WCONTINUED = 0x00000008
WNOWAIT = 0x01000000
WNOTHREAD = 0x20000000
WALL = 0x40000000
WCLONE = 0x80000000
)
// ID types for waitid(2), from include/uapi/linux/wait.h.
const (
P_ALL = 0x0
P_PID = 0x1
P_PGID = 0x2
)
// WaitStatus represents a thread status, as returned by the wait* family of
// syscalls.
type WaitStatus uint32
// WaitStatusExit returns a WaitStatus representing the given exit status.
func WaitStatusExit(status int32) WaitStatus {
return WaitStatus(uint32(status) << 8)
}
// WaitStatusTerminationSignal returns a WaitStatus representing termination by
// the given signal.
func WaitStatusTerminationSignal(sig Signal) WaitStatus {
return WaitStatus(uint32(sig))
}
// WaitStatusStopped returns a WaitStatus representing stoppage by the given
// signal or ptrace trap code.
func WaitStatusStopped(code uint32) WaitStatus {
return WaitStatus(code<<8 | 0x7f)
}
// WaitStatusContinued returns a WaitStatus representing continuation by
// SIGCONT.
func WaitStatusContinued() WaitStatus {
return WaitStatus(0xffff)
}
// WithCoreDump returns a copy of ws that indicates that a core dump was
// generated.
//
// Preconditions: ws.Signaled().
func (ws WaitStatus) WithCoreDump() WaitStatus {
return ws | 0x80
}
// Exited returns true if ws represents an exit status, consistent with
// WIFEXITED.
func (ws WaitStatus) Exited() bool {
return ws&0x7f == 0
}
// Signaled returns true if ws represents a termination by signal, consistent
// with WIFSIGNALED.
func (ws WaitStatus) Signaled() bool {
// ws&0x7f != 0 (exited) and ws&0x7f != 0x7f (stopped or continued)
return ((ws&0x7f)+1)>>1 != 0
}
// CoreDumped returns true if ws indicates that a core dump was produced,
// consistent with WCOREDUMP.
//
// Preconditions: ws.Signaled().
func (ws WaitStatus) CoreDumped() bool {
return ws&0x80 != 0
}
// Stopped returns true if ws represents a stoppage, consistent with
// WIFSTOPPED.
func (ws WaitStatus) Stopped() bool {
return ws&0xff == 0x7f
}
// Continued returns true if ws represents a continuation by SIGCONT,
// consistent with WIFCONTINUED.
func (ws WaitStatus) Continued() bool {
return ws == 0xffff
}
// ExitStatus returns the lower 8 bits of the exit status represented by ws,
// consistent with WEXITSTATUS.
//
// Preconditions: ws.Exited().
func (ws WaitStatus) ExitStatus() uint32 {
return uint32((ws & 0xff00) >> 8)
}
// TerminationSignal returns the termination signal represented by ws,
// consistent with WTERMSIG.
//
// Preconditions: ws.Signaled().
func (ws WaitStatus) TerminationSignal() Signal {
return Signal(ws & 0x7f)
}
// StopSignal returns the stop signal represented by ws, consistent with
// WSTOPSIG.
//
// Preconditions: ws.Stopped().
func (ws WaitStatus) StopSignal() Signal {
return Signal((ws & 0xff00) >> 8)
}
// PtraceEvent returns the PTRACE_EVENT_* field in ws.
//
// Preconditions: ws.Stopped().
func (ws WaitStatus) PtraceEvent() uint32 {
return uint32(ws >> 16)
}
// String implements fmt.Stringer.String.
func (ws WaitStatus) String() string {
switch {
case ws.Exited():
return fmt.Sprintf("exit status %d", ws.ExitStatus())
case ws.Signaled():
if ws.CoreDumped() {
return fmt.Sprintf("killed by signal %d (core dumped)", ws.TerminationSignal())
}
return fmt.Sprintf("killed by signal %d", ws.TerminationSignal())
case ws.Stopped():
if ev := ws.PtraceEvent(); ev != 0 {
return fmt.Sprintf("stopped by signal %d (PTRACE_EVENT %d)", ws.StopSignal(), ev)
}
return fmt.Sprintf("stopped by signal %d", ws.StopSignal())
case ws.Continued():
return "continued"
default:
return fmt.Sprintf("unknown status %#x", uint32(ws))
}
}

39
pkg/abi/linux/xattr.go Normal file
View file

@ -0,0 +1,39 @@
// Copyright 2019 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
// Constants for extended attributes.
const (
XATTR_NAME_MAX = 255
XATTR_SIZE_MAX = 65536
XATTR_LIST_MAX = 65536
XATTR_CREATE = 1
XATTR_REPLACE = 2
XATTR_SECURITY_PREFIX = "security."
XATTR_SECURITY_PREFIX_LEN = len(XATTR_SECURITY_PREFIX)
XATTR_SECURITY_CAPABILITY = XATTR_SECURITY_PREFIX + "capability"
XATTR_SYSTEM_PREFIX = "system."
XATTR_SYSTEM_PREFIX_LEN = len(XATTR_SYSTEM_PREFIX)
XATTR_TRUSTED_PREFIX = "trusted."
XATTR_TRUSTED_PREFIX_LEN = len(XATTR_TRUSTED_PREFIX)
XATTR_USER_PREFIX = "user."
XATTR_USER_PREFIX_LEN = len(XATTR_USER_PREFIX)
)