• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

drakenclimber / libseccomp / 7064690886

01 Dec 2023 08:07PM UTC coverage: 89.523% (-0.5%) from 89.973%
7064690886

push

github

drakenclimber
Revert "tests: Fix wrong syscall-error in test 29"

Revert commit a707ec98cc2c ("tests: Fix wrong syscall-error in test
29").  The reverted commit properly set the syscall number to -10001 in
a call to seccomp_rule_add_exact(), but due to previously unknown
shortcomings in the test, this led to failures.  Revert to the previous
version of test 29.

Note that this reverted version of test 29 is not functioning as
originally designed, but it is largely benign and the functional test
will pass on all architectures.  (It's generating a BPF filter that will
allow all syscalls on x86.)

Fixes: a707ec98cc2c ("tests: Fix wrong syscall-error in test 29")
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>

2572 of 2873 relevant lines covered (89.52%)

272267.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.7
/src/api.c
1
/**
2
 * Seccomp Library API
3
 *
4
 * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com>
5
 * Author: Paul Moore <paul@paul-moore.com>
6
 */
7

8
/*
9
 * This library is free software; you can redistribute it and/or modify it
10
 * under the terms of version 2.1 of the GNU Lesser General Public License as
11
 * published by the Free Software Foundation.
12
 *
13
 * This library is distributed in the hope that it will be useful, but WITHOUT
14
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
16
 * for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this library; if not, see <http://www.gnu.org/licenses>.
20
 */
21

22
#include <endian.h>
23
#include <errno.h>
24
#include <inttypes.h>
25
#include <unistd.h>
26
#include <stdarg.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <stdbool.h>
30
#include <sys/ioctl.h>
31

32
#include <seccomp.h>
33

34
#include "arch.h"
35
#include "db.h"
36
#include "gen_pfc.h"
37
#include "gen_bpf.h"
38
#include "helper.h"
39
#include "system.h"
40

41
#define API        __attribute__((visibility("default")))
42

43
const struct scmp_version library_version = {
44
        .major = SCMP_VER_MAJOR,
45
        .minor = SCMP_VER_MINOR,
46
        .micro = SCMP_VER_MICRO,
47
};
48

49
unsigned int seccomp_api_level = 0;
50

51
/**
52
 * Filter the error codes we send back to callers
53
 * @param err the error code
54
 *
55
 * We consider error codes part of our API so we want to make sure we don't
56
 * accidentally send an undocumented error code to our callers.  This function
57
 * helps with that.
58
 *
59
 */
60
static int _rc_filter(int err)
113,828✔
61
{
62
        /* pass through success values */
63
        if (err >= 0)
113,103✔
64
                return err;
65

66
        /* filter the error codes */
67
        switch (err) {
1,081✔
68
        case -EACCES:
69
        /* NOTE: operation is not permitted by libseccomp */
70
        case -ECANCELED:
71
        /* NOTE: kernel level error that is beyond the control of
72
         *       libseccomp */
73
        case -EDOM:
74
        /* NOTE: failure due to arch/ABI */
75
        case -EEXIST:
76
        /* NOTE: operation failed due to existing rule or filter */
77
        case -EINVAL:
78
        /* NOTE: invalid input to the libseccomp API */
79
        case -ENOENT:
80
        /* NOTE: no matching entry found */
81
        case -ENOMEM:
82
        /* NOTE: unable to allocate enough memory to perform the
83
         *       requested operation */
84
        case -EOPNOTSUPP:
85
        /* NOTE: operation is not supported */
86
        case -ESRCH:
87
                /* NOTE: operation failed due to multi-threading */
88
                return err;
89
        default:
27✔
90
                /* NOTE: this is the default "internal libseccomp error"
91
                 *       error code, it is our catch-all */
92
                return -EFAULT;
27✔
93
        }
94
}
95

96
/**
97
 * Filter the system error codes we send back to callers
98
 * @param col the filter collection
99
 * @param err the error code
100
 *
101
 * This is similar to _rc_filter(), but it first checks the filter attribute
102
 * to determine if we should be filtering the return codes.
103
 *
104
 */
105
static int _rc_filter_sys(struct db_filter_col *col, int err)
5✔
106
{
107
        /* pass through success values */
108
        if (err >= 0)
5✔
109
                return err;
110

111
        /* pass the return code if the SCMP_FLTATR_API_SYSRAWRC is true */
112
        if (db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC))
3✔
113
                return err;
1✔
114
        return -ECANCELED;
115
}
116

