Skip to content

Commit 1bcbe5d

Browse files
committed
api: add the SCMP_FLTATR_CTL_WAITKILL filter attribute
The SCMP_FLTATR_CTL_WAITKILL attribute requests that the SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV flag be passed to the seccomp(2) system call when possible, which is currently only when the SECCOMP_FILTER_FLAG_NEW_LISTENER flag is also set. Signed-off-by: Paul Moore <[email protected]>
1 parent e797591 commit 1bcbe5d

File tree

14 files changed

+97
-4
lines changed

14 files changed

+97
-4
lines changed

doc/man/man3/seccomp_api_get.3

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH "seccomp_api_get" 3 "6 November 2020" "[email protected]" "libseccomp Documentation"
1+
.TH "seccomp_api_get" 3 "22 September 2022" "[email protected]" "libseccomp Documentation"
22
.\" //////////////////////////////////////////////////////////////////////////
33
.SH NAME
44
.\" //////////////////////////////////////////////////////////////////////////
@@ -60,6 +60,9 @@ The SCMP_ACT_NOTIFY action and the notify APIs are supported.
6060
.TP
6161
.B 6
6262
The simultaneous use of SCMP_FLTATR_CTL_TSYNC and the notify APIs are supported.
63+
.TP
64+
.B 7
65+
The SCMP_FLTATR_CTL_WAITKILL filter attribute is supported.
6366
.\" //////////////////////////////////////////////////////////////////////////
6467
.SH RETURN VALUE
6568
.\" //////////////////////////////////////////////////////////////////////////

doc/man/man3/seccomp_attr_set.3

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH "seccomp_attr_set" 3 "06 June 2020" "[email protected]" "libseccomp Documentation"
1+
.TH "seccomp_attr_set" 3 "21 September 2022" "[email protected]" "libseccomp Documentation"
22
.\" //////////////////////////////////////////////////////////////////////////
33
.SH NAME
44
.\" //////////////////////////////////////////////////////////////////////////
@@ -132,6 +132,12 @@ A flag to specify if libseccomp should pass system error codes back to the
132132
caller instead of the default -ECANCELED. Defaults to off
133133
.RI ( value
134134
== 0).
135+
.TP
136+
.B SCMP_FLTATR_CTL_WAITKILL
137+
A flag to specify if libseccomp should request wait killable semantics when
138+
possible. Defaults to off
139+
.RI ( value
140+
== 0).
135141
.\" //////////////////////////////////////////////////////////////////////////
136142
.SH RETURN VALUE
137143
.\" //////////////////////////////////////////////////////////////////////////

include/seccomp.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum scmp_filter_attr {
7878
* number
7979
*/
8080
SCMP_FLTATR_API_SYSRAWRC = 9, /**< return the system return codes */
81+
SCMP_FLTATR_CTL_WAITKILL = 10, /**< request wait killable semantics */
8182
_SCMP_FLTATR_MAX,
8283
};
8384

@@ -424,6 +425,7 @@ const struct scmp_version *seccomp_version(void);
424425
* 4 : support for the SCMP_FLTATR_CTL_SSB filter attribute
425426
* 5 : support for the SCMP_ACT_NOTIFY action and notify APIs
426427
* 6 : support the simultaneous use of SCMP_FLTATR_CTL_TSYNC and notify APIs
428+
* 7 : support for the SCMP_FLTATR_CTL_WAITKILL filter attribute
427429
*
428430
*/
429431
unsigned int seccomp_api_get(void);

src/api.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ static unsigned int _seccomp_api_update(void)
191191
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) == 1)
192192
level = 6;
193193

