Hola,
En primer lugar, gracias por libseccomp: lo hemos estado usando felizmente en producción durante varios años y no hemos tenido ningún problema (hasta ahora). No estoy seguro de si esto es un error en nuestro código, un malentendido de la documentación o algo más, pero pasé el mes pasado tratando de rastrear esto en vano.
Recientemente actualizamos los paquetes en nuestros contenedores Docker, que incluyeron una actualización de libseccomp 2.3.3 (versión en repositorios estables de Debian) a 2.4.3. Hubo otros paquetes del sistema que también se actualizaron, pero no los registré. Nuestro kernel no se actualizó y es la versión 4.19.0-8-amd64.
Usamos SCMP_ACT_TRACE
, y construimos un filtro que consta solo de reglas SCMP_ACT_ALLOW
que se agregan usando números de llamada al sistema nativos, en lugar de los pseudo-números de libseccomp. Bifurcamos un proceso auxiliar de 64 bits que construye y carga el filtro seccomp antes de exec
-ing otro binario de 64 bits.
Como referencia, esta es la totalidad de nuestra rutina de inicialización seccomp, utilizando una verificación de errores similar a la de la página de manual seccomp_rule_add
.
Sin embargo, nuestra llamada a seccomp_load
ha comenzado a devolver -EINVAL
, del orden de magnitud de 1 / 100.000 inicializaciones de proceso. (No poder reproducirlo de manera confiable ha hecho que la depuración sea tediosa). No hubo cambios en el código de nuestra aplicación durante este tiempo. Las llamadas al sistema agregadas al filtro son idénticas en todas las ejecuciones.
¿Alguna idea sobre lo que podría estar saliendo mal (o incluso cómo profundizar más en lo que va mal), o si esto se espera de alguna manera? No hay muchas partes móviles dinámicas y no pude encontrar nada en la documentación sobre por qué podría estar sucediendo esto.
Hola @Xyene ,
No hay muchos lugares que devuelvan -EINVAL en la ruta del código seccomp_load (). Basado en un examen rápido del código libseccomp v2.4.3, parece que se debe a un scmp_filter_ctx
inválido o al kernel quejándose de la llamada prctl(...)
que carga el filtro.
Teniendo en cuenta que v2.4.3 generalmente funciona, y no ha cambiado su kernel, parece dudoso que la llamada prctl(...)
sea la causa que nos lleva a un contexto de filtro no válido. ¿Ha notado algún otro comportamiento extraño en su programa desde la actualización? Me pregunto si hay un problema de corrupción de memoria en otro lugar que está causando el problema.
Si bien siempre es posible que la falla esté en libseccomp, ejecutamos cada versión a través de una serie de verificaciones que incluyen ejecuciones de valgrind para todas nuestras pruebas de regresión, así como análisis estático usando clang y Coverity.
Además, aunque esto no ayuda para la v2.4.3, una de las mejoras a las que nos dirigimos para la versión v2.5.0 casi lista es la mejora de la documentación y el manejo de los códigos de error.
Recientemente actualizamos los paquetes en nuestros contenedores Docker, que incluyeron una actualización de libseccomp 2.3.3 (versión en repositorios estables de Debian) a 2.4.3. Hubo otros paquetes del sistema que también se actualizaron, pero no los registré. Nuestro kernel no se actualizó y es la versión 4.19.0-8-amd64.
Gracias por verificar que su código y el kernel subyacente no han cambiado. Eso debería ayudar a localizar el problema.
Como referencia, esta es la totalidad de nuestra rutina de inicialización seccomp, utilizando una verificación de errores similar a la de la página de manual
seccomp_rule_add
.
Tu filtro me parece razonable.
¿Alguna idea sobre lo que podría estar saliendo mal (o incluso cómo profundizar más en lo que va mal), o si esto se espera de alguna manera? No hay muchas partes móviles dinámicas y no pude encontrar nada en la documentación sobre por qué podría estar sucediendo esto.
Revisé el código v2.4.3 seccomp_load()
, y creo que solo hay dos lugares donde libseccomp genera un código de retorno de -EINVAL
:
seccomp_load()
en la línea 283_gen_bpf_build_bpf()
en la línea 1657Los dos errores anteriores son causados efectivamente por un filtro no válido. Eso me parece poco probable basado en su código de filtro.
Vale la pena señalar que el valor de retorno predeterminado del kernel en seccomp_set_mode_filter()
es -EINVAL
, por lo que es posible que algo más en el sistema haya cambiado, lo que nos lleva a caer en ese camino. Mencionas que estás ejecutando en Docker; ¿Está deshabilitando el filtro seccomp de Docker predeterminado?
Me sentiría tentado a agregar más depuración a su código dentro del if after seccomp_load()
falla. Por ejemplo, podríamos generar el PFC y / o el BPF del propio filtro para verificar que parezca razonable. Consulte seccomp_export_pfc()
y seccomp_export_bpf()
.
Revisé el código v2.4.3
seccomp_load()
, y creo que solo hay dos lugares donde libseccomp genera un código de retorno de-EINVAL
:
seccomp_load()
en la línea 283_gen_bpf_build_bpf()
en la línea 1657
Tenga en cuenta que cualquier falla encontrada en gen_bpf_generate(...)
, o por debajo, se combina efectivamente en -ENOMEM por sys_filter_load(...)
en src / system.c: 267 .
¡Odio volver a la "corrupción de la memoria"! muy rápido, pero parece que ese puede ser el caso aquí.
¡Gracias por las respuestas rápidas y detalladas! Han generado varias vías de exploración: mild_smiling_face:
¿Ha notado algún otro comportamiento extraño en su programa desde la actualización? Me pregunto si hay un problema de corrupción de memoria en otro lugar que está causando el problema.
No, solo esto. Nuestras pruebas de unidad e integración continúan pasando, y aparte de este EINVAL
muy raro, no se registran errores en prod. Esto ciertamente lo hace desconcertante; También sospeché corrupción de la memoria, pero no he podido encontrar ninguna evidencia que lo respalde :ligeramente_frowning_face:
Para un poco más de contexto:
seccomp_init
etc.Mientras escribía esto, tuve una idea: he escuchado historias de terror acerca de que malloc
no es seguro de usar después de la bifurcación, y tenemos algunas dentro de libseccomp. La aplicación de Python en sí _es_ multiproceso, pero siempre mantenemos el GIL mientras está en código nativo, por lo que esto debería ser seguro (?). Sin embargo, solo he oído hablar de interbloqueos que ocurren a través de malloc-after-fork. (Supongo que esto hace que el siguiente orden del día se mueva seccomp_init
et al. Antes de la bifurcación, solo llamando a seccomp_load
post-fork y viendo si los errores siguen ocurriendo).
Me sentiría tentado a agregar más depuración a su código dentro del if after seccomp_load () falla.
¡Gracias por la sugerencia! Agregué una llamada a seccomp_export_pfc
, además de descargar el contenido de la entrada al filtro ( config->syscall_whitelist
). Haré un seguimiento la próxima vez que esto falle.
Hola @Xyene : ya que ha pasado aproximadamente una semana, solo quería verificar y ver si hay algo nuevo que hayas encontrado.
Desafortunadamente, todavía no. Después de agregar un parche a seccomp_export_pfc
, se ha guardado silencio. Ayer envié ese parche a todas nuestras máquinas virtuales (en lugar de solo una de prueba) con la esperanza de capturar el problema cuando finalmente ocurra.
Me parece extraño el silencio, pero por ahora lo atribuyo a una coincidencia, ya que toda la lógica de depuración / exportación ocurre _después_ de fallar seccomp_load
, por lo que no debería afectar la falla en sí.
¡Progreso!
Resulta que la razón por la que ha estado en silencio es porque seccomp_export_bpf
estaba segfaulting (¿debería, si se llama después de seccomp_load
?), Y eso se informó en otro lugar y no donde estaba buscando fallas de seccomp. Más importante aún, me encontré con un caso en el que puedo reproducir de manera confiable el problema en ~ 150 invocaciones, por lo que con un poco de trabajo de plomería debería poder extraer algunos volcados de núcleo.
Muy bien, saqué un volcado de núcleo y este fue el rastro: https://gist.github.com/Xyene/920f1cb098784a031f53c66a2f49d167
Esto fue un poco sospechoso, ya que está fallando dentro de la rutina realloc
jemalloc. Además, el uso de glibc malloc resuelve el problema (desafortunadamente, no es una opción a largo plazo en este caso debido a problemas de fragmentación).
A continuación, extraje jemalloc, lo compilé con -O0
y símbolos de depuración, y volví a ejecutar la reproducción. ¡Esta vez se estrelló en seccomp_load
, en lugar de después! He subido ese rastro aquí: https://gist.github.com/Xyene/5da56168bcea337da85b2cd30704d12e
Un fragmento de ese rastro:
#9 0x00007ff962698495 in free (ptr=0x5a5a5a5a5a5a5a5a) at src/jemalloc.c:2867
No locals.
#10 0x00007ff96062d087 in _program_free (prg=prg@entry=0x7ff95e963010) at gen_bpf.c:511
No locals.
#11 0x00007ff96062f605 in gen_bpf_release (program=program@entry=0x7ff95e963010) at gen_bpf.c:1986
No locals.
#12 0x00007ff96062c04f in sys_filter_load (col=col@entry=0x7ff95e9a5000) at system.c:293
rc = -1
prgm = 0x7ff95e963010
#13 0x00007ff96062b666 in seccomp_load (ctx=ctx@entry=0x7ff95e9a5000) at api.c:286
col = 0x7ff95e9a5000
Al buscar en jemalloc, parece que 0x5a
se usa para marcar los bytes libres como libres , con la intención específica de bloquear el código que intenta liberar algo que ya se ha liberado.
gen_bpf.c:511
en v2.4.3 es: https://github.com/seccomp/libseccomp/blob/1dde9d94e0848e12da20602ca38032b91d521427/src/gen_bpf.c#L505 -L513
Pero esto no tiene mucho sentido ya que la duración del programa es solo el cuerpo de sys_filter_load
:
Creo que he detectado al menos un problema. En gen_bpf_generate
;
state.bpf = prgm
siempre que zmalloc
no falle. A continuación, se llama a _gen_bpf_build_bpf
y, basándose en su rc
, state.bpf
se establece en NULL
.
Teniendo en cuenta el caso en el que rc != 0
, state.bpf
todavía se establece en prgm
en el momento de la llamada a _state_release
. Esto hará que se libere la memoria apuntada por prgm
.
A continuación, gen_bpf_generate
será return prgm
, que a pesar de haber sido liberado, sigue siendo un puntero distinto de cero.
De vuelta en sys_filter_load
, gen_bpf_generate
devuelve, y prgm
no es- NULL
por lo que continúa.
Finalmente, al final de sys_filter_load
, se llama a gen_bpf_release
en el prgm
ya libre.
Esto no aborda la preocupación de por qué _gen_bpf_build_bpf
fallaría en primer lugar, pero parece algo malo que podría suceder si lo hiciera.
Editar: en realidad, parece que probablemente se corrigió como un efecto secundario de https://github.com/seccomp/libseccomp/commit/3a1d1c977065f204b96293cccfe7d3e5aa0d7ace.
Teniendo en cuenta el caso en el que rc! = 0, state.bpf todavía está configurado en prgm en el momento de la llamada a _state_release. Esto hará que se libere la memoria apuntada por prgm.
¡Ah, ja! ¡Buen partido @Xyene!
Creo que tenemos que arreglar esto más allá de 3a1d1c977065f204b96293cccfe7d3e5aa0d7ace, déjame pensar en esto por un minuto ... No creo que la solución sea demasiado difícil ... y ver si puedo llegar a un PR.
Creo que tenemos que arreglar esto más allá de 3a1d1c9, déjame pensar en esto por un minuto ... No creo que la solución sea demasiado difícil ... y ver si puedo llegar a un PR.
Vaya, estaba mirando el código antiguo cuando escribí eso; sí, creo que 3a1d1c9 nos arregla esto, pero necesitaremos un parche para la rama de la versión 2.4. Trabajaré en eso ahora.
_ (Meta: Continuaré actualizando este mensaje con mis hallazgos a medida que avanzo, así que tengo un lugar para escribirlos sin enviarles correos electrónicos no deseados:) _
Muy bien, de vuelta en 2.4.3 con el parche aplicado, pude sacar el filtro que estaba fallando: enlace .
La causa informada ahora es ENOMEM
lugar de EINVAL
, que supongo que se espera dado que _gen_bpf_build_bpf
está fallando y devuelve un programa NULL
. Sin embargo, el PFC se imprime bien. Modificar el código seccomp para informar el valor de retorno de _gen_bpf_build_bpf
muestra EFAULT
como la causa.
Como un truco rápido, ejecuté :%s/return -EFAULT/abort()
sobre src/gen_bpf.c
, y pude extraer este rastro de pila:
Stacktrace de EFAULT
(gdb) bt full
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {__val = {0, 140084028365964, 140083248439464, 140083248438968, 140083248431088, 140084028368143, 28659884033, 140083965300736,
140083248439464, 140083248438968, 140083248431088, 140084028351031, 140084019988760, 140083248439624, 140083248431200, 140084028372597}}
pid = <optimized out>
tid = <optimized out>
ret = <optimized out>
#1 0x00007f67daa4d55b in __GI_abort () at abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x7f67d6f3eec0, sa_sigaction = 0x7f67d6f3eec0}, sa_mask = {__val = {140083965300736,
140083965300736, 0, 0, 140083248438968, 140083248438968, 140083248439464, 140083248431504, 140084028417173, 140083964793344,
140083965300736, 140083248431552, 140083994791895, 140083248431552, 140083994787642, 140083965300736}}, sa_flags = -1404894496,
sa_restorer = 0x0}
sigs = {__val = {32, 0 <repeats 15 times>}}
#2 0x00007f67d8bfd455 in _gen_bpf_build_bpf (state=0x7f67ac4302e0, col=0x7f67d6f63040) at gen_bpf.c:1943
rc = 0
iter = 1
h_val = 1425818561
res_cnt = 0
jmp_len = 0
arch_x86_64 = 0
arch_x32 = -1
instr = {op = 32, jt = {tgt = {imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, jf = {tgt = {
imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, k = {tgt = {imm_j = 4 '\004', imm_k = 4,
hash = 4, db = 0x4, blk = 0x4, nxt = 4}, type = TGT_K}}
i_iter = 0x7f67d6fdcb60
b_badarch = 0x7f67d6fd9000
b_default = 0x7f67d6fd9060
b_head = 0x7f67d6fda1a0
b_tail = 0x7f67d6fd9000
b_iter = 0x0
b_new = 0x7f67d6fe3300
b_jmp = 0x0
db_secondary = 0x0
pseudo_arch = {token = 0, token_bpf = 0, size = ARCH_SIZE_UNSPEC, endian = ARCH_ENDIAN_LITTLE, syscall_resolve_name = 0x0,
syscall_resolve_num = 0x0, syscall_rewrite = 0x0, rule_add = 0x0}
#3 0x00007f67d8bfd560 in gen_bpf_generate (col=0x7f67d6f63040) at gen_bpf.c:1971
rc = 0
state = {htbl = {0x0 <repeats 256 times>}, attr = 0x7f67d6f63044, bad_arch_hsh = 889798935, def_hsh = 742199527, arch = 0x7f67ac4301e0,
bpf = 0x7f67d6f64010}
prgm = 0x7f67d6f64010
#4 0x00007f67d8bf64a7 in sys_filter_load (col=0x7f67d6f63040) at system.c:265
rc = 32615
prgm = 0x0
#5 0x00007f67d8bf4f10 in seccomp_load (ctx=0x7f67d6f63040) at api.c:287
col = 0x7f67d6f63040
Eso corresponde con la línea 1943:
Dada la naturaleza del reemplazo, creo que podemos excluir cualquier EFAULT
en cualquier función auxiliar, ya que se habrían abortado primero.
Después de esto, intenté reproducir lo mismo con HEAD; todavía sucede. A continuación, %s:/goto build_bpf_free_blks/abort()
y repita. La causa fue:
Afortunadamente, esta función era corta y solo tenía un puñado de puntos de falla. Otra ronda de inserciones abort
más tarde;
Rastro
(gdb) bt full
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {__val = {0, 140050183343588, 0, 448, 140049402494880, 140049402509040, 140049402494832, 140050183342988, 140049402495088,
140049402509040, 140049402494896, 140050183343588, 4294967296, 140049402509040, 140049402509040, 140049402509040}}
pid = <optimized out>
tid = <optimized out>
ret = <optimized out>
#1 0x00007f5ff953055b in __GI_abort () at abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x7f5ff595d260, sa_sigaction = 0x7f5ff595d260}, sa_mask = {__val = {139642271694862,
140050119389792, 0, 0, 140049402502840, 0, 140049402503336, 140049402502888, 140049402502840, 112, 384, 140049402502840, 140050149861504,
140049402495328, 140050149857273, 392}}, sa_flags = 448, sa_restorer = 0x7f5ff595d240}
sigs = {__val = {32, 0 <repeats 15 times>}}
#2 0x00007f5ff76edee5 in _bpf_append_blk (prg=0x7f5ff5964010, blk=0x7f5ff59df1a0) at gen_bpf.c:452
rc = -12
i_new = 0x0
i_iter = 0x7f5ff59fa178
old_cnt = 48
iter = 1
#3 0x00007f5ff76f3716 in _gen_bpf_build_bpf (state=0x7f5fcae302d0, col=0x7f5ff59c5000) at gen_bpf.c:2223
rc = 0
iter = 1
h_val = 1425818561
res_cnt = 0
jmp_len = 0
arch_x86_64 = 0
arch_x32 = -1
instr = {op = 32, jt = {tgt = {imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, jf = {tgt = {
imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, k = {tgt = {imm_j = 4 '\004', imm_k = 4,
hash = 4, db = 0x4, blk = 0x4, nxt = 4}, type = TGT_K}}
i_iter = 0x7f5ff59e1b60
b_badarch = 0x7f5ff59de000
b_default = 0x7f5ff59de060
b_head = 0x7f5ff59df1a0
b_tail = 0x7f5ff59de000
b_iter = 0x7f5ff59df1a0
b_new = 0x7f5ff59e8300
b_jmp = 0x7f5ff59df0e0
db_secondary = 0x0
pseudo_arch = {token = 0, token_bpf = 0, size = ARCH_SIZE_UNSPEC, endian = ARCH_ENDIAN_LITTLE, syscall_resolve_name = 0x0,
syscall_resolve_num = 0x0, syscall_rewrite = 0x0, rule_add = 0x0}
#4 0x00007f5ff76f3874 in gen_bpf_generate (col=0x7f5ff59c5000, prgm_ptr=0x7f5fcae30b40) at gen_bpf.c:2270
rc = 0
state = {htbl = {0x0, 0x7f5ff593ef80, 0x7f5ff593efe0, 0x7f5ff593efc0, 0x0, 0x7f5ff595d000, 0x7f5ff593ef60, 0x7f5ff593ef00,
0x0 <repeats 248 times>}, attr = 0x7f5ff59c5004, bad_arch_hsh = 889798935, def_hsh = 742199527, bpf = 0x7f5ff5964010,
arch = 0x7f5fcae301c0, b_head = 0x7f5ff59e8300, b_tail = 0x7f5ff59de120, b_new = 0x7f5ff59e8300}
prgm = <optimized out>
#5 0x00007f5ff76eb275 in sys_filter_load (col=0x7f5ff59c5000, rawrc=false) at system.c:307
rc = 0
prgm = 0x0
#6 0x00007f5ff76e9505 in seccomp_load (ctx=0x7f5ff59c5000) at api.c:386
col = 0x7f5ff59c5000
rawrc = false
Entonces es realloc
fallando nuevamente, y _bpf_append_blk
devuelve -ENOMEM
que se enmascara por _gen_bpf_build_bpf
y se convierte en -EFAULT
. Esto no es un gran problema, pero como dijiste que un mejor informe de errores es un objetivo de 2.5, pensé que lo mencionaría ya que parece dentro del alcance:
Algunos pinchando con GDB:
(gdb) f 2
#2 0x00007f5ff76edee5 in _bpf_append_blk (prg=0x7f5ff5964010, blk=0x7f5ff59df1a0) at gen_bpf.c:452
452 abort();
(gdb) info args
prg = 0x7f5ff5964010
blk = 0x7f5ff59df1a0
(gdb) print prg->blks
$4 = (bpf_instr_raw *) 0x7f5ff59fa000
(gdb) x/32bx &prg->blks
0x7f5ff5964018: 0x00 0xa0 0x9f 0xf5 0x5f 0x7f 0x00 0x00
0x7f5ff5964020: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
0x7f5ff5964028: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
0x7f5ff5964030: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(gdb) print ((prg)->blk_cnt * sizeof(*((prg)->blks)))
$5 = 392
(gdb) print prg->blk_cnt
$6 = 49
Este realmente comienza a verse como una falla en el asignador ...
Ajá, esta historia finalmente ha llegado a su _ emocionante_ conclusión: descubrí lo que ha estado sucediendo y verifiqué una solución: levemente_sonriente_cara:
Como podría ser una historia interesante, aquí está:
El proceso principal que bifurca al trabajador generalmente se encuentra en ~ 80mb RSS. Después de que se bifurca, restringe el uso de la memoria a través de rlimit
, a veces a 64 MB. Esto lo coloca en una posición en la que su uso de memoria actual excede su límite, pero esto está permitido por rlimit
. La mayoría de las veces, el asignador de memoria tendrá suficiente memoria libre disponible para dar servicio a las rutinas de inicialización de libseccomp sin solicitar más del kernel. Pero cuando _no lo hace_, y necesita solicitar espacio para una arena adicional o algo así, el kernel no lo proporcionará ya que el proceso ya está por encima de su límite.
En 2.4.3, esta falla en la obtención de memoria se manifestó en EINVAL
y un doble libre. En la publicación maestra: https://github.com/seccomp/libseccomp/commit/3a1d1c977065f204b96293cccfe7d3e5aa0d7ace , se informa EFAULT
su lugar. Con https://github.com/seccomp/libseccomp/pull/257 aplicado, ENOMEM
se informa correctamente.
La razón por la que esto sucede tan raramente se vuelve obvia: depende completamente de si el asignador tiene suficiente memoria para construir el programa BPF sin solicitar más del kernel. El asignador de glibc es más flexible acerca de permitir que se acumule la fragmentación, por lo que esto nunca sucedió con él en su lugar. jemalloc establece límites más estrictos y conduce a una mayor probabilidad de necesitar solicitar memoria durante seccomp_load
, lo suficiente para notar las fallas resultantes, pero aún así es exasperante rastrear.
La solución, entonces, es simplemente mover todas las llamadas setrlimit
a _after_ seccomp_load
. Al hacerlo, realloc
ya no falla en _bpf_append_blk
y el filtro se carga correctamente. Esto significa que el filtro debe permitir setrlimit
, pero en mi caso esto fue aceptable. De manera más general, creo que este problema se resolvería con algo como https://github.com/seccomp/libseccomp/issues/123.
@pcmoore , @drakenclimber : ¡gracias de nuevo por toda su ayuda para depurar este problema! Me alegro de poder dejarlo atrás ahora, pero sus consejos fueron invaluables para llegar allí: smiley:
Este error se solucionó mediante el compromiso https://github.com/seccomp/libseccomp/commit/c0a6e6fd15f74c429a0b74e0dfd4de5a29aabebd
Comentario más útil
Desafortunadamente, todavía no. Después de agregar un parche a
seccomp_export_pfc
, se ha guardado silencio. Ayer envié ese parche a todas nuestras máquinas virtuales (en lugar de solo una de prueba) con la esperanza de capturar el problema cuando finalmente ocurra.Me parece extraño el silencio, pero por ahora lo atribuyo a una coincidencia, ya que toda la lógica de depuración / exportación ocurre _después_ de fallar
seccomp_load
, por lo que no debería afectar la falla en sí.