|
32 | 32 | # define PR_CAP_AMBIENT_RAISE 2
|
33 | 33 | #endif
|
34 | 34 |
|
| 35 | +#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW |
| 36 | +# define SECCOMP_FILTER_FLAG_SPEC_ALLOW 4 |
| 37 | +#endif |
| 38 | + |
| 39 | +#ifndef PR_GET_SPECULATION_CTRL |
| 40 | +# define PR_GET_SPECULATION_CTRL 52 |
| 41 | +#endif |
| 42 | +#ifndef PR_SET_SPECULATION_CTRL |
| 43 | +# define PR_SET_SPECULATION_CTRL 53 |
| 44 | +#endif |
| 45 | +#ifndef PR_SPEC_PRCTL |
| 46 | +# define PR_SPEC_PRCTL 1 |
| 47 | +#endif |
| 48 | +#ifndef PR_SPEC_ENABLE |
| 49 | +# define PR_SPEC_ENABLE 2 |
| 50 | +#endif |
| 51 | +#ifndef PR_SPEC_DISABLE |
| 52 | +# define PR_SPEC_DISABLE 4 |
| 53 | +#endif |
| 54 | +#ifndef PR_SPEC_DISABLE_NOEXEC |
| 55 | +# define PR_SPEC_DISABLE_NOEXEC 16 |
| 56 | +#endif |
| 57 | +#ifndef PR_SPEC_STORE_BYPASS |
| 58 | +# define PR_SPEC_STORE_BYPASS 0 |
| 59 | +#endif |
| 60 | +#ifndef PR_SPEC_INDIRECT_BRANCH |
| 61 | +# define PR_SPEC_INDIRECT_BRANCH 1 |
| 62 | +#endif |
| 63 | + |
35 | 64 | static struct capabilities_v3 caps;
|
36 | 65 |
|
37 | 66 | static struct sock_filter filter[] = {
|
@@ -67,6 +96,35 @@ static struct sock_filter filter[] = {
|
67 | 96 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO|(SECCOMP_RET_DATA & 0x0)),
|
68 | 97 | };
|
69 | 98 |
|
| 99 | +MAYBE_UNUSED static int |
| 100 | +disable_mitigation(int spec) |
| 101 | +{ |
| 102 | + switch (prctl(PR_GET_SPECULATION_CTRL, spec, 0, 0, 0)) { |
| 103 | + case PR_SPEC_PRCTL|PR_SPEC_DISABLE: |
| 104 | + case PR_SPEC_PRCTL|PR_SPEC_DISABLE_NOEXEC: |
| 105 | + if (prctl(PR_SET_SPECULATION_CTRL, spec, PR_SPEC_ENABLE, 0, 0) < 0) |
| 106 | + return (-1); |
| 107 | + break; |
| 108 | + case -1: |
| 109 | + if (errno != EINVAL && errno != ENODEV) |
| 110 | + return (-1); |
| 111 | + break; |
| 112 | + } |
| 113 | + return (0); |
| 114 | +} |
| 115 | + |
| 116 | +static int |
| 117 | +seccomp_set_filter(void) |
| 118 | +{ |
| 119 | +#ifdef ALLOW_SPECULATION |
| 120 | + if ((int)syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_SPEC_ALLOW, &(const struct sock_fprog){ARRAY_SIZE(filter), filter}) == 0) |
| 121 | + return (0); |
| 122 | + else if (errno != EINVAL) |
| 123 | + return (-1); |
| 124 | +#endif |
| 125 | + return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &(const struct sock_fprog){ARRAY_SIZE(filter), filter}); |
| 126 | +} |
| 127 | + |
70 | 128 | int
|
71 | 129 | main(int argc, char *argv[])
|
72 | 130 | {
|
@@ -105,9 +163,15 @@ main(int argc, char *argv[])
|
105 | 163 | }
|
106 | 164 | }
|
107 | 165 |
|
108 |
| - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &(const struct sock_fprog){ARRAY_SIZE(filter), filter}) < 0) |
| 166 | + if (seccomp_set_filter() < 0) |
109 | 167 | err(EXIT_FAILURE, "failed to register seccomp filter");
|
110 | 168 |
|
| 169 | +#ifdef ALLOW_SPECULATION |
| 170 | + if (disable_mitigation(PR_SPEC_STORE_BYPASS) < 0) |
| 171 | + err(EXIT_FAILURE, "failed to disable SSBD mitigation"); |
| 172 | + if (disable_mitigation(PR_SPEC_INDIRECT_BRANCH) < 0) |
| 173 | + err(EXIT_FAILURE, "failed to disable IBPB/STIBP mitigation"); |
| 174 | +#endif |
111 | 175 | if (execvp(argv[1], &argv[1]) < 0)
|
112 | 176 | err(EXIT_FAILURE, "failed to execute: %s", argv[1]);
|
113 | 177 | return (0);
|
|
0 commit comments