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

drakenclimber / libseccomp / 16117087672

09 May 2025 07:24PM UTC coverage: 89.046% (-1.2%) from 90.252%
16117087672

push

github

pcmoore
build: add License variable to pkg-config file

The pkg-config file has License variable that allows you to set the license
for the software. This sets 'LGPL-2.1-only' as defined in SPDX to License.

Ref: https://github.com/pkgconf/pkgconf/blob/master/man/pc.5#L116
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
[PM: tweaked subj, line wrapping in description]
Signed-off-by: Paul Moore <paul@paul-moore.com>

3146 of 3533 relevant lines covered (89.05%)

256706.43 hits per line

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

80.69
/src/syscalls.c
1
/**
2
 * Enhanced Seccomp Syscall Table Functions
3
 *
4
 * Copyright (c) 2012, 2020 Red Hat <pmoore@redhat.com>
5
 * Author: Paul Moore <paul@paul-moore.com>
6
 * gperf support: Giuseppe Scrivano <gscrivan@redhat.com>
7
 */
8

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

23
#include <stdlib.h>
24
#include <errno.h>
25
#include <string.h>
26
#include <seccomp.h>
27

28
#include "db.h"
29
#include "arch.h"
30
#include "syscalls.h"
31

32
/**
33
 * Resolve a syscall name to a number
34
 * @param arch the arch definition
35
 * @param name the syscall name
36
 *
37
 * Resolve the given syscall name to the syscall number using the syscall table.
38
 * Returns the syscall number on success, including negative pseudo syscall
39
 * numbers; returns __NR_SCMP_ERROR on failure.
40
 *
41
 */
42
int abi_syscall_resolve_name_munge(const struct arch_def *arch,
79,761✔
43
                                   const char *name)
