Agregar una nueva llamada del sistema a Linux 3.2.x con un módulo de núcleo cargable [cerrado]

11

Quiero agregar una nueva llamada particular al sistema en el kernel 3.2.x de Linux pero como un módulo de kernel cargable (ya que no quiero volver a compilar el kernel una y otra vez)

Leí muchas publicaciones en Internet y también en SO, y algunos lugares afirman que la implementación de llamadas al sistema como módulos cargables no es posible, mientras que otros dicen que es posible.

Cual es ¿Cómo se hace si es posible?

abhi
fuente
Esta pregunta está fuera de tema aquí: Unix y Linux trata sobre el uso y la administración, no sobre la programación. Debes preguntar en Stack Overflow . No sea tan vago: enlace a las publicaciones que encontró en Stack Overflow y explique lo que encontró no concluyente o contradictorio.
Gilles 'SO- deja de ser malvado'
2
Creo que esta pregunta está mucho más relacionada con Linux como sistema operativo que con la programación misma. También es bastante importante saber cuáles son las posibilidades de ampliar las capacidades de nuestro sistema y cuáles son sus límites. Esto, por ejemplo, le hace comprender por qué algunas características no son posibles de implementar como módulo cargable y necesitan parches del kernel. Saber por qué es así también puede darle algunas ideas de seguridad frente a usabilidad que los desarrolladores de kernel deben hacer. ¿Esa pregunta sería más sobre el tema si OP preguntara solo si es posible y por qué no y no cómo implementar esto?
Krzysztof Adamski
1
Hubo numerosas discusiones sobre <stroke> flames </stroke> en la lista de correo del kernel de Linux, por ejemplo, reiserfs usó sus propias llamadas al sistema, que algunos desarrolladores centrales no amaban realmente, incluido Linus. En su caso, simplemente usaría ioctl()s para la tarea, son fácilmente modularizables. Afaik, la razón principal detrás de hacer esto tan difícil como sea posible, es que el número de llamadas al sistema es algo altamente codificado y nadie quiere el caos en lo que podría aparecer en la imagen. Pero existen numerosas interfaces de kernel para alcanzar la misma funcionalidad, por ejemplo, sysfs, ioctls o similares.
peterh - Restablece a Monica el

Respuestas:

14

No es posible porque la tabla de llamadas del sistema (llamada sys_call_table) es una matriz de tamaño estático. Y su tamaño está determinado en tiempo de compilación por el número de llamadas al sistema registradas. Esto significa que no hay espacio para otro.

Puede verificar la implementación, por ejemplo, para la arquitectura x86 en el arch/x86/kernel/syscall_64.carchivo, donde sys_call_tablese define. Su tamaño es exactamente __NR_syscall_max+1. __NR_syscall_maxse define arch/x86/kernel/asm-offsets_64.ccomo sizeof(syscalls) - 1(es el número de la última llamada al sistema), donde syscallhay una tabla con todas las llamadas al sistema.

Una posible solución es reutilizar algunos sys_setaltrootnúmeros existentes (o obsoletos si su arquitectura tiene uno, ver por ejemplo) syscall con el suyo, ya que esto no requerirá más espacio en la memoria. Algunas arquitecturas también pueden tener agujeros en la tabla syscall (como la versión de 64 bits de x86) para que pueda usar esto también.

Puede usar esta técnica si está desarrollando una nueva llamada al sistema y solo desea evitar reiniciar mientras experimenta. Tendrá que definir su nueva llamada al sistema, buscar la entrada existente en la tabla syscall y luego reemplazarla desde su módulo.

Hacer esto desde el módulo del núcleo no es trivial ya que el núcleo no se exporta sys_call_tablea los módulos a partir de la versión 2.6 (la última versión del núcleo que tenía este símbolo exportado era 2.5.41).

Una forma de evitar esto es cambiar su núcleo para exportar el sys_call_tablesímbolo a los módulos. Para hacer esto, debe agregar las siguientes dos líneas kernel/kallsyms.c( no haga esto en máquinas de producción ):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

Otra técnica es encontrar la tabla syscall dinámicamente. Usted itera sobre la memoria del núcleo, comparando cada palabra con un puntero con la función conocida de llamada del sistema. Como conoce el desplazamiento de esta llamada al sistema en la tabla, puede calcular la dirección inicial de la tabla.

Krzysztof Adamski
fuente
1

Lamentablemente, no puede agregar llamadas al sistema al núcleo como módulos cargables. Debe tomarse la molestia de compilar el núcleo cada vez que agrega una nueva llamada al sistema.

PaulDaviesC
fuente