117
/**
118
 * Validate a filter context
119
 * @param ctx the filter context
120
 *
121
 * Attempt to validate the provided filter context.  Returns zero if the
122
 * context is valid, negative values on failure.
123
 *
124
 */
125
static int _ctx_valid(const scmp_filter_ctx *ctx)
8,072✔
126
{
127
        return db_col_valid((struct db_filter_col *)ctx);
8,072✔
128
}
129

130
/**
131
 * Validate a syscall number
132
 * @param syscall the syscall number
133
 *
134
 * Attempt to perform basic syscall number validation.  Returns zero of the
135
 * syscall appears valid, negative values on failure.
136
 *
137
 */
138
static int _syscall_valid(const struct db_filter_col *col, int syscall)
50,597✔
139
{
140
        /* syscall -1 is used by tracers to skip the syscall */
141
        if (col->attr.api_tskip && syscall == -1)
6✔
142
                return 0;
143
        if (syscall <= -1 && syscall >= -99)
50,591✔
144
                return -EINVAL;
145
        return 0;
146
}
147

148
/**
149
 * Update the API level
150
 *
151
 * This function performs a series of tests to determine what functionality is
152
 * supported given the current running environment (kernel, etc.).  It is
153
 * important to note that this function only does meaningful checks the first
154
 * time it is run, the resulting API level is cached after this first run and
155
 * used for all subsequent calls.  The API level value is returned.
156
 *
157
 */
158
static unsigned int _seccomp_api_update(void)
7,621✔
159
{
160
        unsigned int level = 1;
7,621✔
161

162
        /* if seccomp_api_level > 0 then it's already been set, we're done */
163
        if (seccomp_api_level >= 1)
7,621✔
164
                return seccomp_api_level;
165

166
        /* NOTE: level 1 is the base level, start checking at 2 */
167

168
        if (sys_chk_seccomp_syscall() &&
13,704✔
169
            sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC) == 1)
6,852✔
170
                level = 2;
6,852✔
171

172
        if (level == 2 &&
6,852✔
173
            sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG) == 1 &&
13,704✔
174
            sys_chk_seccomp_action(SCMP_ACT_LOG) == 1 &&
13,704✔
175
            sys_chk_seccomp_action(SCMP_ACT_KILL_PROCESS) == 1)
6,852✔
176
                level = 3;
6,852✔
177

178
        if (level == 3 &&
6,852✔
179
            sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 1)
6,852✔
180
                level = 4;
6,852✔
181

182
        if (level == 4 &&
6,852✔
183
            sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER) == 1 &&
13,704✔
184
            sys_chk_seccomp_action(SCMP_ACT_NOTIFY) == 1)
6,852✔
185
                level = 5;
6,852✔
186

187
        if (level == 5 &&
6,852✔
188
            sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) == 1)
6,852✔
189
                level = 6;
6,852✔
190

191
        /* update the stored api level and return */
192
        seccomp_api_level = level;
6,852✔
193
        return seccomp_api_level;
6,852✔
194
}
195

196
/* NOTE - function header comment in include/seccomp.h */
197
API const struct scmp_version *seccomp_version(void)
1✔
198
{
199
        return &library_version;
1✔
200
}
201

202
/* NOTE - function header comment in include/seccomp.h */
203
API unsigned int seccomp_api_get(void)
10✔
204
{
205
        /* update the api level, if needed */
206
        return _seccomp_api_update();
10✔
207
}
208

209
/* NOTE - function header comment in include/seccomp.h */
210
API int seccomp_api_set(unsigned int level)
724✔
211
{
212
        switch (level) {
724✔
213
        case 1:
9✔
214
                sys_set_seccomp_syscall(false);
9✔
215
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, false);
9✔
216
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false);
9✔
217
                sys_set_seccomp_action(SCMP_ACT_LOG, false);
9✔
218
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false);
9✔
219
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false);
9✔
220
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
9✔
221
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
9✔
222
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
9✔
223
                break;