44
{
45

46
#define _ABI_SYSCALL_RES_NAME_CHK(NAME) \
47
        if (!strcmp(name, #NAME)) return __PNR_##NAME;
48

49
        _ABI_SYSCALL_RES_NAME_CHK(socket)
79,761✔
50
        _ABI_SYSCALL_RES_NAME_CHK(bind)
76,812✔
51
        _ABI_SYSCALL_RES_NAME_CHK(connect)
76,364✔
52
        _ABI_SYSCALL_RES_NAME_CHK(listen)
73,442✔
53
        _ABI_SYSCALL_RES_NAME_CHK(accept)
72,994✔
54
        _ABI_SYSCALL_RES_NAME_CHK(getsockname)
72,301✔
55
        _ABI_SYSCALL_RES_NAME_CHK(getpeername)
71,853✔
56
        _ABI_SYSCALL_RES_NAME_CHK(socketpair)
71,405✔
57
        _ABI_SYSCALL_RES_NAME_CHK(send)
70,957✔
58
        _ABI_SYSCALL_RES_NAME_CHK(recv)
70,509✔
59
        _ABI_SYSCALL_RES_NAME_CHK(sendto)
70,061✔
60
        _ABI_SYSCALL_RES_NAME_CHK(recvfrom)
69,613✔
61
        _ABI_SYSCALL_RES_NAME_CHK(shutdown)
69,165✔
62
        _ABI_SYSCALL_RES_NAME_CHK(setsockopt)
66,243✔
63
        _ABI_SYSCALL_RES_NAME_CHK(getsockopt)
65,795✔
64
        _ABI_SYSCALL_RES_NAME_CHK(sendmsg)
65,347✔
65
        _ABI_SYSCALL_RES_NAME_CHK(recvmsg)
64,899✔
66
        _ABI_SYSCALL_RES_NAME_CHK(accept4)
64,451✔
67
        _ABI_SYSCALL_RES_NAME_CHK(recvmmsg)
63,759✔
68
        _ABI_SYSCALL_RES_NAME_CHK(sendmmsg)
63,308✔
69
        _ABI_SYSCALL_RES_NAME_CHK(semop)
62,860✔
70
        _ABI_SYSCALL_RES_NAME_CHK(semget)
62,164✔
71
        _ABI_SYSCALL_RES_NAME_CHK(semctl)
61,468✔
72
        _ABI_SYSCALL_RES_NAME_CHK(semtimedop)
60,772✔
73
        _ABI_SYSCALL_RES_NAME_CHK(msgsnd)
60,076✔
74
        _ABI_SYSCALL_RES_NAME_CHK(msgrcv)
59,380✔
75
        _ABI_SYSCALL_RES_NAME_CHK(msgget)
58,684✔
76
        _ABI_SYSCALL_RES_NAME_CHK(msgctl)
57,988✔
77
        _ABI_SYSCALL_RES_NAME_CHK(shmat)
57,292✔
78
        _ABI_SYSCALL_RES_NAME_CHK(shmdt)
56,596✔
79
        _ABI_SYSCALL_RES_NAME_CHK(shmget)
55,900✔
80
        _ABI_SYSCALL_RES_NAME_CHK(shmctl)
55,204✔
81

82
        return arch->syscall_resolve_name_raw(name);
54,498✔
83
}
84

85
/**
86
 * Resolve a syscall number to a name
87
 * @param arch the arch definition
88
 * @param num the syscall number
89
 *
90
 * Resolve the given syscall number to the syscall name using the syscall table.
91
 * Returns a pointer to the syscall name string on success, including pseudo
92
 * syscall names; returns NULL on failure.
93
 *
94
 */
95
const char *abi_syscall_resolve_num_munge(const struct arch_def *arch, int num)
2,960✔
96
{
97

98
#define _ABI_SYSCALL_RES_NUM_CHK(NAME) \
99
        if (num == __PNR_##NAME) return #NAME;
100

101
        _ABI_SYSCALL_RES_NUM_CHK(socket)
2,960✔
102
        _ABI_SYSCALL_RES_NUM_CHK(bind)
10✔
103
        _ABI_SYSCALL_RES_NUM_CHK(connect)
10✔
104
        _ABI_SYSCALL_RES_NUM_CHK(listen)
10✔
105
        _ABI_SYSCALL_RES_NUM_CHK(accept)
10✔
106
        _ABI_SYSCALL_RES_NUM_CHK(getsockname)
10✔
107
        _ABI_SYSCALL_RES_NUM_CHK(getpeername)
10✔
108
        _ABI_SYSCALL_RES_NUM_CHK(socketpair)
10✔
109
        _ABI_SYSCALL_RES_NUM_CHK(send)
10✔
110
        _ABI_SYSCALL_RES_NUM_CHK(recv)
10✔
111
        _ABI_SYSCALL_RES_NUM_CHK(sendto)
10✔
112
        _ABI_SYSCALL_RES_NUM_CHK(recvfrom)
10✔
113
        _ABI_SYSCALL_RES_NUM_CHK(shutdown)
10✔
114
        _ABI_SYSCALL_RES_NUM_CHK(setsockopt)
10✔
115
        _ABI_SYSCALL_RES_NUM_CHK(getsockopt)
10✔
116
        _ABI_SYSCALL_RES_NUM_CHK(sendmsg)
10✔
117
        _ABI_SYSCALL_RES_NUM_CHK(recvmsg)
10✔
118
        _ABI_SYSCALL_RES_NUM_CHK(accept4)
10✔
119
        _ABI_SYSCALL_RES_NUM_CHK(recvmmsg)
10✔
120
        _ABI_SYSCALL_RES_NUM_CHK(sendmmsg)
10✔
121
        _ABI_SYSCALL_RES_NUM_CHK(semop)
10✔
122
        _ABI_SYSCALL_RES_NUM_CHK(semget)
10✔
123
        _ABI_SYSCALL_RES_NUM_CHK(semctl)
10✔
124
        _ABI_SYSCALL_RES_NUM_CHK(semtimedop)
10✔
125
        _ABI_SYSCALL_RES_NUM_CHK(msgsnd)
10✔
126
        _ABI_SYSCALL_RES_NUM_CHK(msgrcv)
10✔
127
        _ABI_SYSCALL_RES_NUM_CHK(msgget)
10✔
128
        _ABI_SYSCALL_RES_NUM_CHK(msgctl)
10✔
129
        _ABI_SYSCALL_RES_NUM_CHK(shmat)
10✔
130
        _ABI_SYSCALL_RES_NUM_CHK(shmdt)
10✔
131
        _ABI_SYSCALL_RES_NUM_CHK(shmget)
10✔
132
        _ABI_SYSCALL_RES_NUM_CHK(shmctl)
10✔
133

134
        return arch->syscall_resolve_num_raw(num);
2,640✔
135
}
136

137
/**
138
 * Check if a syscall is a socket syscall
139
 * @param arch the arch definition
140
 * @param sys the syscall number
141
 *
142
 * Returns true if the syscall is a socket related syscall, false otherwise.
143
 *
144
 */
145
static bool _abi_syscall_socket_test(const struct arch_def *arch, int sys)
76,668✔
146
{
147
        const char *name;
76,668✔
148

149
        /* multiplexed pseudo-syscalls */
150
        if (sys <= -100 && sys >= -120)
76,668✔
151
                return true;
152

153
        name = arch->syscall_resolve_num_raw(sys);
59,851✔
154
        if (!name)
59,851✔
155
                return false;
156

157
#define _ABI_SYSCALL_SOCK_CHK(NAME) \
158
        if (!strcmp(name, #NAME)) return true;
159

160
        _ABI_SYSCALL_SOCK_CHK(socket)
52,699✔
161
        _ABI_SYSCALL_SOCK_CHK(bind)
52,699✔
162
        _ABI_SYSCALL_SOCK_CHK(connect)
52,699✔
163
        _ABI_SYSCALL_SOCK_CHK(listen)
52,699✔
164
        _ABI_SYSCALL_SOCK_CHK(accept)
52,699✔
165
        _ABI_SYSCALL_SOCK_CHK(getsockname)
52,699✔
166
        _ABI_SYSCALL_SOCK_CHK(getpeername)
52,699✔
167
        _ABI_SYSCALL_SOCK_CHK(socketpair)
52,699✔
168
        _ABI_SYSCALL_SOCK_CHK(send)
52,699✔
169
        _ABI_SYSCALL_SOCK_CHK(recv)
52,699✔
170
        _ABI_SYSCALL_SOCK_CHK(sendto)
52,699✔
171
        _ABI_SYSCALL_SOCK_CHK(recvfrom)
52,699✔
172
        _ABI_SYSCALL_SOCK_CHK(shutdown)
52,699✔
173
        _ABI_SYSCALL_SOCK_CHK(setsockopt)
52,699✔
174
        _ABI_SYSCALL_SOCK_CHK(getsockopt)
52,699✔
175
        _ABI_SYSCALL_SOCK_CHK(sendmsg)
52,699✔
176
        _ABI_SYSCALL_SOCK_CHK(recvmsg)
52,699✔
177
        _ABI_SYSCALL_SOCK_CHK(accept4)
52,699✔
178
        _ABI_SYSCALL_SOCK_CHK(recvmmsg)
52,699✔
179
        _ABI_SYSCALL_SOCK_CHK(sendmmsg)
52,699✔
180

181
        return false;
182
}
183

184
/**
185
 * Check if a syscall is an ipc syscall
186
 * @param arch the arch definition
187
 * @param sys the syscall number
188
 *
189
 * Returns true if the syscall is an ipc related syscall, false otherwise.
190
 *
191
 */
192
static bool _abi_syscall_ipc_test(const struct arch_def *arch, int sys)
59,851✔
193
{
194
        const char *name;
59,851✔
195

196
        /* multiplexed pseudo-syscalls */
197
        if (sys <= -200 && sys >= -224)
59,851✔
198
                return true;
199

200
        name = arch->syscall_resolve_num_raw(sys);
51,499✔
201
        if (!name)
51,499✔
202
                return false;
203

204
#define _ABI_SYSCALL_IPC_CHK(NAME) \
205
        if (!strcmp(name, #NAME)) return true;
206

207
        _ABI_SYSCALL_IPC_CHK(semop)
51,499✔
208
        _ABI_SYSCALL_IPC_CHK(semget)
51,499✔
209
        _ABI_SYSCALL_IPC_CHK(semctl)
51,499✔
210
        _ABI_SYSCALL_IPC_CHK(semtimedop)
51,499✔
211
        _ABI_SYSCALL_IPC_CHK(msgsnd)
51,499✔
212
        _ABI_SYSCALL_IPC_CHK(msgrcv)
51,499✔
213
        _ABI_SYSCALL_IPC_CHK(msgget)
51,499✔
214
        _ABI_SYSCALL_IPC_CHK(msgctl)
51,499✔
215
        _ABI_SYSCALL_IPC_CHK(shmat)
51,499✔
216
        _ABI_SYSCALL_IPC_CHK(shmdt)
51,499✔
217
        _ABI_SYSCALL_IPC_CHK(shmget)
51,499✔
218
        _ABI_SYSCALL_IPC_CHK(shmctl)
51,499✔
219

220
        return false;
221
}
222

223
/**
224
 * Convert a multiplexed pseudo syscall into a direct syscall
225
 * @param arch the arch definition
226
 * @param syscall the multiplexed pseudo syscall number
227
 *
228
 * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
229
 * no related syscall, or __NR_SCMP_ERROR otherwise.
230
 *
231
 */
232
static int _abi_syscall_demux(const struct arch_def *arch, int syscall)
25,168✔
233
{
234
        int sys = __NR_SCMP_UNDEF;
25,168✔
235

236
#define _ABI_SYSCALL_DEMUX_CHK(NAME) \
237
case __PNR_##NAME: \
238
        sys = arch->syscall_resolve_name_raw(#NAME); break;
239

240
        switch (syscall) {
25,168✔
241
                _ABI_SYSCALL_DEMUX_CHK(socket)
2,928✔
242
                _ABI_SYSCALL_DEMUX_CHK(bind)
448✔
243
                _ABI_SYSCALL_DEMUX_CHK(connect)
2,920✔
244
                _ABI_SYSCALL_DEMUX_CHK(listen)
448✔
245
                _ABI_SYSCALL_DEMUX_CHK(accept)
664✔
246
                _ABI_SYSCALL_DEMUX_CHK(getsockname)
448✔
247
                _ABI_SYSCALL_DEMUX_CHK(getpeername)
448✔
248
                _ABI_SYSCALL_DEMUX_CHK(socketpair)
448✔
249
                _ABI_SYSCALL_DEMUX_CHK(send)
448✔
250
                _ABI_SYSCALL_DEMUX_CHK(recv)
448✔
251
                _ABI_SYSCALL_DEMUX_CHK(sendto)
448✔
252
                _ABI_SYSCALL_DEMUX_CHK(recvfrom)
448✔
253
                _ABI_SYSCALL_DEMUX_CHK(shutdown)
2,920✔
254
                _ABI_SYSCALL_DEMUX_CHK(setsockopt)
448✔
255
                _ABI_SYSCALL_DEMUX_CHK(getsockopt)
448✔
256
                _ABI_SYSCALL_DEMUX_CHK(sendmsg)
448✔
257
                _ABI_SYSCALL_DEMUX_CHK(recvmsg)
448✔
258
                _ABI_SYSCALL_DEMUX_CHK(accept4)
664✔
259
                _ABI_SYSCALL_DEMUX_CHK(recvmmsg)
448✔
260
                _ABI_SYSCALL_DEMUX_CHK(sendmmsg)
448✔
261
                _ABI_SYSCALL_DEMUX_CHK(semop)
696✔
262
                _ABI_SYSCALL_DEMUX_CHK(semget)
696✔
263
                _ABI_SYSCALL_DEMUX_CHK(semctl)
696✔
264
                _ABI_SYSCALL_DEMUX_CHK(semtimedop)
696✔
265
                _ABI_SYSCALL_DEMUX_CHK(msgsnd)
696✔
266
                _ABI_SYSCALL_DEMUX_CHK(msgrcv)
696✔
267
                _ABI_SYSCALL_DEMUX_CHK(msgget)
696✔
268
                _ABI_SYSCALL_DEMUX_CHK(msgctl)
696✔
269
                _ABI_SYSCALL_DEMUX_CHK(shmat)
696✔
270
                _ABI_SYSCALL_DEMUX_CHK(shmdt)
696✔
271
                _ABI_SYSCALL_DEMUX_CHK(shmget)
696✔
272
                _ABI_SYSCALL_DEMUX_CHK(shmctl)
696✔
273
        }
274

275
        /* this looks odd because the arch resolver returns _ERROR if it can't
276
         * resolve the syscall, but we want to use _UNDEF for that, so we set
277
         * 'sys' to a sentinel value of _UNDEF and if it is error here we know
278
         * the resolve failed to find a match */
279
        if (sys == __NR_SCMP_UNDEF)
25,168✔
280
                sys = __NR_SCMP_ERROR;
281
        else if (sys == __NR_SCMP_ERROR)
25,168✔
282
                sys = __NR_SCMP_UNDEF;
×
283

284
        return sys;
25,168✔
285
}
286

287
/**
288
 * Convert a direct syscall into multiplexed pseudo socket syscall
289
 * @param arch the arch definition
290
 * @param syscall the direct syscall
291
 *
292
 * Return the related multiplexed pseudo syscall number, __NR_SCMP_UNDEF is
293
 * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
294
 *
295
 */
296
static int _abi_syscall_mux(const struct arch_def *arch, int syscall)
×
297
{
298
        const char *sys;
×
299

300
        sys = arch->syscall_resolve_num_raw(syscall);
×
301
        if (!sys)
×
302
                return __NR_SCMP_ERROR;
303

304
#define _ABI_SYSCALL_MUX_CHK(NAME) \
305
        if (!strcmp(sys, #NAME)) return __PNR_##NAME;
306

307
        _ABI_SYSCALL_MUX_CHK(socket)
×
308
        _ABI_SYSCALL_MUX_CHK(bind)
×
309
        _ABI_SYSCALL_MUX_CHK(connect)
×
310
        _ABI_SYSCALL_MUX_CHK(listen)
×
311
        _ABI_SYSCALL_MUX_CHK(accept)
×
312
        _ABI_SYSCALL_MUX_CHK(getsockname)
×
313
        _ABI_SYSCALL_MUX_CHK(getpeername)
×
314
        _ABI_SYSCALL_MUX_CHK(socketpair)
×
315
        _ABI_SYSCALL_MUX_CHK(send)
×
316
        _ABI_SYSCALL_MUX_CHK(recv)
×
317
        _ABI_SYSCALL_MUX_CHK(sendto)
×
318
        _ABI_SYSCALL_MUX_CHK(recvfrom)
×
319
        _ABI_SYSCALL_MUX_CHK(shutdown)
×
320
        _ABI_SYSCALL_MUX_CHK(setsockopt)
×
321
        _ABI_SYSCALL_MUX_CHK(getsockopt)
×
322
        _ABI_SYSCALL_MUX_CHK(sendmsg)
×
323
        _ABI_SYSCALL_MUX_CHK(recvmsg)
×
324
        _ABI_SYSCALL_MUX_CHK(accept4)
×
325
        _ABI_SYSCALL_MUX_CHK(recvmmsg)
×
326
        _ABI_SYSCALL_MUX_CHK(sendmmsg)
×
327
        _ABI_SYSCALL_MUX_CHK(semop)
×
328
        _ABI_SYSCALL_MUX_CHK(semget)
×
329
        _ABI_SYSCALL_MUX_CHK(semctl)
×
330
        _ABI_SYSCALL_MUX_CHK(semtimedop)
×
331
        _ABI_SYSCALL_MUX_CHK(msgsnd)
×
332
        _ABI_SYSCALL_MUX_CHK(msgrcv)
×
333
        _ABI_SYSCALL_MUX_CHK(msgget)
×
334
        _ABI_SYSCALL_MUX_CHK(msgctl)
×
335
        _ABI_SYSCALL_MUX_CHK(shmat)
×
336
        _ABI_SYSCALL_MUX_CHK(shmdt)
×
337
        _ABI_SYSCALL_MUX_CHK(shmget)
×
338
        _ABI_SYSCALL_MUX_CHK(shmctl)
×
339

340
        return __NR_SCMP_ERROR;
341
}
342

343
/**
344
 * Rewrite a syscall value to match the architecture
345
 * @param arch the arch definition
346
 * @param syscall the syscall number
347
 *
348
 * Syscalls can vary across different architectures so this function rewrites
349
 * the syscall into the correct value for the specified architecture.  Returns
350
 * zero on success, negative values on failure.
351
 *
352
 */
353
int abi_syscall_rewrite(const struct arch_def *arch, int *syscall)
86✔
354
{
355
        int sys = *syscall;
86✔
356

357
        if (sys <= -100 && sys >= -120)
86✔
358
                *syscall = arch->sys_socketcall;
76✔
359
        else if (sys <= -200 && sys >= -224)
10✔
360
                *syscall = arch->sys_ipc;
10✔
361
        else if (sys < 0)
×
362
                return -EDOM;
363

364
        return 0;
365
}
366

367
/**
368
 * add a new rule to the abi seccomp filter
369
 * @param db the seccomp filter db
370
 * @param rule the filter rule
371
 *
372
 * This function adds a new syscall filter to the seccomp filter db, making any
373
 * necessary adjustments for the abi ABI.  Returns zero on success, negative
374
 * values on failure.
375
 *
376
 * It is important to note that in the case of failure the db may be corrupted,
377
 * the caller must use the transaction mechanism if the db integrity is
378
 * important.
379
 *
380
 */
381
int abi_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
76,668✔
382
{
383
        int rc = 0;
76,668✔
384
        unsigned int iter;
76,668✔
385
        int sys = rule->syscall;
76,668✔
386
        int sys_a, sys_b;
76,668✔
387
        struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
76,668✔
388

389
        if (_abi_syscall_socket_test(db->arch, sys)) {
76,668✔
390
                /* socket syscalls */
391

392
                /* strict check for the multiplexed socket syscalls */
393
                for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
117,713✔
394
                        if ((rule->args[iter].valid != 0) && (rule->strict)) {
100,897✔
395
                                rc = -EINVAL;
1✔
396
                                goto add_return;
1✔
397
                        }
398
                }
399

400
                /* determine both the muxed and direct syscall numbers */
401
                if (sys > 0) {
16,816✔
402
                        sys_a = _abi_syscall_mux(db->arch, sys);
×
403
                        if (sys_a == __NR_SCMP_ERROR) {
×
404
                                rc = __NR_SCMP_ERROR;
×
405
                                goto add_return;
×
406
                        }
407
                        sys_b = sys;
408
                } else {
409
                        sys_a = sys;
16,816✔
410
                        sys_b = _abi_syscall_demux(db->arch, sys);
16,816✔
411
                        if (sys_b == __NR_SCMP_ERROR) {
16,816✔
412
                                rc = __NR_SCMP_ERROR;
×
413
                                goto add_return;
×
414
                        }
415
                }
416

417
                /* use rule_a for the multiplexed syscall and use rule_b for
418
                 * the direct wired syscall */
419

420
                if (sys_a == __NR_SCMP_UNDEF) {
16,816✔
421
                        rule_a = NULL;
422
                        rule_b = rule;
423
                } else if (sys_b == __NR_SCMP_UNDEF) {
16,816✔
424
                        rule_a = rule;
425
                        rule_b = NULL;
426
                } else {
427
                        /* need two rules, dup the first and link together */
428
                        rule_a = rule;
16,816✔
429
                        rule_dup = db_rule_dup(rule_a);
16,816✔
430
                        rule_b = rule_dup;
16,816✔
431
                        if (rule_b == NULL)
16,816✔
432
                                goto add_return;
×
433
                        rule_b->prev = rule_a;
16,816✔
434
                        rule_b->next = NULL;
16,816✔
435
                        rule_a->next = rule_b;
16,816✔
436
                }
437

438
                /* multiplexed socket syscalls */
439
                if (rule_a != NULL) {
16,816✔
440
                        rule_a->syscall = db->arch->sys_socketcall;
16,816✔
441
                        rule_a->args[0].arg = 0;
16,816✔
442
                        rule_a->args[0].op = SCMP_CMP_EQ;
16,816✔
443
                        rule_a->args[0].mask = DATUM_MAX;
16,816✔
444
                        rule_a->args[0].datum = (-sys_a) % 100;
16,816✔
445
                        rule_a->args[0].valid = 1;
16,816✔
446
                }
447

448
                /* direct wired socket syscalls */
449
                if (rule_b != NULL)
16,816✔
450
                        rule_b->syscall = sys_b;
16,816✔
451

452
                /* we should be protected by a transaction checkpoint */
453
                if (rule_a != NULL) {
16,816✔
454
                        rc = db_rule_add(db, rule_a);
16,816✔
455
                        if (rc < 0)
16,816✔
456
                                goto add_return;
×
457
                }
458
                if (rule_b != NULL) {
16,816✔
459
                        rc = db_rule_add(db, rule_b);
16,816✔
460
                        if (rc < 0)
16,816✔
461
                                goto add_return;
462
                }
463
        } else if (_abi_syscall_ipc_test(db->arch, sys)) {
59,851✔
464
                /* ipc syscalls */
465

466
                /* strict check for the multiplexed socket syscalls */
467
                for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
58,464✔
468
                        if ((rule->args[iter].valid != 0) && (rule->strict)) {
50,112✔
469
                                rc = -EINVAL;
×
470
                                goto add_return;
×
471
                        }
472
                }
473

474
                /* determine both the muxed and direct syscall numbers */
475
                if (sys > 0) {
8,352✔
476
                        sys_a = _abi_syscall_mux(db->arch, sys);
×
477
                        if (sys_a == __NR_SCMP_ERROR) {
×
478
                                rc = __NR_SCMP_ERROR;
×
479
                                goto add_return;
×
480
                        }
481
                        sys_b = sys;
482
                } else {
483
                        sys_a = sys;
8,352✔
484
                        sys_b = _abi_syscall_demux(db->arch, sys);
8,352✔
485
                        if (sys_b == __NR_SCMP_ERROR) {
8,352✔
486
                                rc = __NR_SCMP_ERROR;
×
487
                                goto add_return;
×
488
                        }
489
                }
490

491
                /* use rule_a for the multiplexed syscall and use rule_b for
492
                 * the direct wired syscall */
493

494
                if (sys_a == __NR_SCMP_UNDEF) {
8,352✔
495
                        rule_a = NULL;
496
                        rule_b = rule;
497
                } else if (sys_b == __NR_SCMP_UNDEF) {
8,352✔
498
                        rule_a = rule;
499
                        rule_b = NULL;
500
                } else {
501
                        /* need two rules, dup the first and link together */
502
                        rule_a = rule;
8,352✔
503
                        rule_dup = db_rule_dup(rule_a);
8,352✔
504
                        rule_b = rule_dup;
8,352✔
505
                        if (rule_b == NULL)
8,352✔
506
                                goto add_return;
×
507
                        rule_b->prev = rule_a;
8,352✔
508
                        rule_b->next = NULL;
8,352✔
509
                        rule_a->next = rule_b;
8,352✔
510
                }
511

512
                /* multiplexed socket syscalls */
513
                if (rule_a != NULL) {
8,352✔
514
                        rule_a->syscall = db->arch->sys_ipc;
8,352✔
515
                        rule_a->args[0].arg = 0;
8,352✔
516
                        rule_a->args[0].op = SCMP_CMP_EQ;
8,352✔
517
                        rule_a->args[0].mask = DATUM_MAX;
8,352✔
518
                        rule_a->args[0].datum = (-sys_a) % 200;
8,352✔
519
                        rule_a->args[0].valid = 1;
8,352✔
520
                }
521

522
                /* direct wired socket syscalls */
523
                if (rule_b != NULL)
8,352✔
524
                        rule_b->syscall = sys_b;
8,352✔
525

526
                /* we should be protected by a transaction checkpoint */
527
                if (rule_a != NULL) {
8,352✔
528
                        rc = db_rule_add(db, rule_a);
8,352✔
529
                        if (rc < 0)
8,352✔
530
                                goto add_return;
×
531
                }
532
                if (rule_b != NULL) {
8,352✔
533
                        rc = db_rule_add(db, rule_b);
8,352✔
534
                        if (rc < 0)
8,352✔
535
                                goto add_return;
536
                }
537
        } else if (sys >= 0) {
51,499✔
538
                /* normal syscall processing */
539
                rc = db_rule_add(db, rule);
50,446✔
540
                if (rc < 0)
50,446✔
541
                        goto add_return;
542
        } else if (rule->strict) {
1,053✔
543
                rc = -EDOM;
351✔
544
                goto add_return;
351✔
545
        }
546

547
add_return:
702✔
548
        if (rule_dup != NULL)
25,520✔
549
                free(rule_dup);
25,168✔
550
        return rc;
76,668✔
551
}
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

© 2026 Coveralls, Inc