phyto's ramblings

Seccomp Syscall Debugging

Finding blocked syscalls that are missing from a seccomp whitelist

Step 1: Realise that program crashes whenever you apply the random whitelist you found online

Step 2: Cry, give up and do nothing for checks time about 4 months

Step 3: Get an unreasonable bout of confidence and use it within the 6 or so hours you have until you get bored

Listing the syscalls

strace needs to be used like this:

bwrap strace nheko

and not like this

strace bwrap nheko

The latter will strace bwrap but not the actual program, and I eventually learnt this the hard way.

So just change your bwrap script (here called bnheko) to include a strace, and then run it like bnheko 2> bnheko-strace.txt. This leaves you with a fairly large (8.2M) file. Most of these are duplicates and come with arguments that we can filter out using this patented 1-liner sed "s/(.*//" <bnheko-strace.txt | sort -u | uniq > bnheko-syscalls.txt.

Remember to forget to use the -l flag that nheko has like a moron and spend a minute or two filtering out all the stuff nheko printed to stderr from your new bnheko-syscalls.txt file. If you want to, also filter out all the stuff that’s not really a syscall, but that step is optional.

Now you have a nice 90-or-so line file of syscalls, yay!

Filtering them

At this stage, forget that grep exists, and write 30 or so odd lines of Lua to find things that are in the syscall list but not in the whitelist. Make sure you are also too lazy to actually take these two files as separate things so concatenate them and take them both in through stdin, seperated with the literal string “EOF\n”.

Oooooooor, just use grep like grep -f whitelist.seccomp bnheko-syscalls.txt (where whitelist.seccomp is a file in the kicksecure script format), and look at all lines that aren’t a 100% match. We end up with:

clone3
ioctl
mmap
mprotect
rseq
shmat
socket

These are all the syscalls that nheko made, but aren’t in the whitelist.

If you’d actually filtered out the arguments from the whitelist.seccomp file first like a good girl then you’d know that ioctl, mmap, mprotect, shmat and socket are all whitelisted but have restrictions on the arguments (like to enforce W^X with mmap).

This means only clone3 and rseq remain. clone3 is just clone with fancy dress (and clone is just fork with glasses), and rseq is something something mutex structs parralelism atomic userspace kernel mmmnnnnyyyaaaaaaaah (∪。∪)。。。 zzZ.

Confirm nheko isn’t just weird

Do the entire thing again with another program like to double check you aren’t going crazy, and it’s not your weird nheko patches that are breaking things.

Almost every program I tested used both clone3 and rseq:

hmmmm yeah it looks a lot like these are probably a part of some common library. It’s probably glibc’s fault, wouldn’t be the first time it breaks seccomp filters either.

Interestingly weechat (cli irc client) uses rseq but not clone3. When it doesn’t have rseq weechat spits out an error on launche fifo: unable to create pipe for remote control (/run/user/1000/weechat/weechat_fifo_2): error 10 No child processes but otherwise it works fine strangely.

Harrass Ask thankless maintainers

The person who made the whitelist is madaidan, a knowledgable and respected security person who contributes to whonix and sometimes writes stuff. I don’t expect him to respond, but I messaged him to let him know about this.

It’s important to mention this to upstream, both because they might have a very good reason for not including these syscalls, and they may want to also inculde them in their own lists.

It’s likely that the whitelist and associated scripts aren’t being used anymore and are unmaintained, which explains how it got so out of date. But the github (ew) repo isn’t archived, so I figured it might as well be worth doing anyway.

Either way, I got no response, so it looks like we are on our own.

Punch organised holes in the wall

clone3 doesn’t seem like a weird syscall, and someone else added it to their whitelist, so it’s probably fine to add to my own however it has been explicitly blacklisted in flatpak for reasons beyond my attention span. If you can, make it cause an ENOSYS1, which should make glibc fall back to using clone.

rseq does seem a little weird, and I don’t understand it even more than clone3, so it’s worth doing some digging online. When a google for "resq" security returns nothing relevant, and you can’t find any CVEs for it, then it’s probably fine.

Remember that even if these are really insecure, it’s still not a loss to add them to the whitelist, because most things aren’t using any whitelist at all right now. So throw them on, recompile the bpf files, and now everything should work with whitelist-wx.bpf, and some things with whitelist.bpf. Just keep in mind that seccomp filters are not magic bullets.

– 2024-04-12: Noted that clone3 was blocked by flatpak, and specified that seccomp filters are not magic bullets


  1. ENOSYS means “Function not implemented” - errno(3) ↩︎