*********************************** * Peticiones de Sistema * * Por OyZzO/bcs * * oyzzo.coder@gmail.com * * www.badchecksum.com * * http://oyzzo.sytes.net * *********************************** ***************************** * * INDICE * * ************************* INDICE - - - - -> Indice Lin.[13] INTRODUCCION - - - - -> Intro al tema :) Lin.[40] MAGIC SYSRQ? - - - - -> Manos a la obra Lin.[59] -Tipos de Magic SysRq - - -> Eso mismo :P Lin.[76] -Otras maneras de generar Magic SysRq -> Pues eso xD Lin.[128] USOS DE SYSRQ - - - - -> Algun ejemplillo Lin.[143] ESTUDIO DE SYSRQ - - - -> Como lo hace Linux Lin.[194] DESPEDIDA - - - - -> Ultimas palabras Lin.[240] BIBLIOGRAFIA - - - - -> Para 1337 ;) Lin.[252] CODIGOS - - - - -> Codigos Lin.[261] ***************************** * * INTRODUCCION * * ************************* Esta vez me ha dado por escribir sobre las peticiones de sistema o SysRq(system requests). Es un tema sencillito pero que mucha gente no lo conoce pese a que va muy bien para solucionar cuelgues del sistema y para obtener algo de informacion del kernel, util para probar nuestros modulos ;). Todo lo que explico en este texto lo he probado en un kernel de gentoo concretamente en un 2.6.12-gentoo-r10, deberia ir todo igual k en un kernel oficial pero lo digo por si acaso algo os sale diferente puede ser por algun parche de gentoo en mi kernel. No se necesitan grandes conocimientos para entender el texto, con unos conocimientos basicos sobre el kernel y programacion en C sera suficiente. Ahora que ya he puesto algo de paja para hacer bulto ya puedo empezar ;). ***************************** * * Magic SysRq? * * ************************* ¿Queson las peticiones de sistema(SysRq)? Son unas acciones basicas que le podemos pedir al kernel mediante Magic SysRq. Para generar una Magic SysRq lo podemos hacer de varias formas, la principal es mediante la combinacion de teclas [Alt + Pet Sis] segidas de la tecla correspondiente al tipo de SysRq que queramos. Por defecto Magic SysRq suele venir desactivado en el kernel asi que tendremos que configurar y recompilar uno con esta opcion activada para que funcionen, se encuentra en: Kernel hacking -> Kernel debugging -> Magic SysRq key. Si generamos una Magic SysRq y no vemos el resultado por consola lo podemos recojer con el comando dmesg. _____________________________ Tipos de Magic SysRq | Aqui voy a describir los principales tipos de Magic SysRq. [h] - Esta SysRq nos imprime la lista de SysRq que podemos utilizar en ese kernel. [0-9] - Indicando un numero del 0 al 9 decimos que mensajes del kernel se imprimen por consola en linux/kernel.h yo tengo definidos los siguientes: KERN_EMERG = 0 -> el sistema esta inusable KERN_ALERT = 1 -> necesita accion immediata KERN_CRIT = 2 -> condiciones criticas KERN_ERR = 3 -> condiciones de error KERN_WARNING = 4 -> condiciones de alerta KERN_NOTICE = 5 -> normal pero condicion importante KERN_INFO = 6 -> informacion KERN_DEBUG = 7 -> mensajes de debugging [r] - Desactiva el modo "raw" del teclado y lo pone en "XLATE". [k] - SAK(Secure Access Key- Tecla de acceso seguro) mata todos los procesos en la consola virtual actual. [b] - Reinicio immediato del sistema (sin sincronizar ni desmontar los discos). [o] - Apaga el sistema si el APM funciona. [s] - Sincroniza todos los sistemas de ficheros montados. [u] - Remonta todos los sistemas de ficheros montados como solo lectura. [p] - Hace un volcado de los actuales registros y flags. [t] - Hace un volcado de las tareas actuales i su informacion. [m] - Hace un volcado de la informacion de memoria. [v] - Hace un volcado de la informacion de procesador SMP. [e] - Envia una señal SIGTERM a todos los procesos excepto init. [i] - Envia una señal SIGKILL a todos los procesos excepto init. [l] - Envia una señal SIGKILL a todos los procesos INCLUIDO init, el sistema se quedara no funcional. _____________________________________________ Otras maneras de generar Magic SysRq | Tambien se pueden generar Magic SysRq escribiendo el caracter correspondiente al tipo de peticion que queremos en el archivo de solo lectura /proc/sysrq-trigger. Es util si queremos generar SysRq dese algun lugar sin acceso al teclado del sistema como una sesion ssh remota. ¿que hago si hay usuarios no autorizados con acceso a la maquina? Pues en este caso podemos desactivar las SysRq escribiendo un 0 en /proc/sys/kernel/sysrq pero las podremos continuar generando mediante el punto de entrada /proc/sysrq-trigger ya que sigue funcionando y solo permite la escritura a usuarios autorizados ;). ***************************** * * Usos de SysRq * * ************************* Voy a comentar algunos de los usos mas comunes que he visto. Imaginate que estamos programando un modulo que cae en bucle infinito y bloquea el sistema, con SysRq p podemos conocer la rutina culpable.Vamos a ver un ejemplo del uso de esta SysRq, con Alt+PetSis+p: SysRq : Show Regs Pid: 0, comm: swapper EIP: 0060:[] CPU: 0 EIP is at acpi_processor_idle+0x126/0x262 EFLAGS: 00000206 Not tainted (2.6.12-gentoo-r10) EAX: 0013ef6f EBX: 00000808 ECX: 0013eddc EDX: 00000808 ESI: c156e0bc EDI: c071a380 EBP: c156e000 DS: 007b ES: 007b CR0: 8005003b CR2: b75c2000 CR3: 1cde6000 CR4: 000006d0 [] acpi_processor_idle+0x0/0x262 [] cpu_idle+0x61/0x80 [] start_kernel+0x164/0x180 [] unknown_bootoption+0x0/0x1e0 Vemos k esta SysRq nos imprime la informacion de los registros, del proceso actual y los nombres y posiciones en memoria de las funciones k se estan ejecutando en este instante: direccion-----> [] acpi_processor_idle+0x0/0x262 ->nombre y offset* direccion-----> [] cpu_idle+0x61/0x80 -> nombre y offset* direccion-----> [] start_kernel+0x164/0x180 -> nombre y offset* direccion-----> [] unknown_bootoption+0x0/0x1e0 -> nombre y offset* *offset es el desplazamiento en bytes dentro de la funcion. EIP: 0060:[] CPU: 0 -> Nos indica la posicion de memoria que se va a ejecutar y el procesador que la va a ejecutar, como solo tengo uno es 0 ;) EIP is at acpi_processor_idle+0x126/0x262 -> para que no tengamos ni que restar nos indica que punto exacto se esta ejecutando actualmente, vamos a comprobar que no nos engaña. Dice que esta en acpi_processor_idle+0x126 y eso tiene que corresponder a c033e665 que es donde dice que esta EIP, sumamos la direccion de acpi_processor_idle que nos ha dicho antes con el offset: c033e53f + 126 = c033e665 ;) facil no? Bueno, provando ireis encontrando mas utilidad pero si rebooteais es recomendable que hagais un sync y un umount primero ;) ***************************** * * Estudio de SysRq * * ************************* Vamos a estudiar como funcionan las sysrq en el kernel para poder crear las nuestras en nuestros modulos. Rapidamente vemos el archivo de cabezera linux/sysrq.h que nos define todo lo necesario para crear nuestra peticion de sistema. Mirando en este fichero vemos dos funciones: int register_sysrq_key(int,struct sysrq_key_op *); int unregister_sysrq_key(int,struct sysrq_key_op *); Bien ya sabemos como registrar y desregistrar nuestra SysRq.Estas funciones toman dos parametros, uno es la magic key y el otro es una estructura sysrq_key_op. El primer parametro es el entero correspondiente al caracter que queremos registrar para nuestra SysRq. El segundo parametro es la estructura de nuestra SysRq que esta definida en ese mismo archivo: struct sysrq_key_op{ void (*handler)(int,struct pt_regs *,struct tty_struct *); char *help_msg; char *action_msg; int enable_mask; }; En eneble_mask podemos meter alguna de las constantes SYSRQ_ENABLE* definidas en ese mismo archivo o 0x0001 para activarlo todo. El puntero a caracter action_msg apunta a una cadena que se imprimira cuando llamemos a la SysRq. El puntero a caracter help_msg es una cadena que se imprimira cuando llamemos a la SysRq Help (PetSis+h). Y por ultimo handler es la funcion que manejara la peticion de nuestra SysRq, el primer parametro vuelbe a ser la magic key y las otras estructuras sudo de explicarlas porque no las necesitaremos, la funcion manejadora de la sysrq tiene k tener esos parametros pero podeis sudar de ellos, quien las necesite que se las mire :P . Para saber k magic keys se usan por el kernel de linux podemos hechar un vistazo en drivers/char/sysrq.c donde se define sysrq_key_table y vemos k por ejemplo la w no esta siendo usada por ninguna SysRq: /* w */ NULL, Como ves no es complicado crearte una magic sysrq propia para sacar info de tu modulo cuando te interese, sin tener k crear un /proc ni llenar los logs del kernel de mierda ;) ***************************** * * Despedida * * ************************* Esto es todo sobre la teoria de peticiones de sistema, para aquellos que quieran ver una demostracion practica he creado un modulo sencillo que crea la magic sysrq 'w' que lo unico que hace es imprimir un mensajito :P solo para que podais ver algo de codigo vivo ;). El modulo lo podeis bajar de http://oyzzo.sytes.net y de http://www.badchecksum.com en la seccion de codigos. ***************************** * * Bibliografia * * ************************* Los sources del kernel son muy claritos ;) en drivers/char/sysrq.c y en linux/sysrq.h viene todo, os animo a k le hecheis un vistazo porque es muy sencillo y vereis como funcionan las sysrq que trae el kernel :). ***************************** * * Codigos * * ************************* <++> SysRq/SysRq.c $20d0bb4a48c33a1afbb79d992e1637ea #include #include #include #include MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("oyzzo"); MODULE_DESCRIPTION("Hello Word SysRq"); static struct sysrq_key_op sysrq_hw; static char magickey = 'w'; static char *help = "helloWord"; static char *action = "Printing HW message"; static void handle_hw(int key, struct pt_regs *pt_regs, struct tty_struct *tty) { printk(KERN_ALERT "Hello World Magic SysRq on w key by oyzzo ;)\n"); } static int __init sysrq_hw_init(void) { int erroh; sysrq_hw.help_msg = help; sysrq_hw.action_msg = action; sysrq_hw.handler = handle_hw; erroh = register_sysrq_key(magickey, &sysrq_hw); if (erroh) printk(KERN_ALERT "SysRq Hello World: el registro ha fallado\n"); else printk(KERN_ALERT "SysRq Hello World: se ha registrado bien\n"); return erroh; } static void __exit sysrq_hw_exit(void) { int erroh; erroh = unregister_sysrq_key(magickey, &sysrq_hw); if (erroh) printk(KERN_ALERT "SysRq Hello World: el DESregistro ha fallado\n"); else printk(KERN_ALERT "SysRq Hello World: DESregistro correcto\n"); } module_init(sysrq_hw_init); module_exit(sysrq_hw_exit); <--> <++> SysRq/Makefile $b9384b825a90a439d68c7a67683e3c0e ifneq ($(KERNELRELEASE),) obj-m := SysRq.o else KERNELDIR ?= /usr/src/linux-$(shell uname -r) PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif <--> <++> SysRq/README $ec6b1ce898e5f86bade17be85f0218e5 Para compilar: make Para cargar el modulo: insmod SysRq.ko Para listar los modulos cargados: lsmod Para descargar el modulo: rmmod SysRq Para ver los mensajes del kernel: dmesg Para generar la Magic SysRq: Alt+PetSis+w Para generar la Magic SysRq Help del kernel: Alt+PetSis+h (y deberiamos ver tambien la nuestra ;) <-->