9✔
224
        case 2:
1✔
225
                sys_set_seccomp_syscall(true);
1✔
226
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
1✔
227
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false);
1✔
228
                sys_set_seccomp_action(SCMP_ACT_LOG, false);
1✔
229
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false);
1✔
230
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false);
1✔
231
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
1✔
232
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
1✔
233
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
1✔
234
                break;
1✔
235
        case 3:
709✔
236
                sys_set_seccomp_syscall(true);
709✔
237
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
709✔
238
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
709✔
239
                sys_set_seccomp_action(SCMP_ACT_LOG, true);
709✔
240
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
709✔
241
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false);
709✔
242
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
709✔
243
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
709✔
244
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
709✔
245
                break;
709✔
246
        case 4:
1✔
247
                sys_set_seccomp_syscall(true);
1✔
248
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
1✔
249
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
1✔
250
                sys_set_seccomp_action(SCMP_ACT_LOG, true);
1✔
251
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
1✔
252
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true);
1✔
253
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
1✔
254
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
1✔
255
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
1✔
256
                break;
1✔
257
        case 5:
2✔
258
                sys_set_seccomp_syscall(true);
2✔
259
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
2✔
260
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
2✔
261
                sys_set_seccomp_action(SCMP_ACT_LOG, true);
2✔
262
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
2✔
263
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true);
2✔
264
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
2✔
265
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
2✔
266
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
2✔
267
                break;
2✔
268
        case 6:
1✔
269
                sys_set_seccomp_syscall(true);
1✔
270
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
1✔
271
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
1✔
272
                sys_set_seccomp_action(SCMP_ACT_LOG, true);
1✔
273
                sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
1✔
274
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true);
1✔
275
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
1✔
276
                sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
1✔
277
                sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true);
1✔
278
                break;
1✔
279
        default:
280
                return _rc_filter(-EINVAL);
724✔
281
        }
282

283
        seccomp_api_level = level;
723✔
284
        return _rc_filter(0);
723✔
285
}
286

287
/* NOTE - function header comment in include/seccomp.h */
288
API scmp_filter_ctx seccomp_init(uint32_t def_action)
7,604✔
289
{
290
        /* force a runtime api level detection */
291
        _seccomp_api_update();
7,604✔
292

293
        if (db_col_action_valid(NULL, def_action) < 0)
7,604✔
294
                return NULL;
295

296
        return db_col_init(def_action);
7,603✔
297
}
298

299
/* NOTE - function header comment in include/seccomp.h */
300
API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)
366✔
301
{
302
        struct db_filter_col *col = (struct db_filter_col *)ctx;
366✔
303

304
        /* a NULL filter context indicates we are resetting the global state */
305
        if (ctx == NULL) {
366✔
306
                /* reset the global state and redetermine the api level */
307
                sys_reset_state();
1✔
308
                _seccomp_api_update();
1✔
309
                return _rc_filter(0);
1✔
310
        }
311
        /* ensure the default action is valid */
312
        if (db_col_action_valid(NULL, def_action) < 0)
365✔
313
                return _rc_filter(-EINVAL);
366✔
314

315
        /* reset the filter */
316
        return _rc_filter(db_col_reset(col, def_action));
365✔
317
}
318

319
/* NOTE - function header comment in include/seccomp.h */
320
API void seccomp_release(scmp_filter_ctx ctx)
7,577✔
321
{
322
        db_col_release((struct db_filter_col *)ctx);
7,577✔
323
}
7,577✔
324

325
/* NOTE - function header comment in include/seccomp.h */
326
API int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src)
27✔
327
{
328
        struct db_filter_col *col_dst = (struct db_filter_col *)ctx_dst;
27✔
329
        struct db_filter_col *col_src = (struct db_filter_col *)ctx_src;
27✔
330

331
        if (db_col_valid(col_dst) || db_col_valid(col_src))
27✔
332
                return _rc_filter(-EINVAL);
1✔
333

334
        /* NOTE: only the default action, NNP, and TSYNC settings must match */
335
        if ((col_dst->attr.act_default != col_src->attr.act_default) ||
26✔
336
            (col_dst->attr.nnp_enable != col_src->attr.nnp_enable) ||
26✔
337
            (col_dst->attr.tsync_enable != col_src->attr.tsync_enable))
26✔
338
                return _rc_filter(-EINVAL);
27✔
339

340
        return _rc_filter(db_col_merge(col_dst, col_src));
26✔
341
}
342

