$ sudo add-apt-repository ppa:paelzer/bug-1830859-with-proposed-seccomp
or
$ sudo add-apt-repository ppa:paelzer/bug-1830859-without-proposed-seccomp
# add main/debug and enable the deb-src in the PPA sources
Hrm ??
equal qemu source
Good:
Breakpoint 1 at 0x4d63f4: file ./qemu-seccomp.c, line 293.
Bad:
Breakpoint 1 at 0x4d63f4: qemu_seccomp. (2 location
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x00000000004d63f4 in qemu_seccomp at ./qemu-seccomp.c:293
1.2 y 0x00000000004d656e in qemu_seccomp at ./qemu-seccomp.c:244
Now the second hit isn't an actual qemu_seccomp call, but it is very close to the error that we get reported.
(gdb) l qemu-seccomp.c:293
288
289 #if defined(SECCOMP_FILTER_FLAG_TSYNC)
290 int check;
291
292 /* check host TSYNC capability, it returns errno == ENOSYS if unavailable */
293 check = qemu_seccomp(SECCOMP_SET_MODE_FILTER,
294 SECCOMP_FILTER_FLAG_TSYNC, NULL);
295 if (check < 0 && errno == EFAULT) {
296 add = true;
297 }
(gdb) l qemu-seccomp.c:244
239 error_setg(errp, "invalid argument for resourcecontrol");
240 return -1;
241 }
242 }
243
244 if (seccomp_start(seccomp_opts) < 0) {
245 error_setg(errp, "failed to install seccomp syscall filter "
246 "in the kernel");
247 return -1;
248 }
Well maybe with seccomp 2.4 development headers something changed and this now gets inlined?
That is not an error, but suspicious.
qemu_seccomp should ALWAYS be inlined
static inline __attribute__((unused)) int
qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
The one at line 293 is at seccomp_register and depends on #if defined(SECCOMP_FILTER_FLAG_TSYNC).
This one is active in both cases.
But the one at line 244 is part of qemu_seccomp_get_kill_action
That has some checks as well being:
#if defined(SECCOMP_GET_ACTION_AVAIL) && \
defined(SCMP_ACT_KILL_PROCESS) && \
defined(SECCOMP_RET_KILL_PROCESS)
There is no other way to "avoid" the path of
parse_sandbox -> seccomp_start -> qemu_seccomp_get_kill_action -> qemu_seccomp
in terms of precompiler.
Both have CONFIG_SECCOMP set, so it might really come down to the three checks above.
Reading the commit [1] that added this to qemu seems to match the current theories.
Lets see what happens when it tries to use things buildt with 2.4 but without 2.4 being installed at runtime.
The returned value for action is matching expected /usr/include/seccomp.h numbers:
- good case => 196608 ==> SCMP_ACT_TRAP = 0x00030000U
- bad case => 2147483648 ==> SCMP_ACT_KILL_PROCESS = 0x80000000U
As a summary:
- the libseccomp-dev 2.4 headers being installed at build time
- code can detect now the availability of SCMP_ACT_KILL_PROCESS
- code might decide to use SCMP_ACT_KILL_PROCESS
- if code runs without libseccomp2 2.4 installed it breaks
For qemu I could patch out the usage of SCMP_ACT_KILL_PROCESS, but:
- that is stupid as it is preferred if available
- the question is either
- how can we make such rebuilds pick up the dependency correctly
- could we runtime (instead of compile time) detect if SCMP_ACT_KILL_PROCESS is available
Two Disco containers (one per PPA)
$ sudo add-apt-repository ppa:paelzer/bug-1830859-with-proposed- seccomp proposed- seccomp
or
$ sudo add-apt-repository ppa:paelzer/bug-1830859-without-
# add main/debug and enable the deb-src in the PPA sources
$ sudo apt install gdb qemu-system-x86 qemu-system- x86-dbgsym dpkg-dev
$ apt source qemu
$ cd qemu-3.1+dfsg/
break on qemu_seccomp
Hrm ?? seccomp. c:293 seccomp. c:244
equal qemu source
Good:
Breakpoint 1 at 0x4d63f4: file ./qemu-seccomp.c, line 293.
Bad:
Breakpoint 1 at 0x4d63f4: qemu_seccomp. (2 location
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x00000000004d63f4 in qemu_seccomp at ./qemu-
1.2 y 0x00000000004d656e in qemu_seccomp at ./qemu-
Now the second hit isn't an actual qemu_seccomp call, but it is very close to the error that we get reported.
(gdb) l qemu-seccomp.c:293 SECCOMP_ FILTER_ FLAG_TSYNC) SECCOMP_ SET_MODE_ FILTER, FILTER_ FLAG_TSYNC, NULL); start(seccomp_ opts) < 0) {
288
289 #if defined(
290 int check;
291
292 /* check host TSYNC capability, it returns errno == ENOSYS if unavailable */
293 check = qemu_seccomp(
294 SECCOMP_
295 if (check < 0 && errno == EFAULT) {
296 add = true;
297 }
(gdb) l qemu-seccomp.c:244
239 error_setg(errp, "invalid argument for resourcecontrol");
240 return -1;
241 }
242 }
243
244 if (seccomp_
245 error_setg(errp, "failed to install seccomp syscall filter "
246 "in the kernel");
247 return -1;
248 }
Well maybe with seccomp 2.4 development headers something changed and this now gets inlined?
That is not an error, but suspicious.
qemu_seccomp should ALWAYS be inlined
static inline __attribute_ _((unused) ) int unsigned int operation, unsigned int flags, void *args)
qemu_seccomp(
The one at line 293 is at seccomp_register and depends on #if defined( SECCOMP_ FILTER_ FLAG_TSYNC) .
This one is active in both cases.
But the one at line 244 is part of qemu_seccomp_ get_kill_ action SECCOMP_ GET_ACTION_ AVAIL) && \ SCMP_ACT_ KILL_PROCESS) && \ SECCOMP_ RET_KILL_ PROCESS)
That has some checks as well being:
#if defined(
defined(
defined(
There is no other way to "avoid" the path of get_kill_ action -> qemu_seccomp
parse_sandbox -> seccomp_start -> qemu_seccomp_
in terms of precompiler.
Both have CONFIG_SECCOMP set, so it might really come down to the three checks above.
Reading the commit [1] that added this to qemu seems to match the current theories.
Lets see what happens when it tries to use things buildt with 2.4 but without 2.4 being installed at runtime.
The returned value for action is matching expected /usr/include/ seccomp. h numbers: KILL_PROCESS = 0x80000000U
- good case => 196608 ==> SCMP_ACT_TRAP = 0x00030000U
- bad case => 2147483648 ==> SCMP_ACT_
As a summary: KILL_PROCESS KILL_PROCESS
- the libseccomp-dev 2.4 headers being installed at build time
- code can detect now the availability of SCMP_ACT_
- code might decide to use SCMP_ACT_
- if code runs without libseccomp2 2.4 installed it breaks
For qemu I could patch out the usage of SCMP_ACT_ KILL_PROCESS, but: KILL_PROCESS is available
- that is stupid as it is preferred if available
- the question is either
- how can we make such rebuilds pick up the dependency correctly
- could we runtime (instead of compile time) detect if SCMP_ACT_
[1]: https:/ /git.qemu. org/?p= qemu.git; a=commit; h=bda08a5764d