Libseccomp: RFE: extender el soporte de SCMP_FLTATR_API_SYSRAWRC a la API de notificación

Creado en 13 nov. 2020  ·  5Comentarios  ·  Fuente: seccomp/libseccomp

La implementación de seccomp_notify_receive() solo usa:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0)
                return -ECANCELED;

Independientemente del error en errno , devuelve -ECANCELED .

Al depurar con strace, descubrí que ioctl devolvía EINTR debido a la señal SIGURG:

1448850 ioctl(7, SECCOMP_IOCTL_NOTIF_RECV <unfinished ...>
1448230 getpid()                        = 1448217
1448230 tgkill(1448217, 1448850, SIGURG) = 0
1448850 <... ioctl resumed>, 0x7fc65d49ecd0) = -1 EINTR (Interrupted system call)

La señal SIGURL es generada por el tiempo de ejecución de Golang, consulte los detalles en https://go-review.googlesource.com/c/go/+/232862/
De acuerdo con ese informe, la llamada al sistema solo debe volver a emitirse al obtener EINTR.
Idealmente, libseccomp debería encargarse de eso, para que sea transparente para los usuarios.

Como solución alternativa, traté de volver a emitir la llamada al sistema llamando a seccomp_notify_receive() en mi programa y hacer lo mismo en seccomp_notify_respond() porque tiene el mismo patrón:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0)
                return -ECANCELED;

Pero a veces obtengo el valor de retorno errno = ENOENT:

1497880 ioctl(12, SECCOMP_IOCTL_NOTIF_SEND, 0x7f718fd28e10) = -1 ENOENT (No such file or directory)

libseccomp no me permite distinguir entre ENOENT (el proceso objetivo se interrumpió justo antes de llamar a SECCOMP_IOCTL_NOTIF_SEND ) y EINTR (el agente seccomp fue interrumpido por la señal SIGURG).

Además, no puedo leer errno de Golang, por lo que no puedo encontrar una solución alternativa.

enhancement prioritmedium

Comentario más útil

Pero las nuevas funciones... están usando _rc_filter() y no _rc_filter_sys()...

Ah... lo siento por eso. En realidad, es más profundo que el nivel de API, mire en "system.c" y verá que las llamadas de nivel de sistema de libseccomp no las propagan hasta las funciones de nivel de API. Mirando las páginas de manual, parece que no hacemos ningún reclamo sobre SCMP_FLTATR_API_SYSRAWRC para la API de notificación (consulte seccomp_load(3) para ver un ejemplo de contador).

Continuaré y reabriré esto como RFE ya que actualmente no hacemos ninguna afirmación sobre este funcionamiento.

@drakenclimber Creo que este es material v2.6.x (posiblemente v2.5.2) ya que no quiero retrasar el lanzamiento de v2.5.1. Si piensas lo contrario, házmelo saber.

Todos 5 comentarios

Hola @alban.

Mire SCMP_FLTATR_API_SYSRAWRC en la página seccomp_attr_set(3) :

Un indicador para especificar si libseccomp debe devolver los códigos de error del sistema a la persona que llama en lugar del valor predeterminado -ECANCELED. Por defecto está desactivado (valor == 0).

Forzamos -ECANCELED en este caso para garantizar una promesa de código de retorno estable en la API de libseccomp en diferentes versiones de kernel/libc. Ofrecemos SCMP_FLTATR_API_SYSRAWRC para las personas que llamen y aún deseen ver el código de retorno real de kernel/libc, solo tenga en cuenta que no garantizamos un código de retorno estable si habilita ese atributo.

Voy a cerrar este problema como NOTABUG, pero siéntase libre de continuar discutiendo esto aquí si tiene preguntas adicionales. Podemos reabrir si parece que hay un problema real que debe abordarse.

Hola @pcmoore , gracias por la rápida respuesta.

Ofrecemos SCMP_FLTATR_API_SYSRAWRC para las personas que llaman que aún desean ver el código de retorno real del kernel/libc

Pero las nuevas funciones

  • seccomp_notify_receive
  • seccomp_notify_respond
  • seccomp_notify_id_valid

están usando _rc_filter() y no _rc_filter_sys() , por lo que SCMP_FLTATR_API_SYSRAWRC no debería tener efecto, si no me equivoco.

Pero las nuevas funciones... están usando _rc_filter() y no _rc_filter_sys()...

Ah... lo siento por eso. En realidad, es más profundo que el nivel de API, mire en "system.c" y verá que las llamadas de nivel de sistema de libseccomp no las propagan hasta las funciones de nivel de API. Mirando las páginas de manual, parece que no hacemos ningún reclamo sobre SCMP_FLTATR_API_SYSRAWRC para la API de notificación (consulte seccomp_load(3) para ver un ejemplo de contador).

Continuaré y reabriré esto como RFE ya que actualmente no hacemos ninguna afirmación sobre este funcionamiento.

@drakenclimber Creo que este es material v2.6.x (posiblemente v2.5.2) ya que no quiero retrasar el lanzamiento de v2.5.1. Si piensas lo contrario, házmelo saber.

¡Gracias!

Para que conste, encontré la solución en el lado de Golang para poder distinguir ENOENT y EINTR, con este patrón de código:

-   if retCode := C.seccomp_notify_respond(C.int(fd), resp); retCode != 0 {
-       return errRc(retCode)
+   for {
+       retCode, errno := C.seccomp_notify_respond(C.int(fd), resp)
+       if errno == syscall.EINTR {
+           continue
+       }
+       if errno == syscall.ENOENT {
+           return errno
+       }
+       if retCode != 0 {
+           return errRc(retCode)
+       }
+       break
    }

Con esto, parece funcionar bien con libseccomp-2.5.0,

¿Fue útil esta página
0 / 5 - 0 calificaciones