343
/* NOTE - function header comment in include/seccomp.h */
344
API uint32_t seccomp_arch_resolve_name(const char *arch_name)
5,494✔
345
{
346
        const struct arch_def *arch;
5,494✔
347

348
        if (arch_name == NULL)
5,494✔
349
                return 0;
350

351
        arch = arch_def_lookup_name(arch_name);
5,494✔
352
        if (arch == NULL)
5,494✔
353
                return 0;
354

355
        return arch->token;
5,494✔
356
}
357

358
/* NOTE - function header comment in include/seccomp.h */
359
API uint32_t seccomp_arch_native(void)
1,387✔
360
{
361
        return arch_def_native->token;
1,387✔
362
}
363

364
/* NOTE - function header comment in include/seccomp.h */
365
API int seccomp_arch_exist(const scmp_filter_ctx ctx, uint32_t arch_token)
472✔
366
{
367
        struct db_filter_col *col = (struct db_filter_col *)ctx;
472✔
368

369
        if (arch_token == 0)
472✔
370
                arch_token = arch_def_native->token;
236✔
371

372
        if (arch_valid(arch_token))
472✔
373
                return _rc_filter(-EINVAL);
472✔
374

375
        return _rc_filter((db_col_arch_exist(col, arch_token) ? 0 : -EEXIST));
708✔
376
}
377

378
/* NOTE - function header comment in include/seccomp.h */
379
API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token)
8,440✔
380
{
381
        const struct arch_def *arch;
8,440✔
382
        struct db_filter_col *col = (struct db_filter_col *)ctx;
8,440✔
383

384
        if (arch_token == 0)
8,440✔
385
                arch_token = arch_def_native->token;
236✔
386

387
        arch = arch_def_lookup(arch_token);
8,440✔
388
        if (arch == NULL)
8,440✔
389
                return _rc_filter(-EINVAL);
8,440✔
390
        if (db_col_arch_exist(col, arch_token))
8,440✔
391
                return _rc_filter(-EEXIST);
8,440✔
392

393
        return _rc_filter(db_col_db_new(col, arch));
8,440✔
394
}
395

396
/* NOTE - function header comment in include/seccomp.h */
397
API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token)
4,019✔
398
{
399
        struct db_filter_col *col = (struct db_filter_col *)ctx;
4,019✔
400

401
        if (arch_token == 0)
4,019✔
402
                arch_token = arch_def_native->token;
1,659✔
403

404
        if (arch_valid(arch_token))
4,019✔
405
                return _rc_filter(-EINVAL);
4,019✔
406
        if (db_col_arch_exist(col, arch_token) != -EEXIST)
4,019✔
407
                return _rc_filter(-EEXIST);
4,019✔
408

409
        return _rc_filter(db_col_db_remove(col, arch_token));
4,019✔
410
}
411

412
/* NOTE - function header comment in include/seccomp.h */
413
API int seccomp_load(const scmp_filter_ctx ctx)
2✔
414
{
415
        struct db_filter_col *col;
2✔
416
        bool rawrc;
2✔
417

418
        if (_ctx_valid(ctx))
2✔
419
                return _rc_filter(-EINVAL);
2✔
420
        col = (struct db_filter_col *)ctx;
1✔
421

422
        rawrc = db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC);
1✔
423
        return _rc_filter(sys_filter_load(col, rawrc));
1✔
424
}
425

426
/* NOTE - function header comment in include/seccomp.h */
427
API int seccomp_attr_get(const scmp_filter_ctx ctx,
10✔
428
                         enum scmp_filter_attr attr, uint32_t *value)
429
{
430
        if (_ctx_valid(ctx))
10✔
431
                return _rc_filter(-EINVAL);
10✔
432

433
        return _rc_filter(db_col_attr_get((const struct db_filter_col *)ctx,
10✔
434
                                          attr, value));
435
}
436

