diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-09-11 16:33:57 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-11 16:33:57 -0400 |
| commit | 1eaf0691f97decfdee9d73a72869ad63805d159b (patch) | |
| tree | 58564e4b6df649f051681470ae5ced82f2f85a55 /lib | |
| parent | 42c32dbc7b6cb474a1aa6dc524acb7451efeb15e (diff) | |
| parent | 1078810cef4b346bdcd0ab0cab27dd997e68d206 (diff) | |
| download | zig-1eaf0691f97decfdee9d73a72869ad63805d159b.tar.gz zig-1eaf0691f97decfdee9d73a72869ad63805d159b.zip | |
Merge pull request #6320 from ifreund/prctl
std: add prctl and securebits definitions for linux/C
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/c.zig | 2 | ||||
| -rw-r--r-- | lib/std/os.zig | 39 | ||||
| -rw-r--r-- | lib/std/os/bits/linux.zig | 2 | ||||
| -rw-r--r-- | lib/std/os/bits/linux/prctl.zig | 158 | ||||
| -rw-r--r-- | lib/std/os/bits/linux/securebits.zig | 41 | ||||
| -rw-r--r-- | lib/std/os/linux.zig | 4 |
6 files changed, 246 insertions, 0 deletions
diff --git a/lib/std/c.zig b/lib/std/c.zig index bbc32cf351..aa50fff90e 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -340,3 +340,5 @@ pub extern "c" fn sync() void; pub extern "c" fn syncfs(fd: c_int) c_int; pub extern "c" fn fsync(fd: c_int) c_int; pub extern "c" fn fdatasync(fd: c_int) c_int; + +pub extern "c" fn prctl(option: c_int, ...) c_int; diff --git a/lib/std/os.zig b/lib/std/os.zig index 25c71e5d15..91365c81dd 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -5418,3 +5418,42 @@ pub fn fdatasync(fd: fd_t) SyncError!void { else => |err| return std.os.unexpectedErrno(err), } } + +pub const PrctlError = error{ + /// Can only occur with PR_SET_SECCOMP/SECCOMP_MODE_FILTER or + /// PR_SET_MM/PR_SET_MM_EXE_FILE + AccessDenied, + /// Can only occur with PR_SET_MM/PR_SET_MM_EXE_FILE + InvalidFileDescriptor, + InvalidAddress, + /// Can only occur with PR_SET_SPECULATION_CTRL, PR_MPX_ENABLE_MANAGEMENT, + /// or PR_MPX_DISABLE_MANAGEMENT + UnsupportedFeature, + /// Can only occur wih PR_SET_FP_MODE + OperationNotSupported, + PermissionDenied, +} || UnexpectedError; + +pub fn prctl(option: i32, args: anytype) PrctlError!u31 { + if (@typeInfo(@TypeOf(args)) != .Struct) + @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args))); + if (args.len > 4) + @compileError("prctl takes a maximum of 4 optional arguments"); + + var buf: [4]usize = undefined; + inline for (args) |arg, i| buf[i] = arg; + + const rc = system.prctl(option, buf[0], buf[1], buf[2], buf[3]); + switch (errno(rc)) { + 0 => return @intCast(u31, rc), + EACCES => return error.AccessDenied, + EBADF => return error.InvalidFileDescriptor, + EFAULT => return error.InvalidAddress, + EINVAL => unreachable, + ENODEV, ENXIO => return error.UnsupportedFeature, + EOPNOTSUPP => return error.OperationNotSupported, + EPERM, EBUSY => return error.PermissionDenied, + ERANGE => unreachable, + else => |err| return std.os.unexpectedErrno(err), + } +} diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index f393f04abe..df31bc32fd 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -25,6 +25,8 @@ pub usingnamespace switch (builtin.arch) { }; pub usingnamespace @import("linux/netlink.zig"); +pub usingnamespace @import("linux/prctl.zig"); +pub usingnamespace @import("linux/securebits.zig"); const is_mips = builtin.arch.isMIPS(); diff --git a/lib/std/os/bits/linux/prctl.zig b/lib/std/os/bits/linux/prctl.zig new file mode 100644 index 0000000000..7fa9969af4 --- /dev/null +++ b/lib/std/os/bits/linux/prctl.zig @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. + +pub const PR_SET_PDEATHSIG = 1; +pub const PR_GET_PDEATHSIG = 2; + +pub const PR_GET_DUMPABLE = 3; +pub const PR_SET_DUMPABLE = 4; + +pub const PR_GET_UNALIGN = 5; +pub const PR_SET_UNALIGN = 6; +pub const PR_UNALIGN_NOPRINT = 1; +pub const PR_UNALIGN_SIGBUS = 2; + +pub const PR_GET_KEEPCAPS = 7; +pub const PR_SET_KEEPCAPS = 8; + +pub const PR_GET_FPEMU = 9; +pub const PR_SET_FPEMU = 10; +pub const PR_FPEMU_NOPRINT = 1; +pub const PR_FPEMU_SIGFPE = 2; + +pub const PR_GET_FPEXC = 11; +pub const PR_SET_FPEXC = 12; +pub const PR_FP_EXC_SW_ENABLE = 0x80; +pub const PR_FP_EXC_DIV = 0x010000; +pub const PR_FP_EXC_OVF = 0x020000; +pub const PR_FP_EXC_UND = 0x040000; +pub const PR_FP_EXC_RES = 0x080000; +pub const PR_FP_EXC_INV = 0x100000; +pub const PR_FP_EXC_DISABLED = 0; +pub const PR_FP_EXC_NONRECOV = 1; +pub const PR_FP_EXC_ASYNC = 2; +pub const PR_FP_EXC_PRECISE = 3; + +pub const PR_GET_TIMING = 13; +pub const PR_SET_TIMING = 14; +pub const PR_TIMING_STATISTICAL = 0; +pub const PR_TIMING_TIMESTAMP = 1; + +pub const PR_SET_NAME = 15; +pub const PR_GET_NAME = 16; + +pub const PR_GET_ENDIAN = 19; +pub const PR_SET_ENDIAN = 20; +pub const PR_ENDIAN_BIG = 0; +pub const PR_ENDIAN_LITTLE = 1; +pub const PR_ENDIAN_PPC_LITTLE = 2; + +pub const PR_GET_SECCOMP = 21; +pub const PR_SET_SECCOMP = 22; + +pub const PR_CAPBSET_READ = 23; +pub const PR_CAPBSET_DROP = 24; + +pub const PR_GET_TSC = 25; +pub const PR_SET_TSC = 26; +pub const PR_TSC_ENABLE = 1; +pub const PR_TSC_SIGSEGV = 2; + +pub const PR_GET_SECUREBITS = 27; +pub const PR_SET_SECUREBITS = 28; + +pub const PR_SET_TIMERSLACK = 29; +pub const PR_GET_TIMERSLACK = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE = 32; + +pub const PR_MCE_KILL = 33; +pub const PR_MCE_KILL_CLEAR = 0; +pub const PR_MCE_KILL_SET = 1; + +pub const PR_MCE_KILL_LATE = 0; +pub const PR_MCE_KILL_EARLY = 1; +pub const PR_MCE_KILL_DEFAULT = 2; + +pub const PR_MCE_KILL_GET = 34; + +pub const PR_SET_MM = 35; +pub const PR_SET_MM_START_CODE = 1; +pub const PR_SET_MM_END_CODE = 2; +pub const PR_SET_MM_START_DATA = 3; +pub const PR_SET_MM_END_DATA = 4; +pub const PR_SET_MM_START_STACK = 5; +pub const PR_SET_MM_START_BRK = 6; +pub const PR_SET_MM_BRK = 7; +pub const PR_SET_MM_ARG_START = 8; +pub const PR_SET_MM_ARG_END = 9; +pub const PR_SET_MM_ENV_START = 10; +pub const PR_SET_MM_ENV_END = 11; +pub const PR_SET_MM_AUXV = 12; +pub const PR_SET_MM_EXE_FILE = 13; +pub const PR_SET_MM_MAP = 14; +pub const PR_SET_MM_MAP_SIZE = 15; + +pub const prctl_mm_map = extern struct { + start_code: u64, + end_code: u64, + start_data: u64, + end_data: u64, + start_brk: u64, + brk: u64, + start_stack: u64, + arg_start: u64, + arg_end: u64, + env_start: u64, + env_end: u64, + auxv: *u64, + auxv_size: u32, + exe_fd: u32, +}; + +pub const PR_SET_PTRACER = 0x59616d61; +pub const PR_SET_PTRACER_ANY = std.math.maxInt(c_ulong); + +pub const PR_SET_CHILD_SUBREAPER = 36; +pub const PR_GET_CHILD_SUBREAPER = 37; + +pub const PR_SET_NO_NEW_PRIVS = 38; +pub const PR_GET_NO_NEW_PRIVS = 39; + +pub const PR_GET_TID_ADDRESS = 40; + +pub const PR_SET_THP_DISABLE = 41; +pub const PR_GET_THP_DISABLE = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT = 43; +pub const PR_MPX_DISABLE_MANAGEMENT = 44; + +pub const PR_SET_FP_MODE = 45; +pub const PR_GET_FP_MODE = 46; +pub const PR_FP_MODE_FR = 1 << 0; +pub const PR_FP_MODE_FRE = 1 << 1; + +pub const PR_CAP_AMBIENT = 47; +pub const PR_CAP_AMBIENT_IS_SET = 1; +pub const PR_CAP_AMBIENT_RAISE = 2; +pub const PR_CAP_AMBIENT_LOWER = 3; +pub const PR_CAP_AMBIENT_CLEAR_ALL = 4; + +pub const PR_SVE_SET_VL = 50; +pub const PR_SVE_SET_VL_ONEXEC = 1 << 18; +pub const PR_SVE_GET_VL = 51; +pub const PR_SVE_VL_LEN_MASK = 0xffff; +pub const PR_SVE_VL_INHERIT = 1 << 17; + +pub const PR_GET_SPECULATION_CTRL = 52; +pub const PR_SET_SPECULATION_CTRL = 53; +pub const PR_SPEC_STORE_BYPASS = 0; +pub const PR_SPEC_NOT_AFFECTED = 0; +pub const PR_SPEC_PRCTL = 1 << 0; +pub const PR_SPEC_ENABLE = 1 << 1; +pub const PR_SPEC_DISABLE = 1 << 2; +pub const PR_SPEC_FORCE_DISABLE = 1 << 3; diff --git a/lib/std/os/bits/linux/securebits.zig b/lib/std/os/bits/linux/securebits.zig new file mode 100644 index 0000000000..0086a694d9 --- /dev/null +++ b/lib/std/os/bits/linux/securebits.zig @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. + +fn issecure_mask(comptime x: comptime_int) comptime_int { + return 1 << x; +} + +pub const SECUREBITS_DEFAULT = 0x00000000; + +pub const SECURE_NOROOT = 0; +pub const SECURE_NOROOT_LOCKED = 1; + +pub const SECBIT_NOROOT = issecure_mask(SECURE_NOROOT); +pub const SECBIT_NOROOT_LOCKED = issecure_mask(SECURE_NOROOT_LOCKED); + +pub const SECURE_NO_SETUID_FIXUP = 2; +pub const SECURE_NO_SETUID_FIXUP_LOCKED = 3; + +pub const SECBIT_NO_SETUID_FIXUP = issecure_mask(SECURE_NO_SETUID_FIXUP); +pub const SECBIT_NO_SETUID_FIXUP_LOCKED = issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED); + +pub const SECURE_KEEP_CAPS = 4; +pub const SECURE_KEEP_CAPS_LOCKED = 5; + +pub const SECBIT_KEEP_CAPS = issecure_mask(SECURE_KEEP_CAPS); +pub const SECBIT_KEEP_CAPS_LOCKED = issecure_mask(SECURE_KEEP_CAPS_LOCKED); + +pub const SECURE_NO_CAP_AMBIENT_RAISE = 6; +pub const SECURE_NO_CAP_AMBIENT_RAISE_LOCKED = 7; + +pub const SECBIT_NO_CAP_AMBIENT_RAISE = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE); +pub const SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED); + +pub const SECURE_ALL_BITS = issecure_mask(SECURE_NOROOT) | + issecure_mask(SECURE_NO_SETUID_FIXUP) | + issecure_mask(SECURE_KEEP_CAPS) | + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE); +pub const SECURE_ALL_LOCKS = SECURE_ALL_BITS << 1; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 25a0d6814d..50d1e4ae78 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1259,6 +1259,10 @@ pub fn fdatasync(fd: fd_t) usize { return syscall1(.fdatasync, @bitCast(usize, @as(isize, fd))); } +pub fn prctl(option: i32, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return syscall5(.prctl, @bitCast(usize, @as(isize, option)), arg2, arg3, arg4, arg5); +} + test "" { if (builtin.os.tag == .linux) { _ = @import("linux/test.zig"); |
