Repository navigation
a seccomp fix regarding ugetrlimit/prlimit64 - #6952
Conversation
tixxdz
left a comment
There was a problem hiding this comment.
Patch 1 lgtm, small fixes for patch 2.
There was a problem hiding this comment.
Did you let these inside @privileged set on purpose ? they should be removed from that set or at least have a way to import the @chown into @privileged and let the syscalls opencoded in one place. However, for backward compatibility, capabilities should cover this so removing them from @privileged should be ok.
P.S. will post patches to add logic to auto import a set into another one soon for the abstracted sandbox model.
There was a problem hiding this comment.
you are right, @privileged should just import this group. will fix.
There was a problem hiding this comment.
Maybe prefix this set with fs-sync or file-system-sync ?
There was a problem hiding this comment.
dunno if that's necessary... This is in the context of syscalls after all, and in syscalls the name "sync" is clear enough i think.
53148d0 to
697b2cc
Compare
|
I force pushed a new version now, that ports Please have another look! |
|
lgtm, thank you! |
|
The underlying reason seems to be trouble with starting a container: Hmm, other PRs don't seem to fail in this way. The failure could be related to changes in this PR. I'll restart CI. |
697b2cc to
48c77a7
Compare
|
CI failed again, with a similar issue. Not grokking it. The only effective difference in the seccomp lists is that ugetrlimit is added to nspawn's default whitelist. Which is a syscall that doesn't exist on x86-64. most likely there's something wrong with the handling of that missing syscall in libseccomp or so. I tried to figure out why that doesn#t fail here though... nothing really changed with handling of that syscall in libseccomp recently afaics (but i only had a cursory look). i force pushed a new version now that conditions out them item, if libseccomp doesn't explicitly define a pseudo syscall nr for ugetrlimit. maybe that fixes it. otherwise i have no real idea.. i am puzzled. anyone? |
|
@tixxdz btw, could you dissmiss your negative review, so that github is happy? |
topimiettinen
left a comment
There was a problem hiding this comment.
Commit message: igetrlimit should be ugetrlimit.
|
Bisect: |
|
So...
only amd64 fails with "upstream FAIL timed out"
fails with a "merge conflict"
fails with a "merge conflict"
fails on "boot-and-services" and "upstream", but only on amd64 and i386 It seems something is off, but we can't bisect because the CI is unreliable. |
|
Hmm, or maybe it is not related since we should be able to handle that from our seccomp logic... ?! |
|
So, my educated guess is that libseccomp (at least in its debian/ubuntu version) gets confused by references to geturlimit on archs that don't have it. I am tempted to add an ugly hack for it, to work around this. But first, let's see if @pcmoore has an idea about that? Are you aware of any recent issues with handling of ugetrlimit() in libseccomp? specifically, if we reference it on x86-64 even though it doesn't exist there? Normally, libseccomp should of course isolate us from issues like that... |
48c77a7 to
3f719ab
Compare
|
so, i force pushed a new, rebased version now. It also contains a hackish commit that skips adding geturlimit on archs that aren't arm of i386. If that fixes the tests for this everything points to a libseccomp issue |
|
bummer. that didn't work either... i have no clue |
3f719ab to
2e09a8f
Compare
|
So I split this PR into two bits now: this PR shall only be about the getrlimit/ugetrlimit/prlimit64 issue. And there's now #6999 for the rest. Given that the new additions are kind unrelated to the ugetrlimit thing, let's do this in two PRs. And now I am curious whether we can make the two PRs pass CI... |
|
Without digging through all of the systemd seccomp code, can someone explain the problem beyond "ugetrlimit is acting funny on some ABIs"? Bonus points if you can show me the libseccomp calls ;) |
|
I think the following patch should "fix" the issue: --- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -337,10 +337,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"lseek\0"
"pread64\0"
"preadv\0"
- "preadv2\0"
"pwrite64\0"
"pwritev\0"
- "pwritev2\0"
"read\0"
"readv\0"
"write\0" |
|
The patch above has just enabled me to successfully run By the way, I'm not sure I understand why almost all the errors in |
|
If ignoring errors is really needed, diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index 5f3d7d9..48e0af9 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -852,15 +852,12 @@ static int seccomp_add_syscall_filter_set(
char **exclude) {
const char *sys;
- int r;
assert(seccomp);
assert(set);
NULSTR_FOREACH(sys, set->value) {
- r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude);
- if (r < 0)
- return r;
+ (void) seccomp_add_syscall_filter_item(seccomp, sys, action, exclude);
}
return 0; |
iirc libseccomp doesn't define clear error codes in some cases where we really want to ignore errors, specifically if we add a syscall to a filter that doesn't actually exist on the arch of the filter. and because we can't detect this case we instead check for cases where we know the error as relevant and something to propagate. We should really rework this one day when libseccomp documents error codes, so that we only eat up errors we really want to ignore |
Also, move prlimit64() out of @resources. prlimit64() may be used both for getting and setting resource limits, and is implicitly called by glibc at various places, on some archs, the same was as getrlimit(). SImilar, igetrlimit() is an arch-specific replacement for getrlimit(), and hence should be whitelisted at the same place as getrlimit() and prlimit64(). Also see: https://lists.freedesktop.org/archives/systemd-devel/2017-September/039543.html
When a libseccomp implementation doesn't know a syscall yet, that's no reason for us to fail completely. Instead, debug log, and proceed. This hopefully fixes the preadv2/pwritev2 issues pointed out here: systemd#6952 (comment)
Unfortunately libseccomp doesn't return (nor document) clean error codes, hence until then only check for specific error codes that we propagate, but ignore (but debug log) all others. Do this at one more place, we are already doing that at all others.
…rule_add_exact() System calls might exist on some archs but not on others, or might be multiplexed but not on others. Ignore such errors when putting together a filter at this location like we already do it on all others.
2e09a8f to
448ac52
Compare
|
OK, another try, incorporating what @evverx: we need to ignore more errors... @pcmoore so, as it turns out the getrlimit thing was misleading and a false alarm. Sorry for the noise. That said, is there any chance we can get clean, documented error codes from libseccomp functions? i.e. what is returned in which cases? that would be great, so that we can make libseccomp failing fatal... |
| return r; | ||
| if (r < 0) | ||
| log_debug_errno(r, "Failed to restrict system call architectures, skipping: %m"); | ||
|
|
There was a problem hiding this comment.
I am bit concerned about ignoring errors here, if users tried to explicitly set it then and we ignore other architectures then those calls can be used to bypass the native architecture. Maybe turn these debug messages into warnings ? at least users can act on that ?
There was a problem hiding this comment.
yeah, it sucks, but there's little we can do until libseccomp reports proper errors back we can match against. There are cases we validly want to ignore errors and cases where we shouldn't. right now we propagate only EPERM/EACCESS as we know under which conditions those are generated. We should invert this all of course, but we can't as long as we don't have any error codes to check for.
Specifically, we want to at least ignore issues regarding:
- syscall doesn't exist on some arch
- syscall cannot matched on some arch (because multiplexed, think socket/socketcall)
and there are some more, but as long as we can't detect these properly we don't really have any realistic option than to ignore most, but propagate only the ones we know aren't OK.
There was a problem hiding this comment.
btw, do note that this PR doesn't really change much in this regard, in just adjusts one utlier to match what all the other invocations of seccomp_load() do here. Reworking the error handling of our seccomp_load() calls certainly should be revisited but probably later on, and then for all cases at once.
|
nice! the CI completed! |
That would be great, because it is currently impossible to predict what |
No worries. Glad you got everything working, even more glad it wasn't my fault ;)
It's on the todo list (I'm pretty sure there is a GH issue somewhere...), I've just got a lot of things on my plate at the moment. |
|
I opened a new issue 97 for libseccomp as the problem didn't seem to match existing issues. |
|
still an issue on Fedora 27 and systemd-234-10.git5f8984e.fc27.x86_64 as soon as you add |
No description provided.