437
/* NOTE - function header comment in include/seccomp.h */
438
API int seccomp_attr_set(scmp_filter_ctx ctx,
489✔
439
                         enum scmp_filter_attr attr, uint32_t value)
440
{
441
        if (_ctx_valid(ctx))
489✔
442
                return _rc_filter(-EINVAL);
489✔
443

444
        return _rc_filter(db_col_attr_set((struct db_filter_col *)ctx,
489✔
445
                                          attr, value));
446
}
447

448
/* NOTE - function header comment in include/seccomp.h */
449
API char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num)
14,063✔
450
{
451
        const struct arch_def *arch;
14,063✔
452
        const char *name;
14,063✔
453

454
        if (arch_token == 0)
14,063✔
455
                arch_token = arch_def_native->token;
2,505✔
456
        if (arch_valid(arch_token))
14,063✔
457
                return NULL;
458
        arch = arch_def_lookup(arch_token);
14,063✔
459
        if (arch == NULL)
14,063✔
460
                return NULL;
461

462
        name = arch_syscall_resolve_num(arch, num);
14,063✔
463
        if (name == NULL)
14,063✔
464
                return NULL;
465

466
        return strdup(name);
7,558✔
467
}
468

469
/* NOTE - function header comment in include/seccomp.h */
470
API int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name)
5,825✔
471
{
472
        const struct arch_def *arch;
5,825✔
473

474
        if (name == NULL)
5,825✔
475
                return __NR_SCMP_ERROR;
476

477
        if (arch_token == 0)
5,825✔
478
                arch_token = arch_def_native->token;
376✔
479
        if (arch_valid(arch_token))
5,825✔
480
                return __NR_SCMP_ERROR;
481
        arch = arch_def_lookup(arch_token);
5,825✔
482
        if (arch == NULL)
5,825✔
483
                return __NR_SCMP_ERROR;
484

485
        return arch_syscall_resolve_name(arch, name);
5,825✔
486
}
487

488
/* NOTE - function header comment in include/seccomp.h */
489
API int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token,
1,191✔
490
                                             const char *name)
491
{
492
        int rc;
1,191✔
493
        int syscall;
1,191✔
494
        const struct arch_def *arch;
1,191✔
495

496
        if (name == NULL)
1,191✔
497
                return __NR_SCMP_ERROR;
498

499
        if (arch_token == 0)
1,191✔
500
                arch_token = arch_def_native->token;
3✔
501
        if (arch_valid(arch_token))
1,191✔
502
                return __NR_SCMP_ERROR;
503
        arch = arch_def_lookup(arch_token);
1,191✔
504
        if (arch == NULL)
1,191✔
505
                return __NR_SCMP_ERROR;
506

507
        syscall = arch_syscall_resolve_name(arch, name);
1,191✔
508
        if (syscall == __NR_SCMP_ERROR)
1,191✔
509
                return __NR_SCMP_ERROR;
510
        rc = arch_syscall_rewrite(arch, &syscall);
1,191✔
511
        if (rc == -EDOM)
1,191✔
512
                /* if we can't rewrite the syscall, just pass it through */
513
                return syscall;
30✔
514
        else if (rc < 0)
1,161✔
515
                return __NR_SCMP_ERROR;
516

517
        return syscall;
1,161✔
518
}
519

520
/* NOTE - function header comment in include/seccomp.h */
521
API int seccomp_syscall_resolve_name(const char *name)
3✔
522
{
523
        return seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, name);
3✔
524
}
525

526
/* NOTE - function header comment in include/seccomp.h */
527
API int seccomp_syscall_priority(scmp_filter_ctx ctx,
70✔
528
                                 int syscall, uint8_t priority)
529
{
530
        struct db_filter_col *col = (struct db_filter_col *)ctx;
70✔
531

532
        if (db_col_valid(col) || _syscall_valid(col, syscall))
70✔
533
                return _rc_filter(-EINVAL);
70✔
534

535
        return _rc_filter(db_col_syscall_priority(col, syscall, priority));
68✔
536
}
537

538
/* NOTE - function header comment in include/seccomp.h */
539
API int seccomp_rule_add_array(scmp_filter_ctx ctx,
19,276✔
540
                               uint32_t action, int syscall,
541
                               unsigned int arg_cnt,
542
                               const struct scmp_arg_cmp *arg_array)
