Fixing SECCOMP filter stacking
robert at ocallahan.org
Wed Nov 26 12:36:47 PST 2014
I've landed on master changes to build 32-bit tests alongside 64-bit tests
when you build rr 64-bit. The CMake changes are klugy; CMake associates
build flags with source files, so I hack around that by copying the test
source files to objdir/32 and then setting 32-bit builds flags on those
"generated" source files. We also build a 32-bit version of librrpreload in
a similar way.
I've also landed some changes that make recording and replaying 32-bit
tracees with 64-bit rr work for most of the simple tests. There are a
number of bugs remaining that I'm working through. Although I don't think
debugging 32-bit tracees with rr will be very common, I think it's worth
ensuring that 32-bit tests pass with 64-bit rr to catch regressions in
32-bit support from rr developers using 64-bit builds.
One interesting problem I've run into is that SECCOMP filters persist
across exec. After each exec, librrpreload adds a new SECCOMP filter to the
list of current filters for the process, and all of these filters are
evaluated until one returns a status other than "allow". Normally this
isn't a problem (except potentially a perf problem, since for an untraced
syscall every filter will be executed), since every filter returns the same
result, since the untraced-syscall address is the same in every tracee
address space. But when a 32-bit process execs a 64-bit process (or vice
versa) we have two different filters on the list, each one checking if the
program counter is at a different untraced-syscall address. That means our
untraced syscall triggers a ptrace trap since it doesn't match the
untraced-syscall address for the other architecture.
There are a couple of possible ways to fix this. One would be to extend the
filter with an architecture check so syscalls coming from the "wrong"
architecture are always allowed. That doesn't solve the potential perf
problem from accumulating a long chain of filters after a long chain of
execs. The other way is to have rr choose a fixed address for the untraced
syscall when we spawn the first tracee, and after every exec mmap a page at
that address (whatever the architecture) and store an untraced-syscall code
sequence in it. Then rr can set up a single SECCOMP when we spawn the first
oIo otoeololo oyooouo otohoaoto oaonoyooonoeo owohooo oioso oaonogoroyo
owoiotoho oao oboroootohoeoro oooro osoiosotoeoro owoiololo oboeo
osouobojoeocoto otooo ojouodogomoeonoto.o oAogoaoiono,o oaonoyooonoeo
osoaoyoso otooo oao oboroootohoeoro oooro osoiosotoeoro,o o‘oRoaocoao,o’o
oaonosowoeoroaoboloeo otooo otohoeo ocooouoroto.o oAonodo oaonoyooonoeo
osoaoyoso,o o‘oYooouo ofooooolo!o’o owoiololo oboeo oiono odoaonogoeoro
otohoeo ofoioroeo ooofo ohoeololo.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the rr-dev