194+
if (level == 6 &&
195+
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV) == 1)
196+
level = 7;
197+
194198
/* update the stored api level and return */
195199
seccomp_api_level = level;
196200
return seccomp_api_level;
@@ -223,6 +227,8 @@ API int seccomp_api_set(unsigned int level)
223227
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
224228
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
225229
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
230+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
231+
false);
226232
break;
227233
case 2:
228234
sys_set_seccomp_syscall(true);
@@ -234,6 +240,8 @@ API int seccomp_api_set(unsigned int level)
234240
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
235241
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
236242
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
243+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
244+
false);
237245
break;
238246
case 3:
239247
sys_set_seccomp_syscall(true);
@@ -245,6 +253,8 @@ API int seccomp_api_set(unsigned int level)
245253
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
246254
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
247255
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
256+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
257+
false);
248258
break;
249259
case 4:
250260
sys_set_seccomp_syscall(true);
@@ -256,6 +266,8 @@ API int seccomp_api_set(unsigned int level)
256266
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
257267
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
258268
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
269+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
270+
false);
259271
break;
260272
case 5:
261273
sys_set_seccomp_syscall(true);
@@ -267,6 +279,8 @@ API int seccomp_api_set(unsigned int level)
267279
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
268280
sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
269281
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
282+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
283+
false);
270284
break;
271285
case 6:
272286
sys_set_seccomp_syscall(true);
@@ -278,6 +292,21 @@ API int seccomp_api_set(unsigned int level)
278292
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
279293
sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
280294
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true);
295+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
296+
false);
297+
break;
298+
case 7:
299+
sys_set_seccomp_syscall(true);
300+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
301+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
302+
sys_set_seccomp_action(SCMP_ACT_LOG, true);
303+
sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
304+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true);
305+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
306+
sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
307+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true);
308+
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
309+
true);
281310
break;
282311
default:
283312
return _rc_filter(-EINVAL);

src/db.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
10721072
col->attr.spec_allow = 0;
10731073
col->attr.optimize = 1;
10741074
col->attr.api_sysrawrc = 0;
1075+
col->attr.wait_killable_recv = 0;
10751076