543
{
544
        int rc;
19,276✔
545
        struct db_filter_col *col = (struct db_filter_col *)ctx;
19,276✔
546

547
        if (arg_cnt > ARG_COUNT_MAX)
19,276✔
548
                return _rc_filter(-EINVAL);
19,276✔
549
        if (arg_cnt > 0 && arg_array == NULL)
19,276✔
550
                return _rc_filter(-EINVAL);
19,276✔
551

552
        if (db_col_valid(col) || _syscall_valid(col, syscall))
19,276✔
553
                return _rc_filter(-EINVAL);
19,276✔
554

555
        rc = db_col_action_valid(col, action);
19,275✔
556
        if (rc < 0)
19,275✔
557
                return _rc_filter(rc);
2✔
558
        if (action == col->attr.act_default)
19,273✔
559
                return _rc_filter(-EACCES);
19,276✔
560

561
        return _rc_filter(db_col_rule_add(col, 0, action,
19,272✔
562
                                          syscall, arg_cnt, arg_array));
563
}
564

565
/* NOTE - function header comment in include/seccomp.h */
566
API int seccomp_rule_add(scmp_filter_ctx ctx,
19,278✔
567
                         uint32_t action, int syscall,
568
                         unsigned int arg_cnt, ...)
569
{
570
        int rc;
19,278✔
571
        int iter;
19,278✔
572
        struct scmp_arg_cmp arg_array[ARG_COUNT_MAX];
19,278✔
573
        va_list arg_list;
19,278✔
574

575
        /* arg_cnt is unsigned, so no need to check the lower bound */
576
        if (arg_cnt > ARG_COUNT_MAX)
19,278✔
577
                return _rc_filter(-EINVAL);
19,278✔
578

579
        va_start(arg_list, arg_cnt);
19,276✔
580
        for (iter = 0; iter < arg_cnt; ++iter)
32,908✔
581
                arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp);
13,632✔
582
        rc = seccomp_rule_add_array(ctx, action, syscall, arg_cnt, arg_array);
19,276✔
583
        va_end(arg_list);
19,276✔
584

585
        return _rc_filter(rc);
19,276✔
586
}
587

588
/* NOTE - function header comment in include/seccomp.h */
589
API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
31,253✔
590
                                     uint32_t action, int syscall,
591
                                     unsigned int arg_cnt,
592
                                     const struct scmp_arg_cmp *arg_array)
593
{
594
        int rc;
31,253✔
595
        struct db_filter_col *col = (struct db_filter_col *)ctx;
31,253✔
596

597
        if (arg_cnt > ARG_COUNT_MAX)
31,253✔
598
                return _rc_filter(-EINVAL);
31,253✔
599
        if (arg_cnt > 0 && arg_array == NULL)
31,253✔
600
                return _rc_filter(-EINVAL);
31,253✔
601

602
        if (db_col_valid(col) || _syscall_valid(col, syscall))
31,253✔
603
                return _rc_filter(-EINVAL);
31,253✔
604

605
        rc = db_col_action_valid(col, action);
31,253✔
606
        if (rc < 0)
31,253✔
607
                return _rc_filter(rc);
1✔
608
        if (action == col->attr.act_default)
31,252✔
609
                return _rc_filter(-EACCES);
31,253✔
610

611
        if (col->filter_cnt > 1)
31,252✔
612
                return _rc_filter(-EOPNOTSUPP);
31,253✔
613

614
        return _rc_filter(db_col_rule_add(col, 1, action,
31,252✔
615
                                          syscall, arg_cnt, arg_array));
616
}
617

618
/* NOTE - function header comment in include/seccomp.h */
619
API int seccomp_rule_add_exact(scmp_filter_ctx ctx,
29,403✔
620
                               uint32_t action, int syscall,
621
                               unsigned int arg_cnt, ...)
622
{
623
        int rc;
29,403✔
624
        int iter;
29,403✔
625
        struct scmp_arg_cmp arg_array[ARG_COUNT_MAX];
29,403✔
626
        va_list arg_list;
29,403✔
627

628
        /* arg_cnt is unsigned, so no need to check the lower bound */
629
        if (arg_cnt > ARG_COUNT_MAX)
29,403✔
630
                return _rc_filter(-EINVAL);
29,403✔
631

632
        va_start(arg_list, arg_cnt);
29,403✔
633
        for (iter = 0; iter < arg_cnt; ++iter)
85,871✔
634
                arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp);
