diff options
Diffstat (limited to 'pkg/abi/linux')
35 files changed, 3147 insertions, 0 deletions
diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD new file mode 100644 index 000000000..a428e61a3 --- /dev/null +++ b/pkg/abi/linux/BUILD @@ -0,0 +1,69 @@ +# Package linux contains the constants and types needed to inferface with a +# Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix +# when the host OS may not be Linux. + +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_stateify") + +go_stateify( + name = "linux_state", + srcs = [ + "binder.go", + "bpf.go", + "time.go", + "tty.go", + ], + out = "linux_state.go", + package = "linux", +) + +go_library( + name = "linux", + srcs = [ + "aio.go", + "ashmem.go", + "binder.go", + "bpf.go", + "capability.go", + "dev.go", + "elf.go", + "errors.go", + "exec.go", + "file.go", + "fs.go", + "futex.go", + "inotify.go", + "ioctl.go", + "ip.go", + "ipc.go", + "limits.go", + "linux.go", + "linux_state.go", + "mm.go", + "netdevice.go", + "netlink.go", + "netlink_route.go", + "poll.go", + "prctl.go", + "rusage.go", + "sched.go", + "seccomp.go", + "sem.go", + "signal.go", + "socket.go", + "time.go", + "tty.go", + "uio.go", + "utsname.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/abi/linux", + visibility = ["//visibility:public"], + deps = [ + "//pkg/abi", + "//pkg/binary", + "//pkg/bits", + "//pkg/state", + ], +) diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go new file mode 100644 index 000000000..9c39ca2ef --- /dev/null +++ b/pkg/abi/linux/aio.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 ( + // AIORingSize is sizeof(struct aio_ring). + AIORingSize = 32 +) diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go new file mode 100644 index 000000000..7fbfd2e68 --- /dev/null +++ b/pkg/abi/linux/ashmem.go @@ -0,0 +1,29 @@ +// Copyright 2018 Google Inc. +// +// 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 ashmem in pin-related ioctls. +const ( + AshmemNotPurged = 0 + AshmemWasPurged = 1 + AshmemIsUnpinned = 0 + AshmemIsPinned = 1 +) + +// AshmemPin structure is used for pin-related ioctls. +type AshmemPin struct { + Offset uint32 + Len uint32 +} diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go new file mode 100644 index 000000000..b228898f9 --- /dev/null +++ b/pkg/abi/linux/binder.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 + +// BinderVersion structure is used for BINDER_VERSION ioctl. +type BinderVersion struct { + ProtocolVersion int32 +} diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go new file mode 100644 index 000000000..f597ef4f5 --- /dev/null +++ b/pkg/abi/linux/bpf.go @@ -0,0 +1,32 @@ +// Copyright 2018 Google Inc. +// +// 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. +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 +} diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go new file mode 100644 index 000000000..1a1bd0ce3 --- /dev/null +++ b/pkg/abi/linux/capability.go @@ -0,0 +1,104 @@ +// Copyright 2018 Google Inc. +// +// 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 + +// 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_BROAD_CAST = 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) + + // MaxCapability is the highest-numbered capability. + MaxCapability = Capability(36) // CAP_BLOCK_SUSPEND as of 3.11 +) + +// Ok returns true if cp is a supported capability. +func (cp Capability) Ok() bool { + return cp >= 0 && cp <= MaxCapability +} + +// 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 +) + +// CapUserHeader is equivalent to Linux's cap_user_header_t. +type CapUserHeader struct { + Version uint32 + Pid int32 +} + +// CapUserData is equivalent to Linux's cap_user_data_t. +type CapUserData struct { + Effective uint32 + Permitted uint32 + Inheritable uint32 +} diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go new file mode 100644 index 000000000..d3b63063f --- /dev/null +++ b/pkg/abi/linux/dev.go @@ -0,0 +1,48 @@ +// Copyright 2018 Google Inc. +// +// 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) +} + +// Character device IDs. +// +// See Documentations/devices.txt and uapi/linux/major.h. +const ( + // TTYAUX_MAJOR is the major device number for alternate TTY devices. + TTYAUX_MAJOR = 5 + + // UNIX98_PTY_MASTER_MAJOR is the initial major device number for + // Unix98 PTY masters. + UNIX98_PTY_MASTER_MAJOR = 128 + + // UNIX98_PTY_SLAVE_MAJOR is the initial major device number for + // Unix98 PTY slaves. + UNIX98_PTY_SLAVE_MAJOR = 136 +) + +// Minor device numbers for TTYAUX_MAJOR. +const ( + // PTMX_MINOR is the minor device number for /dev/ptmx. + PTMX_MINOR = 2 +) diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go new file mode 100644 index 000000000..76c13b677 --- /dev/null +++ b/pkg/abi/linux/elf.go @@ -0,0 +1,91 @@ +// Copyright 2018 Google Inc. +// +// 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 +) diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go new file mode 100644 index 000000000..b5ddb2b2f --- /dev/null +++ b/pkg/abi/linux/errors.go @@ -0,0 +1,172 @@ +// Copyright 2018 Google Inc. +// +// 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 + +// Errno represents a Linux errno value. +type Errno struct { + number int + name string +} + +// Number returns the errno number. +func (e *Errno) Number() int { + return e.number +} + +// Error implements error.Error. +func (e *Errno) Error() string { + return e.name +} + +// Errno values from include/uapi/asm-generic/errno-base.h. +var ( + EPERM = &Errno{1, "operation not permitted"} + ENOENT = &Errno{2, "no such file or directory"} + ESRCH = &Errno{3, "no such process"} + EINTR = &Errno{4, "interrupted system call"} + EIO = &Errno{5, "I/O error"} + ENXIO = &Errno{6, "no such device or address"} + E2BIG = &Errno{7, "argument list too long"} + ENOEXEC = &Errno{8, "exec format error"} + EBADF = &Errno{9, "bad file number"} + ECHILD = &Errno{10, "no child processes"} + EAGAIN = &Errno{11, "try again"} + ENOMEM = &Errno{12, "out of memory"} + EACCES = &Errno{13, "permission denied"} + EFAULT = &Errno{14, "bad address"} + ENOTBLK = &Errno{15, "block device required"} + EBUSY = &Errno{16, "device or resource busy"} + EEXIST = &Errno{17, "file exists"} + EXDEV = &Errno{18, "cross-device link"} + ENODEV = &Errno{19, "no such device"} + ENOTDIR = &Errno{20, "not a directory"} + EISDIR = &Errno{21, "is a directory"} + EINVAL = &Errno{22, "invalid argument"} + ENFILE = &Errno{23, "file table overflow"} + EMFILE = &Errno{24, "too many open files"} + ENOTTY = &Errno{25, "not a typewriter"} + ETXTBSY = &Errno{26, "text file busy"} + EFBIG = &Errno{27, "file too large"} + ENOSPC = &Errno{28, "no space left on device"} + ESPIPE = &Errno{29, "illegal seek"} + EROFS = &Errno{30, "read-only file system"} + EMLINK = &Errno{31, "too many links"} + EPIPE = &Errno{32, "broken pipe"} + EDOM = &Errno{33, "math argument out of domain of func"} + ERANGE = &Errno{34, "math result not representable"} +) + +// Errno values from include/uapi/asm-generic/errno.h. +var ( + EDEADLK = &Errno{35, "resource deadlock would occur"} + ENAMETOOLONG = &Errno{36, "file name too long"} + ENOLCK = &Errno{37, "no record locks available"} + ENOSYS = &Errno{38, "invalid system call number"} + ENOTEMPTY = &Errno{39, "directory not empty"} + ELOOP = &Errno{40, "too many symbolic links encountered"} + EWOULDBLOCK = &Errno{EAGAIN.number, "operation would block"} + ENOMSG = &Errno{42, "no message of desired type"} + EIDRM = &Errno{43, "identifier removed"} + ECHRNG = &Errno{44, "channel number out of range"} + EL2NSYNC = &Errno{45, "level 2 not synchronized"} + EL3HLT = &Errno{46, "level 3 halted"} + EL3RST = &Errno{47, "level 3 reset"} + ELNRNG = &Errno{48, "link number out of range"} + EUNATCH = &Errno{49, "protocol driver not attached"} + ENOCSI = &Errno{50, "no CSI structure available"} + EL2HLT = &Errno{51, "level 2 halted"} + EBADE = &Errno{52, "invalid exchange"} + EBADR = &Errno{53, "invalid request descriptor"} + EXFULL = &Errno{54, "exchange full"} + ENOANO = &Errno{55, "no anode"} + EBADRQC = &Errno{56, "invalid request code"} + EBADSLT = &Errno{57, "invalid slot"} + EDEADLOCK = EDEADLK + EBFONT = &Errno{59, "bad font file format"} + ENOSTR = &Errno{60, "device not a stream"} + ENODATA = &Errno{61, "no data available"} + ETIME = &Errno{62, "timer expired"} + ENOSR = &Errno{63, "out of streams resources"} + ENONET = &Errno{64, "machine is not on the network"} + ENOPKG = &Errno{65, "package not installed"} + EREMOTE = &Errno{66, "object is remote"} + ENOLINK = &Errno{67, "link has been severed"} + EADV = &Errno{68, "advertise error"} + ESRMNT = &Errno{69, "srmount error"} + ECOMM = &Errno{70, "communication error on send"} + EPROTO = &Errno{71, "protocol error"} + EMULTIHOP = &Errno{72, "multihop attempted"} + EDOTDOT = &Errno{73, "RFS specific error"} + EBADMSG = &Errno{74, "not a data message"} + EOVERFLOW = &Errno{75, "value too large for defined data type"} + ENOTUNIQ = &Errno{76, "name not unique on network"} + EBADFD = &Errno{77, "file descriptor in bad state"} + EREMCHG = &Errno{78, "remote address changed"} + ELIBACC = &Errno{79, "can not access a needed shared library"} + ELIBBAD = &Errno{80, "accessing a corrupted shared library"} + ELIBSCN = &Errno{81, ".lib section in a.out corrupted"} + ELIBMAX = &Errno{82, "attempting to link in too many shared libraries"} + ELIBEXEC = &Errno{83, "cannot exec a shared library directly"} + EILSEQ = &Errno{84, "illegal byte sequence"} + ERESTART = &Errno{85, "interrupted system call should be restarted"} + ESTRPIPE = &Errno{86, "streams pipe error"} + EUSERS = &Errno{87, "too many users"} + ENOTSOCK = &Errno{88, "socket operation on non-socket"} + EDESTADDRREQ = &Errno{89, "destination address required"} + EMSGSIZE = &Errno{90, "message too long"} + EPROTOTYPE = &Errno{91, "protocol wrong type for socket"} + ENOPROTOOPT = &Errno{92, "protocol not available"} + EPROTONOSUPPORT = &Errno{93, "protocol not supported"} + ESOCKTNOSUPPORT = &Errno{94, "socket type not supported"} + EOPNOTSUPP = &Errno{95, "operation not supported on transport endpoint"} + EPFNOSUPPORT = &Errno{96, "protocol family not supported"} + EAFNOSUPPORT = &Errno{97, "address family not supported by protocol"} + EADDRINUSE = &Errno{98, "address already in use"} + EADDRNOTAVAIL = &Errno{99, "cannot assign requested address"} + ENETDOWN = &Errno{100, "network is down"} + ENETUNREACH = &Errno{101, "network is unreachable"} + ENETRESET = &Errno{102, "network dropped connection because of reset"} + ECONNABORTED = &Errno{103, "software caused connection abort"} + ECONNRESET = &Errno{104, "connection reset by peer"} + ENOBUFS = &Errno{105, "no buffer space available"} + EISCONN = &Errno{106, "transport endpoint is already connected"} + ENOTCONN = &Errno{107, "transport endpoint is not connected"} + ESHUTDOWN = &Errno{108, "cannot send after transport endpoint shutdown"} + ETOOMANYREFS = &Errno{109, "too many references: cannot splice"} + ETIMEDOUT = &Errno{110, "connection timed out"} + ECONNREFUSED = &Errno{111, "connection refused"} + EHOSTDOWN = &Errno{112, "host is down"} + EHOSTUNREACH = &Errno{113, "no route to host"} + EALREADY = &Errno{114, "operation already in progress"} + EINPROGRESS = &Errno{115, "operation now in progress"} + ESTALE = &Errno{116, "stale file handle"} + EUCLEAN = &Errno{117, "structure needs cleaning"} + ENOTNAM = &Errno{118, "not a XENIX named type file"} + ENAVAIL = &Errno{119, "no XENIX semaphores available"} + EISNAM = &Errno{120, "is a named type file"} + EREMOTEIO = &Errno{121, "remote I/O error"} + EDQUOT = &Errno{122, "quota exceeded"} + ENOMEDIUM = &Errno{123, "no medium found"} + EMEDIUMTYPE = &Errno{124, "wrong medium type"} + ECANCELED = &Errno{125, "operation Canceled"} + ENOKEY = &Errno{126, "required key not available"} + EKEYEXPIRED = &Errno{127, "key has expired"} + EKEYREVOKED = &Errno{128, "key has been revoked"} + EKEYREJECTED = &Errno{129, "key was rejected by service"} + EOWNERDEAD = &Errno{130, "owner died"} + ENOTRECOVERABLE = &Errno{131, "state not recoverable"} + ERFKILL = &Errno{132, "operation not possible due to RF-kill"} + EHWPOISON = &Errno{133, "memory page has hardware error"} +) diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go new file mode 100644 index 000000000..4d81eca54 --- /dev/null +++ b/pkg/abi/linux/exec.go @@ -0,0 +1,18 @@ +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go new file mode 100644 index 000000000..44672647b --- /dev/null +++ b/pkg/abi/linux/file.go @@ -0,0 +1,232 @@ +// Copyright 2018 Google Inc. +// +// 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" + + "gvisor.googlesource.com/gvisor/pkg/abi" +) + +// Constants for open(2). +const ( + O_NONBLOCK = 00004000 + O_CLOEXEC = 02000000 + O_PATH = 010000000 +) + +// 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 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 ( + FileTypeMask = 0170000 + ModeSocket = 0140000 + ModeSymlink = 0120000 + ModeRegular = 0100000 + ModeBlockDevice = 060000 + ModeDirectory = 040000 + ModeCharacterDevice = 020000 + ModeNamedPipe = 010000 + + ModeSetUID = 04000 + ModeSetGID = 02000 + ModeSticky = 01000 + + ModeUserAll = 0700 + ModeUserRead = 0400 + ModeUserWrite = 0200 + ModeUserExec = 0100 + ModeGroupAll = 0070 + ModeGroupRead = 0040 + ModeGroupWrite = 0020 + ModeGroupExec = 0010 + ModeOtherAll = 0007 + ModeOtherRead = 0004 + ModeOtherWrite = 0002 + ModeOtherExec = 0001 + PermissionsMask = 0777 +) + +// Stat represents struct stat. +type Stat struct { + Dev uint64 + Ino uint64 + Nlink uint64 + Mode uint32 + UID uint32 + GID uint32 + X_pad0 int32 + Rdev uint64 + Size int64 + Blksize int64 + Blocks int64 + ATime Timespec + MTime Timespec + CTime Timespec + X_unused [3]int64 +} + +// FileMode represents a mode_t. +type FileMode uint + +// 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) +} + +// 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, "|") +} + +var modeExtraBits = abi.FlagSet{ + { + Flag: ModeSetUID, + Name: "S_ISUID", + }, + { + Flag: ModeSetGID, + Name: "S_ISGID", + }, + { + Flag: ModeSticky, + Name: "S_ISVTX", + }, +} + +var fileType = abi.ValueSet{ + { + Value: ModeSocket, + Name: "S_IFSOCK", + }, + { + Value: ModeSymlink, + Name: "S_IFLINK", + }, + { + Value: ModeRegular, + Name: "S_IFREG", + }, + { + Value: ModeBlockDevice, + Name: "S_IFBLK", + }, + { + Value: ModeDirectory, + Name: "S_IFDIR", + }, + { + Value: ModeCharacterDevice, + Name: "S_IFCHR", + }, + { + Value: ModeNamedPipe, + Name: "S_IFIFO", + }, +} diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go new file mode 100644 index 000000000..00b239351 --- /dev/null +++ b/pkg/abi/linux/fs.go @@ -0,0 +1,69 @@ +// Copyright 2018 Google Inc. +// +// 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 + DEVPTS_SUPER_MAGIC = 0x00001cd1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 + PIPEFS_MAGIC = 0x50495045 + RAMFS_MAGIC = 0x09041934 + SOCKFS_MAGIC = 0x534F434B + TMPFS_MAGIC = 0x01021994 + V9FS_MAGIC = 0x01021997 +) + +// Statfs is struct statfs, from uapi/asm-generic/statfs.h. +type Statfs struct { + // Type is one of the filesystem magic values, defined above. + Type uint64 + + // BlockSize is the data block size. + BlockSize int64 + + // Blocks is the number of data blocks in use. + Blocks uint64 + + // BlocksFree is the number of free blocks. + BlocksFree uint64 + + // BlocksAvailable is the number of blocks free for use by + // unprivileged users. + 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 +} diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go new file mode 100644 index 000000000..f63f5200c --- /dev/null +++ b/pkg/abi/linux/futex.go @@ -0,0 +1,56 @@ +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go new file mode 100644 index 000000000..072a2d146 --- /dev/null +++ b/pkg/abi/linux/inotify.go @@ -0,0 +1,97 @@ +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go new file mode 100644 index 000000000..35cefbdfc --- /dev/null +++ b/pkg/abi/linux/ioctl.go @@ -0,0 +1,57 @@ +// Copyright 2018 Google Inc. +// +// 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 + TIOCINQ = 0x0000541b + TIOCOUTQ = 0x00005411 + FIONREAD = TIOCINQ + FIONBIO = 0x00005421 + TIOCGPTN = 0x80045430 + TIOCSPTLCK = 0x40045431 + FIONCLEX = 0x00005450 + FIOCLEX = 0x00005451 +) + +// ioctl(2) requests provided by uapi/linux/android/binder.h +const ( + BinderWriteReadIoctl = 0xc0306201 + BinderSetIdleTimeoutIoctl = 0x40086203 + BinderSetMaxThreadsIoctl = 0x40046205 + BinderSetIdlePriorityIoctl = 0x40046206 + BinderSetContextMgrIoctl = 0x40046207 + BinderThreadExitIoctl = 0x40046208 + BinderVersionIoctl = 0xc0046209 +) + +// ioctl(2) requests provided by drivers/staging/android/uapi/ashmem.h +const ( + AshmemSetNameIoctl = 0x41007701 + AshmemGetNameIoctl = 0x81007702 + AshmemSetSizeIoctl = 0x40087703 + AshmemGetSizeIoctl = 0x00007704 + AshmemSetProtMaskIoctl = 0x40087705 + AshmemGetProtMaskIoctl = 0x00007706 + AshmemPinIoctl = 0x40087707 + AshmemUnpinIoctl = 0x40087708 + AshmemGetPinStatusIoctl = 0x00007709 + AshmemPurgeAllCachesIoctl = 0x0000770a +) diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go new file mode 100644 index 000000000..6b68999ab --- /dev/null +++ b/pkg/abi/linux/ip.go @@ -0,0 +1,44 @@ +// Copyright 2018 Google Inc. +// +// 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_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 +) diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go new file mode 100644 index 000000000..5441492e7 --- /dev/null +++ b/pkg/abi/linux/ipc.go @@ -0,0 +1,47 @@ +// Copyright 2018 Google Inc. +// +// 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. 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 = 00001000 + IPC_EXCL = 00002000 + IPC_NOWAIT = 00004000 +) + +const IPC_PRIVATE = 0 + +// IPCPerm is equivalent to struct ipc_perm. +type IPCPerm struct { + Key uint32 + UID uint32 + GID uint32 + CUID uint32 + CGID uint32 + Mode uint16 + pad1 uint16 + Seq uint16 + pad2 uint16 + reserved1 uint32 + reserved2 uint32 +} diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go new file mode 100644 index 000000000..e1f0932ec --- /dev/null +++ b/pkg/abi/linux/limits.go @@ -0,0 +1,88 @@ +// Copyright 2018 Google Inc. +// +// 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 * 1094 + + // 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}, +} diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go new file mode 100644 index 000000000..a946849c5 --- /dev/null +++ b/pkg/abi/linux/linux.go @@ -0,0 +1,38 @@ +// Copyright 2018 Google Inc. +// +// 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 inferface 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. +type Sysinfo struct { + Uptime int64 + Loads [3]uint64 + TotalRAM uint64 + FreeRAM uint64 + SharedRAM uint64 + BufferRAM uint64 + TotalSwap uint64 + FreeSwap uint64 + Procs uint16 + TotalHigh uint64 + FreeHigh uint64 + Unit uint32 + /* The _f field in the glibc version of Sysinfo has size 0 on AMD64 */ +} diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go new file mode 100644 index 000000000..2263653cc --- /dev/null +++ b/pkg/abi/linux/mm.go @@ -0,0 +1,103 @@ +// Copyright 2018 Google Inc. +// +// 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 + +// 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_FIXED = 1 << 4 + MAP_ANONYMOUS = 1 << 5 + 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 +) + +// 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 +) + +// Policies for get_mempolicy(2)/set_mempolicy(2). +const ( + MPOL_DEFAULT = 0 + MPOL_PREFERRED = 1 + MPOL_BIND = 2 + MPOL_INTERLEAVE = 3 + MPOL_LOCAL = 4 + MPOL_MAX = 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) +) diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go new file mode 100644 index 000000000..88654a1b3 --- /dev/null +++ b/pkg/abi/linux/netdevice.go @@ -0,0 +1,86 @@ +// Copyright 2018 Google Inc. +// +// 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 "gvisor.googlesource.com/gvisor/pkg/binary" + +const ( + // IFNAMSIZ is the size of the name field for IFReq. + IFNAMSIZ = 16 +) + +// IFReq is an interface request. +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)) + for i := n; i < len(ifr.IFName); i++ { + ifr.IFName[i] = 0 + } +} + +// SizeOfIFReq is the binary size of an IFReq struct (40 bytes). +var SizeOfIFReq = binary.Size(IFReq{}) + +// 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. +type IFConf struct { + Len int32 + _ [4]byte // Pad to sizeof(struct ifconf). + Ptr uint64 +} diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go new file mode 100644 index 000000000..e823ffa7e --- /dev/null +++ b/pkg/abi/linux/netlink.go @@ -0,0 +1,110 @@ +// Copyright 2018 Google Inc. +// +// 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. +type SockAddrNetlink struct { + Family uint16 + Padding uint16 + PortID uint32 + Groups uint32 +} + +// SockAddrNetlinkSize is the size of SockAddrNetlink. +const SockAddrNetlinkSize = 12 + +// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h. +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 flags, 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 + NLM_F_ROOT = 0x100 + NLM_F_MATCH = 0x200 + NLM_F_ATOMIC = 0x400 + NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH + NLM_F_REPLACE = 0x100 + NLM_F_EXCL = 0x200 + NLM_F_CREATE = 0x400 + NLM_F_APPEND = 0x800 +) + +// 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. +type NetlinkAttrHeader struct { + Length uint16 + Type uint16 +} + +// 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 diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go new file mode 100644 index 000000000..0d88bc5c5 --- /dev/null +++ b/pkg/abi/linux/netlink_route.go @@ -0,0 +1,186 @@ +// Copyright 2018 Google Inc. +// +// 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. +type InterfaceInfoMessage struct { + Family uint8 + Padding uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 +} + +// 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 +) + +// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h. +type InterfaceAddrMessage struct { + Family uint8 + PrefixLen uint8 + Flags uint8 + Scope uint8 + Index uint32 +} + +// 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 +) diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go new file mode 100644 index 000000000..f373cfca1 --- /dev/null +++ b/pkg/abi/linux/poll.go @@ -0,0 +1,42 @@ +// Copyright 2018 Google Inc. +// +// 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. +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 +) diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go new file mode 100644 index 000000000..6c93601de --- /dev/null +++ b/pkg/abi/linux/prctl.go @@ -0,0 +1,72 @@ +// Copyright 2018 Google Inc. +// +// 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 will set the process' death signal. + PR_SET_PDEATHSIG = 1 + + // PR_GET_PDEATHSIG will get the process' death signal. + PR_GET_PDEATHSIG = 2 + + // PR_GET_KEEPCAPS will get the value of the keep capabilities flag. + PR_GET_KEEPCAPS = 7 + + // PR_SET_KEEPCAPS will set the value of the keep capabilities flag. + PR_SET_KEEPCAPS = 8 + + // PR_SET_NAME will set the process' name. + PR_SET_NAME = 15 + + // PR_GET_NAME will get the process' name. + PR_GET_NAME = 16 + + // PR_SET_MM will modify certain kernel memory map descriptor fields of the + // calling process. See prctl(2) for more information. + PR_SET_MM = 35 + + // PR_SET_MM_EXE_FILE will supersede 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_NO_NEW_PRIVS will set the calling thread's no_new_privs bit. + PR_SET_NO_NEW_PRIVS = 38 + + // PR_GET_NO_NEW_PRIVS will get the calling thread's no_new_privs bit. + PR_GET_NO_NEW_PRIVS = 39 + + // PR_SET_SECCOMP will set a process' seccomp mode. + PR_SET_SECCOMP = 22 + + // PR_GET_SECCOMP will get a process' seccomp mode. + PR_GET_SECCOMP = 21 + + // PR_CAPBSET_READ will get the capability bounding set. + PR_CAPBSET_READ = 23 + + // PR_CAPBSET_DROP will set the capability bounding set. + PR_CAPBSET_DROP = 24 +) + +// 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 +) diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go new file mode 100644 index 000000000..a4a89abda --- /dev/null +++ b/pkg/abi/linux/rusage.go @@ -0,0 +1,46 @@ +// Copyright 2018 Google Inc. +// +// 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. +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 +} diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go new file mode 100644 index 000000000..05fda1604 --- /dev/null +++ b/pkg/abi/linux/sched.go @@ -0,0 +1,30 @@ +// Copyright 2018 Google Inc. +// +// 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 +) diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go new file mode 100644 index 000000000..a8de9d3d0 --- /dev/null +++ b/pkg/abi/linux/seccomp.go @@ -0,0 +1,38 @@ +// Copyright 2018 Google Inc. +// +// 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 + +// Seccomp constants taken from <linux/seccomp.h>. +const ( + SECCOMP_MODE_NONE = 0 + SECCOMP_MODE_FILTER = 2 + + SECCOMP_RET_KILL = 0x00000000 + SECCOMP_RET_TRAP = 0x00030000 + SECCOMP_RET_ERRNO = 0x00050000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_ALLOW = 0x7fff0000 + + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_DATA = 0x0000ffff + + SECCOMP_SET_MODE_FILTER = 1 + SECCOMP_FILTER_FLAG_TSYNC = 1 +) + +const ( + // AUDIT_ARCH_X86_64 is taken from <linux/audit.h>. + AUDIT_ARCH_X86_64 = 0xc000003e +) diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go new file mode 100644 index 000000000..f8d8debf1 --- /dev/null +++ b/pkg/abi/linux/sem.go @@ -0,0 +1,53 @@ +// Copyright 2018 Google Inc. +// +// 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 +) + +const SEM_UNDO = 0x1000 + +// SemidDS is equivalent to struct semid_ds. +type SemidDS struct { + SemPerm IPCPerm + SemOTime TimeT + reserved1 uint32 + SemCTime TimeT + reserved2 uint32 + SemNSems uint32 + reserved3 uint32 + reserved4 uint32 +} + +// Sembuf is equivalent to struct sembuf. +type Sembuf struct { + SemNum uint16 + SemOp int16 + SemFlg int16 +} diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go new file mode 100644 index 000000000..cd09008b5 --- /dev/null +++ b/pkg/abi/linux/signal.go @@ -0,0 +1,177 @@ +// Copyright 2018 Google Inc. +// +// 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 ( + "gvisor.googlesource.com/gvisor/pkg/bits" +) + +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. +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_ONSTACK = 0x08000000 + SA_RESTART = 0x10000000 + SA_NODEFER = 0x40000000 + SA_RESTARTHAND = 0x80000000 + SA_NOMASK = SA_NODEFER + SA_ONESHOT = SA_RESTARTHAND +) diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go new file mode 100644 index 000000000..9a78cc131 --- /dev/null +++ b/pkg/abi/linux/socket.go @@ -0,0 +1,290 @@ +// Copyright 2018 Google Inc. +// +// 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 "gvisor.googlesource.com/gvisor/pkg/binary" + +// 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_REINJECT = 0x8000000 + MSG_ZEROCOPY = 0x4000000 + MSG_FASTOPEN = 0x20000000 + MSG_CMSG_CLOEXEC = 0x40000000 +) + +// SOL_SOCKET is from socket.h +const SOL_SOCKET = 1 + +// Socket types, from linux/net.h. +const ( + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_RDM = 4 + SOCK_SEQPACKET = 5 + SOCK_DCCP = 6 + SOCK_PACKET = 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 +) + +// Socket options from socket.h. +const ( + SO_ERROR = 4 + SO_KEEPALIVE = 9 + SO_LINGER = 13 + SO_MARK = 36 + SO_PASSCRED = 16 + SO_PEERCRED = 17 + SO_PEERNAME = 28 + SO_PROTOCOL = 38 + SO_RCVBUF = 8 + SO_RCVTIMEO = 20 + SO_REUSEADDR = 2 + SO_SNDBUF = 7 + SO_SNDTIMEO = 21 + SO_TIMESTAMP = 29 + SO_TIMESTAMPNS = 35 + SO_TYPE = 3 +) + +// SockAddrInt is struct sockaddr_in, from uapi/linux/in.h. +type SockAddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte + Zero [8]uint8 // pad to sizeof(struct sockaddr). +} + +// SockAddrInt6 is struct sockaddr_in6, from uapi/linux/in6.h. +type SockAddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte + Scope_id uint32 +} + +// 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. +type SockAddrUnix struct { + Family uint16 + Path [UnixPathMax]int8 +} + +// TCPInfo is a collection of TCP statistics. +// +// From uapi/linux/tcp.h. +type TCPInfo struct { + State uint8 + CaState uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + 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 uint32 + ATO uint32 + SndMss uint32 + RcvMss uint32 + + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + 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 uint32 + RcvSpace uint32 + + TotalRetrans uint32 + + PacingRate uint64 + 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 uint32 + MinRTT uint32 + // DataSegsIn is RFC4898 tcpEStatsDataSegsIn. + DataSegsIn uint32 + // DataSegsOut is RFC4898 tcpEStatsDataSegsOut. + DataSegsOut uint32 + + 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 +} + +// SizeOfTCPInfo is the binary size of a TCPInfo struct (104 bytes). +var SizeOfTCPInfo = binary.Size(TCPInfo{}) + +// 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. +type ControlMessageHeader struct { + Length uint64 + Level int32 + Type int32 +} + +// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader +// struct. +var SizeOfControlMessageHeader = int(binary.Size(ControlMessageHeader{})) + +// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message. +// +// ControlMessageCredentials represents struct ucred from linux/socket.h. +type ControlMessageCredentials struct { + PID int32 + UID uint32 + GID uint32 +} + +// SizeOfControlMessageCredentials is the binary size of a +// ControlMessageCredentials struct. +var SizeOfControlMessageCredentials = int(binary.Size(ControlMessageCredentials{})) + +// A ControlMessageRights is an SCM_RIGHTS socket control message. +type ControlMessageRights []int32 + +// SizeOfControlMessageRight is the size of a single element in +// ControlMessageRights. +const SizeOfControlMessageRight = 4 + +// SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call. +// From net/scm.h. +const SCM_MAX_FD = 253 diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go new file mode 100644 index 000000000..9109a2848 --- /dev/null +++ b/pkg/abi/linux/time.go @@ -0,0 +1,224 @@ +// Copyright 2018 Google Inc. +// +// 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. +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>. +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>. +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>. +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 */ +// }; +type ItimerVal struct { + Interval Timeval + Value Timeval +} + +// ClockT represents type clock_t. +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). +type Tms struct { + UTime ClockT + STime ClockT + CUTime ClockT + CSTime ClockT +} diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go new file mode 100644 index 000000000..f9e641af9 --- /dev/null +++ b/pkg/abi/linux/tty.go @@ -0,0 +1,292 @@ +// Copyright 2018 Google Inc. +// +// 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 +) + +// Termios is struct termios, defined in uapi/asm-generic/termbits.h. +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. +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 +} + +// Input flags. +const ( + IGNBRK = 0000001 + BRKINT = 0000002 + IGNPAR = 0000004 + PARMRK = 0000010 + INPCK = 0000020 + ISTRIP = 0000040 + INLCR = 0000100 + IGNCR = 0000200 + ICRNL = 0000400 + IUCLC = 0001000 + IXON = 0002000 + IXANY = 0004000 + IXOFF = 0010000 + IMAXBEL = 0020000 + IUTF8 = 0040000 +) + +// Output flags. +const ( + OPOST = 0000001 + OLCUC = 0000002 + ONLCR = 0000004 + OCRNL = 0000010 + ONOCR = 0000020 + ONLRET = 0000040 + OFILL = 0000100 + OFDEL = 0000200 + NLDLY = 0000400 + NL0 = 0000000 + NL1 = 0000400 + CRDLY = 0003000 + CR0 = 0000000 + CR1 = 0001000 + CR2 = 0002000 + CR3 = 0003000 + TABDLY = 0014000 + TAB0 = 0000000 + TAB1 = 0004000 + TAB2 = 0010000 + TAB3 = 0014000 + XTABS = 0014000 + BSDLY = 0020000 + BS0 = 0000000 + BS1 = 0020000 + VTDLY = 0040000 + VT0 = 0000000 + VT1 = 0040000 + FFDLY = 0100000 + FF0 = 0000000 + FF1 = 0100000 +) + +// Control flags. +const ( + CBAUD = 0010017 + B0 = 0000000 + B50 = 0000001 + B75 = 0000002 + B110 = 0000003 + B134 = 0000004 + B150 = 0000005 + B200 = 0000006 + B300 = 0000007 + B600 = 0000010 + B1200 = 0000011 + B1800 = 0000012 + B2400 = 0000013 + B4800 = 0000014 + B9600 = 0000015 + B19200 = 0000016 + B38400 = 0000017 + EXTA = B19200 + EXTB = B38400 + CSIZE = 0000060 + CS5 = 0000000 + CS6 = 0000020 + CS7 = 0000040 + CS8 = 0000060 + CSTOPB = 0000100 + CREAD = 0000200 + PARENB = 0000400 + PARODD = 0001000 + HUPCL = 0002000 + CLOCAL = 0004000 + CBAUDEX = 0010000 + BOTHER = 0010000 + B57600 = 0010001 + B115200 = 0010002 + B230400 = 0010003 + B460800 = 0010004 + B500000 = 0010005 + B576000 = 0010006 + B921600 = 0010007 + B1000000 = 0010010 + B1152000 = 0010011 + B1500000 = 0010012 + B2000000 = 0010013 + B2500000 = 0010014 + B3000000 = 0010015 + B3500000 = 0010016 + B4000000 = 0010017 + CIBAUD = 002003600000 + CMSPAR = 010000000000 + CRTSCTS = 020000000000 + + // IBSHIFT is the shift from CBAUD to CIBAUD. + IBSHIFT = 16 +) + +// Local flags. +const ( + ISIG = 0000001 + ICANON = 0000002 + XCASE = 0000004 + ECHO = 0000010 + ECHOE = 0000020 + ECHOK = 0000040 + ECHONL = 0000100 + NOFLSH = 0000200 + TOSTOP = 0000400 + ECHOCTL = 0001000 + ECHOPRT = 0002000 + ECHOKE = 0004000 + FLUSHO = 0010000 + PENDIN = 0040000 + IEXTEN = 0100000 + EXTPROC = 0200000 +) + +// 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, +} + +// DefaultSlaveTermios is the default terminal configuration of the slave end +// of a Unix98 pseudoterminal. +var DefaultSlaveTermios = 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, +} diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go new file mode 100644 index 000000000..93c972774 --- /dev/null +++ b/pkg/abi/linux/uio.go @@ -0,0 +1,18 @@ +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go new file mode 100644 index 000000000..7d33d20de --- /dev/null +++ b/pkg/abi/linux/utsname.go @@ -0,0 +1,49 @@ +// Copyright 2018 Google Inc. +// +// 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). +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)) +} |