Libseccomp: RFE: admite "versión máxima del kernel"

Creado en 21 ago. 2015  ·  14Comentarios  ·  Fuente: seccomp/libseccomp

A medida que se agregan llamadas al sistema al kernel, siento que no hay suficiente discusión por defecto sobre la amplia variedad de aplicaciones que de repente obtendrán acceso a una nueva superficie de ataque.

El ejemplo canónico aquí es perf_event_open() , la fuente de numerosos CVE. Si bien el rendimiento es increíble, mi (p. ej.) servidor web no debería (por defecto) poder usarlo.

Es posible usar seccomp hoy en la lista negra. las listas blancas pueden volverse muy difíciles de administrar.

Una cosa que podría ser útil es un filtro para cualquier llamada al sistema más reciente que una versión particular del kernel, digamos 3.10. De esa manera, cada nueva llamada al sistema tendría que ser verificada para su uso en, por ejemplo, contenedores antes de que se agregue. Actualizar el kernel no expondría repentinamente los contenedores a una nueva superficie de ataque.

En una discusión con @pcmoore , indicó que esto podría ser otra anotación en la estructura, por ejemplo arch-x86-syscalls.c .

enhancement pendininfo prioritmedium

Comentario más útil

Parece que el número 286 es el problema concreto que ayudará a impulsar este trabajo... incluso si han pasado casi cinco años;)

Creo que el primer paso hacia esto es agregar un nuevo campo al archivo syscalls.csv que indica cuándo se introdujo por primera vez el syscall. Eso va a ser una buena parte del trabajo ya que actualmente tenemos definidas ~469 syscalls (!). Sin embargo, podríamos amortizar este trabajo para las llamadas al sistema existentes con un valor "indefinido" que trataríamos simplemente como la llamada al sistema que se crea en los albores de los tiempos. Por supuesto, todas las nuevas incorporaciones a la tabla syscalls.csv deberán agregarse con la versión del kernel.

Algunos pensamientos más rápidos:

  • formato syscall.csv
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... donde <version> podría ser algo como "5_8", "UNDEF" o similar.

  • fichas de versión
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

Todos 14 comentarios

+1
Eso ayudaría a que las listas negras se puedan utilizar para mitigar los problemas de seguridad.

@nmav para ser claros, este RFE es para agregar información a las tablas internas de llamadas al sistema sobre cuándo se introdujo por primera vez la llamada al sistema en el kernel de Linux, no para agregar lógica para determinar si el kernel en ejecución actual admite una llamada al sistema determinada. Sin embargo, si está tratando de bloquear una llamada al sistema, puede hacerlo con libseccomp independientemente de si es compatible con una versión particular de arch/ABI y kernel, libseccomp hará lo correcto por usted.

Este RFE tiene casi cinco años y, aparte de una sola discusión con @cgwalters , no he visto ni oído hablar de mucho más interés en esta función. Con muchos otros problemas abiertos, la mayoría con mayor prioridad, no está claro cuándo trabajaríamos en esto, o incluso si tal cosa sería una adición útil.

@cgwalters y @drakenclimber , ¿qué opinan de este problema en 2020? Estoy tentado a cerrar esto como WONTFIX, pero me gustaría recibir algunos comentarios y opiniones antes de dar ese paso.

@cgwalters y @drakenclimber , ¿qué opinan de este problema en 2020? Estoy tentado a cerrar esto como WONTFIX, pero me gustaría recibir algunos comentarios y opiniones antes de dar ese paso.

Sinceramente, creo que es una idea genial. Varios de mis clientes internos utilizan listas de permitidos precisamente por este motivo. Si usaran una lista de denegación y se agregara una nueva llamada al sistema al kernel, entonces esa llamada al sistema sería otra vía de ataque.

Vamos a dejarlo abierto un poco más. Preguntaré dentro de Oracle y veré si algún cliente está lo suficientemente interesado en esta función como para que yo pueda elegirla. Pero @cgwalters (o cualquier otra persona) es totalmente bienvenido a poseerlo si tiene el tiempo y el interés :).

De acuerdo, mientras haya interés, no tengo ningún problema en mantener este abierto.

¡Todavía creo que sería útil!

Parece que el número 286 es el problema concreto que ayudará a impulsar este trabajo... incluso si han pasado casi cinco años;)

Creo que el primer paso hacia esto es agregar un nuevo campo al archivo syscalls.csv que indica cuándo se introdujo por primera vez el syscall. Eso va a ser una buena parte del trabajo ya que actualmente tenemos definidas ~469 syscalls (!). Sin embargo, podríamos amortizar este trabajo para las llamadas al sistema existentes con un valor "indefinido" que trataríamos simplemente como la llamada al sistema que se crea en los albores de los tiempos. Por supuesto, todas las nuevas incorporaciones a la tabla syscalls.csv deberán agregarse con la versión del kernel.

Algunos pensamientos más rápidos:

  • formato syscall.csv
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... donde <version> podría ser algo como "5_8", "UNDEF" o similar.

  • fichas de versión
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

¿Es la versión del kernel lo correcto para rastrear? ¿Se garantiza que las llamadas al sistema más nuevas no se retroalimenten, por ejemplo, a ramas estables del kernel con un número de versión más bajo?

Red Hat hará backport de todo tipo de cosas a sus kernels, así que no.

Si RedHat adapta una llamada al sistema a una versión anterior del kernel, también pueden parchear su versión de libseccomp para que coincida. Aunque para ser justos, esto podría ser más importante para ciertos casos de uso, pero como un enfoque para arreglar el #286, creo que es bastante viable. El otro problema es que no estoy seguro de que haya un enfoque mejor: las llamadas al sistema se pueden agregar en orden no consecutivo (por ejemplo, se agregó openat2 antes close_range ), aunque este ejemplo es amable de mi culpa).

Si RedHat adapta una llamada al sistema a una versión anterior del kernel, también pueden parchear su versión de libseccomp para que coincida.

Sí exactamente. El proyecto libseccomp ascendente no tiene control sobre las diversas distribuciones empresariales de Linux y si esas distribuciones deciden desviarse de los proyectos ascendentes (ya sea el Kernel de Linux o libseccomp) están solos para brindar soporte. Si bien haremos todo lo posible para ayudar, no podemos sacrificar el proyecto upstream en favor de estas distribuciones empresariales con su propio personal de soporte e ingeniería.

Como punto de referencia, la página de manual de syscalls(2) tiene información histórica sobre cuándo se introdujeron varias llamadas al sistema en el kernel:

Puedo hacer la espeleología de syscall para averiguar un número de versión para cada syscall; la única pregunta es si deberíamos tener el número de versión por arquitectura, ya que estoy bastante seguro de que se agregaron ciertas syscalls a diferentes arquitecturas en diferentes versiones.

... la única pregunta es si deberíamos tener el número de versión por arquitectura, ya que estoy bastante seguro de que se agregaron ciertas llamadas al sistema a diferentes arquitecturas en diferentes versiones.

Definitivamente lo fueron, y todavía lo son, por lo que puedo ver. Si bien va a ser un poco molesto y definitivamente explotará el CSV, rastrear la primera aparición de la llamada al sistema para cada arco/ABI es probablemente lo correcto.

Cualquier ayuda que pueda proporcionar en este @cyphar sería muy apreciada.

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