56,468✔
635
        rc = seccomp_rule_add_exact_array(ctx,
29,403✔
636
                                          action, syscall, arg_cnt, arg_array);
637
        va_end(arg_list);
29,403✔
638

639
        return _rc_filter(rc);
29,403✔
640
}
641

642
/* NOTE - function header comment in include/seccomp.h */
643
API int seccomp_notify_alloc(struct seccomp_notif **req,
3✔
644
                             struct seccomp_notif_resp **resp)
645
{
646
        /* force a runtime api level detection */
647
        _seccomp_api_update();
3✔
648

649
        return _rc_filter(sys_notify_alloc(req, resp));
3✔
650
}
651

652
/* NOTE - function header comment in include/seccomp.h */
653
API void seccomp_notify_free(struct seccomp_notif *req,
2✔
654
                             struct seccomp_notif_resp *resp)
655
{
656
        if (req)
2✔
657
                free(req);
1✔
658
        if (resp)
2✔
659
                free(resp);
1✔
660
}
2✔
661

662
/* NOTE - function header comment in include/seccomp.h */
663
API int seccomp_notify_receive(int fd, struct seccomp_notif *req)
1✔
664
{
665
        return _rc_filter(sys_notify_receive(fd, req));
1✔
666
}
667

668
/* NOTE - function header comment in include/seccomp.h */
669
API int seccomp_notify_respond(int fd, struct seccomp_notif_resp *resp)
1✔
670
{
671
        return _rc_filter(sys_notify_respond(fd, resp));
1✔
672
}
673

674
/* NOTE - function header comment in include/seccomp.h */
675
API int seccomp_notify_id_valid(int fd, uint64_t id)
1✔
676
{
677
        /* force a runtime api level detection */
678
        _seccomp_api_update();
1✔
679

680
        return _rc_filter(sys_notify_id_valid(fd, id));
1✔
681
}
682

683
/* NOTE - function header comment in include/seccomp.h */
684
API int seccomp_notify_fd(const scmp_filter_ctx ctx)
2✔
685
{
686
        /* NOTE: for historical reasons, and possibly future use, we require a
687
         * valid filter context even though we don't actual use it here; the
688
         * api update is also not strictly necessary, but keep it for now */
689

690
        /* force a runtime api level detection */
691
        _seccomp_api_update();
2✔
692

693
        if (_ctx_valid(ctx))
2✔
694
                return _rc_filter(-EINVAL);
2✔
695

696
        return _rc_filter(sys_notify_fd());
1✔
697
}
698

699
/* NOTE - function header comment in include/seccomp.h */
700
API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)
5✔
701
{
702
        int rc;
5✔
703
        struct db_filter_col *col;
5✔
704

705
        if (_ctx_valid(ctx))
5✔
706
                return _rc_filter(-EINVAL);
5✔
707
        col = (struct db_filter_col *)ctx;
4✔
708

709
        rc = gen_pfc_generate(col, fd);
4✔
710
        return _rc_filter_sys(col, rc);
4✔
711
}
712

713
/* NOTE - function header comment in include/seccomp.h */
714
API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
7,564✔
715
{
716
        int rc;
7,564✔
717
        struct db_filter_col *col;
7,564✔
718
        struct bpf_program *program;
7,564✔
719

720
        if (_ctx_valid(ctx))
7,564✔
721
                return _rc_filter(-EINVAL);
7,564✔
722
        col = (struct db_filter_col *)ctx;
7,563✔
723

724
        rc = gen_bpf_generate(col, &program);
7,563✔
725
        if (rc < 0)
7,563✔
726
                return _rc_filter(rc);
×
727
        rc = write(fd, program->blks, BPF_PGM_SIZE(program));
7,563✔
728
        gen_bpf_release(program);
7,563✔
729
        if (rc < 0)
7,563✔
730
                return _rc_filter_sys(col, -errno);
2✔
731

732
        return 0;
733
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc