1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2020 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
// Use of this source is governed by Apache-2.0 License that can be found
// in the LICENSE file.

//! From `include/uapi/linux/seccomp.h`

#![allow(clippy::module_name_repetitions)]

use crate::IO;

/// Valid values for seccomp.mode and prctl(`PR_SET_SECCOMP`, `<mode>`)
/// seccomp is not in use.
pub const SECCOMP_MODE_DISABLED: i32 = 0;
/// uses hard-coded filter.
pub const SECCOMP_MODE_STRICT: i32 = 1;
/// uses user-supplied filter.
pub const SECCOMP_MODE_FILTER: i32 = 2;

/// Valid operations for seccomp syscall.
pub const SECCOMP_SET_MODE_STRICT: i32 = 0;
pub const SECCOMP_SET_MODE_FILTER: i32 = 1;
pub const SECCOMP_GET_ACTION_AVAIL: i32 = 2;
pub const SECCOMP_GET_NOTIF_SIZES: i32 = 3;

/// Valid flags for `SECCOMP_SET_MODE_FILTER`
pub const SECCOMP_FILTER_FLAG_TSYNC: usize = 1;
pub const SECCOMP_FILTER_FLAG_LOG: usize = 1 << 1;
pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: usize = 1 << 2;
pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: usize = 1 << 3;

/// All BPF programs must return a 32-bit value.
/// The bottom 16-bits are for optional return data.
/// The upper 16-bits are ordered from least permissive values to most,
/// as a signed value (so 0x8000000 is negative).
///
/// The ordering ensures that a `min_t()` over composed return values always
/// selects the least permissive choice.
/// kill the process
pub const SECCOMP_RET_KILL_PROCESS: u32 = 0x8000_0000;
/// kill the thread
pub const SECCOMP_RET_KILL_THREAD: u32 = 0x0000_0000;
pub const SECCOMP_RET_KILL: u32 = SECCOMP_RET_KILL_THREAD;
/// disallow and force a SIGSYS
pub const SECCOMP_RET_TRAP: u32 = 0x0003_0000;
/// returns an errno
pub const SECCOMP_RET_ERRNO: u32 = 0x0005_0000;
/// notifies userspace
pub const SECCOMP_RET_USER_NOTIF: u32 = 0x7fc0_0000;
/// pass to a tracer or disallow
pub const SECCOMP_RET_TRACE: u32 = 0x7ff0_0000;
/// allow after logging
pub const SECCOMP_RET_LOG: u32 = 0x7ffc_0000;
/// allow
pub const SECCOMP_RET_ALLOW: u32 = 0x7fff_0000;

/// Masks for the return value sections.
pub const SECCOMP_RET_ACTION_FULL: u32 = 0xffff_0000;
pub const SECCOMP_RET_ACTION: u32 = 0x7fff_0000;
pub const SECCOMP_RET_DATA: u32 = 0x0000_ffff;

/// struct `seccomp_data` - the format the BPF program executes over.
/// @nr: the system call number
/// @arch: indicates system call convention as an `AUDIT_ARCH_*` value
///        as defined in `<linux/audit.h>`.
/// `@instruction_pointer`: at the time of the system call.
/// @args: up to 6 system call arguments always stored as 64-bit values
///        regardless of the architecture.
#[repr(C)]
#[derive(Debug, Default, Clone, Copy)]
pub struct seccomp_data_t {
    pub nr: i32,
    pub arch: u32,
    pub instruction_pointer: u64,
    pub args: [u64; 6],
}

#[repr(C)]
#[derive(Debug, Default, Clone, Copy)]
pub struct seccomp_notif_sizes_t {
    pub seccomp_notif: u16,
    pub seccomp_notif_resp: u16,
    pub seccomp_data: u16,
}

#[repr(C)]
#[derive(Debug, Default, Clone, Copy)]
pub struct seccomp_notif_t {
    pub id: u64,
    pub pid: u32,
    pub flags: u32,
    pub data: seccomp_data_t,
}

#[repr(C)]
#[derive(Debug, Default, Clone, Copy)]
pub struct seccomp_notif_resp_t {
    pub id: u64,
    pub val: i64,
    pub error: i32,
    pub flags: u32,
}

pub const SECCOMP_IOC_MAGIC: char = '!';

#[inline]
#[must_use]
pub const fn SECCOMP_IO(nr: i32) -> i32 {
    IO(SECCOMP_IOC_MAGIC, nr)
}

// TODO(Shaohua):
//#[inline]
//pub const fn SECCOMP_IOR(nr: i32, type_: char) -> i32 {
//    IOR(SECCOMP_IOC_MAGIC, nr, type_)
//}
//
//#[inline]
//pub const fn SECCOMP_IOW(nr: i32, type_: char) -> i32 {
//    IOW(SECCOMP_IOC_MAGIC, nr, type_)
//}
//
//#[inline]
//pub const fn SECCOMP_IOWR(nr: i32, type_: char) -> i32 {
//    IOWR(SECCOMP_IOC_MAGIC, nr, type_)
//}
//
///// Flags for seccomp notification fd ioctl.
//pub const SECCOMP_IOCTL_NOTIF_RECV: i32 = SECCOMP_IOWR(0, seccomp_notif_t);
//
//pub const SECCOMP_IOCTL_NOTIF_SEND: i32 = SECCOMP_IOWR(1, seccomp_notif_resp_t);
//
//pub const SECCOMP_IOCTL_NOTIF_ID_VALID: i32 = SECCOMP_IOR(2, u64);