10761077
/* set the state */
10771078
col->state = _DB_STA_VALID;
@@ -1331,6 +1332,9 @@ int db_col_attr_get(const struct db_filter_col *col,
13311332
case SCMP_FLTATR_API_SYSRAWRC:
13321333
*value = col->attr.api_sysrawrc;
13331334
break;
1335+
case SCMP_FLTATR_CTL_WAITKILL:
1336+
*value = col->attr.wait_killable_recv;
1337+
break;
13341338
default:
13351339
rc = -EINVAL;
13361340
break;
@@ -1444,6 +1448,9 @@ int db_col_attr_set(struct db_filter_col *col,
14441448
case SCMP_FLTATR_API_SYSRAWRC:
14451449
col->attr.api_sysrawrc = (value ? 1 : 0);
14461450
break;
1451+
case SCMP_FLTATR_CTL_WAITKILL:
1452+
col->attr.wait_killable_recv = (value ? 1 : 0);
1453+
break;
14471454
default:
14481455
rc = -EINVAL;
14491456
break;

src/db.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct db_filter_attr {
124124
uint32_t optimize;
125125
/* return the raw system return codes */
126126
uint32_t api_sysrawrc;
127+
/* request SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV */
128+
uint32_t wait_killable_recv;
127129
};
128130

129131
struct db_filter {

src/python/libseccomp.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ cdef extern from "seccomp.h":
6363
SCMP_FLTATR_CTL_SSB
6464
SCMP_FLTATR_CTL_OPTIMIZE
6565
SCMP_FLTATR_API_SYSRAWRC
66+
SCMP_FLTATR_CTL_WAITKILL
6667

6768
cdef enum scmp_compare:
6869
SCMP_CMP_NE

src/python/seccomp.pyx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ cdef class Attr:
325325
1: rules weighted by priority and complexity (DEFAULT)
326326
2: binary tree sorted by syscall number
327327
API_SYSRAWRC - return the raw syscall codes
328+
CTL_WAITKILL - request wait killable semantics
328329
"""
329330
ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT
330331
ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH
@@ -335,6 +336,7 @@ cdef class Attr:
335336
CTL_SSB = libseccomp.SCMP_FLTATR_CTL_SSB
336337
CTL_OPTIMIZE = libseccomp.SCMP_FLTATR_CTL_OPTIMIZE
337338
API_SYSRAWRC = libseccomp.SCMP_FLTATR_API_SYSRAWRC
339+
CTL_WAITKILL = libseccomp.SCMP_FLTATR_CTL_WAITKILL
338340

339341
cdef class Arg:
340342
""" Python object representing a SyscallFilter syscall argument.

src/system.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct task_state {
5858
int sup_flag_new_listener;
5959
int sup_user_notif;
6060
int sup_flag_tsync_esrch;
61+
int sup_flag_wait_kill;
6162
};
6263
static struct task_state state = {
6364
.nr_seccomp = -1,
@@ -73,6 +74,7 @@ static struct task_state state = {
7374
.sup_flag_new_listener = -1,
7475
.sup_user_notif = -1,
7576
.sup_flag_tsync_esrch = -1,
77+
.sup_flag_wait_kill = -1,
7678
};
7779

7880
/**
@@ -307,6 +309,10 @@ int sys_chk_seccomp_flag(int flag)
307309
if (state.sup_flag_tsync_esrch < 0)
308310
state.sup_flag_tsync_esrch = _sys_chk_flag_kernel(flag);
309311
return state.sup_flag_tsync_esrch;
312+
case SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV:
313+
if (state.sup_flag_wait_kill < 0)
314+
state.sup_flag_wait_kill = _sys_chk_flag_kernel(flag);
315+
return state.sup_flag_wait_kill;
310316
}
311317

312318
return -EOPNOTSUPP;
@@ -339,6 +345,9 @@ void sys_set_seccomp_flag(int flag, bool enable)
339345
case SECCOMP_FILTER_FLAG_TSYNC_ESRCH:
340346
state.sup_flag_tsync_esrch = (enable ? 1 : 0);
341347
break;
348+
case SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV:
349+
state.sup_flag_wait_kill = (enable ? 1 : 0);
350+
break;
342351
}
343352
}
344353

@@ -394,6 +403,9 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc)
394403
flgs |= SECCOMP_FILTER_FLAG_TSYNC;
395404
} else if (listener_req)
396405
flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER;
406+
if ((flgs & SECCOMP_FILTER_FLAG_NEW_LISTENER) &&
407+
col->attr.wait_killable_recv)
408+
flgs |= SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV;
397409
if (col->attr.log_enable)
398410
flgs |= SECCOMP_FILTER_FLAG_LOG;
399411
if (col->attr.spec_allow)

src/system.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ typedef struct sock_filter bpf_instr_raw;
138138
#ifndef SECCOMP_FILTER_FLAG_TSYNC_ESRCH
139139
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
140140
#endif
141+
#ifndef SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV
142+
#define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5)
143+
#endif
141144

142145
#ifndef SECCOMP_RET_LOG
143146
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */

tests/13-basic-attrs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ int main(int argc, char *argv[])
142142
goto out;
143143
}
144144

145+
rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_WAITKILL, 1);
146+
if (rc != 0)
147+
goto out;
148+
rc = seccomp_attr_get(ctx, SCMP_FLTATR_CTL_WAITKILL, &val);
149+
if (rc != 0)
150+
goto out;
151+
if (val != 1) {
152+
rc = -1;
153+
goto out;
154+
}
155+
145156
rc = 0;
146157
out:
147158
seccomp_release(ctx);

tests/13-basic-attrs.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ def test():
6161
f.set_attr(Attr.API_SYSRAWRC, 1)
6262
if f.get_attr(Attr.API_SYSRAWRC) != 1:
6363
raise RuntimeError("Failed getting Attr.API_SYSRAWRC")
64+
f.set_attr(Attr.CTL_WAITKILL, 1)
65+
if f.get_attr(Attr.CTL_WAITKILL) != 1:
66+
raise RuntimeError("Failed getting Attr.CTL_WAITKILL")
6467

6568
test()
6669

tests/39-basic-api_level.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,20 @@ int main(int argc, char *argv[])
7575
if (api != 6)
7676
return -13;
7777

78+
rc = seccomp_api_set(7);
79+
if (rc != 0)
80+
return -14;
81+
api = seccomp_api_get();
82+
if (api != 7)
83+
return -15;
84+
7885
/* Attempt to set a high, invalid API level */
7986
rc = seccomp_api_set(1024);
8087
if (rc != -EINVAL)
8188
return -1001;
8289
/* Ensure that the previously set API level didn't change */
8390
api = seccomp_api_get();
84-
if (api != 6)
91+
if (api != 7)
8592
return -1002;
8693

8794
return 0;

tests/39-basic-api_level.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ def test():
6565
if api != 6:
6666
raise RuntimeError("Failed getting API level 6")
6767

68+
set_api(7)
69+
api = get_api()
70+
if api != 7:
71+
raise RuntimeError("Failed getting API level 7")
72+
6873
# Attempt to set a high, invalid API level
6974
try:
7075
set_api(1024)
@@ -74,7 +79,7 @@ def test():
7479
raise RuntimeError("Missing failure when setting invalid API level")
7580
# Ensure that the previously set API level didn't change
7681
api = get_api()
77-
if api != 6:
82+
if api != 7:
7883
raise RuntimeError("Failed getting old API level after setting an invalid API level")
7984

8085
test()

0 commit comments

Comments
 (0)