Permisos, capabilities y el contexto
En la frontera, el kernel decide quién puede hacer qué. Las capabilities granulares, la comprobación de permisos, y la macro current que identifica quién te llama.
Cruzar datos con seguridad (nivel 12.1) es la mitad; la otra es decidir si quien pide algo tiene derecho. El kernel tiene un sistema de permisos granular más allá del clásico root, y una forma de saber siempre quién está al otro lado de la syscall.
- La macro
current: quién te llama. - Comprobar permisos con
capable. - Capabilities granulares vs root.
- Contexto de proceso vs interrupción.
current: quién está llamando
En contexto de proceso, la macro current te da un puntero al task_struct (nivel 25) del proceso que ejecutó la syscall — quién te está llamando:
printk(KERN_INFO "me llama el proceso %s (PID %d)\n",
current->comm, current->pid);
Es tu identidad del llamador: su PID, su nombre, sus credenciales, su usuario. La base para decidir permisos.
Comprobar permisos: capable
Antes de una operación privilegiada, el kernel comprueba si el llamador tiene el permiso adecuado:
if (!capable(CAP_NET_ADMIN))
return -EPERM; /* no tiene el permiso de administrar red */
Capabilities: root, dividido en piezas
El modelo clásico de Unix era binario: o eres root (todopoderoso) o no (limitado). Eso es peligroso — un programa que solo necesita, digamos, abrir puertos bajos no debería tener también permiso para reformatear discos. Las capabilities de Linux parten el poder de root en piezas granulares: CAP_NET_ADMIN (red), CAP_SYS_ADMIN (admin del sistema), CAP_SYS_MODULE (cargar módulos), CAP_DAC_OVERRIDE (saltarse permisos de archivos), y decenas más. Así un servicio recibe solo las capabilities que necesita, y un fallo suyo compromete mucho menos. Cuando escribas un driver con operaciones privilegiadas, comprueba la capability específica y mínima que corresponda —no CAP_SYS_ADMIN por pereza, que es casi como pedir root entero—. Este es el principio de mínimo privilegio (nivel 26 de C23) aplicado dentro del kernel: da y exige el poder justo, ni más ni menos. Reduce la superficie de ataque de todo el sistema.
Contexto de proceso vs interrupción
Un detalle crucial: current solo tiene sentido en contexto de proceso (cuando ejecutas en nombre de una syscall). En contexto de interrupción (nivel 22), no hay un proceso “llamante” — la interrupción llegó de forma asíncrona. Usar current o dormir ahí es un bug grave.
Antes de usar current, comprobar permisos o dormir, pregúntate: ¿estoy en contexto de proceso o de interrupción? En contexto de proceso (una syscall, tu char device read/write) puedes usar current, comprobar capabilities y dormir. En contexto de interrupción no. Saber en qué contexto corre tu código es una de las distinciones que más importan en el kernel, y la verás una y otra vez (concurrencia, memoria, interrupciones). Cada API del kernel documenta desde qué contexto se puede llamar.
- En tu módulo, imprime quién te llama con
current->commycurrent->pid. - Añade una comprobación
capable(CAP_SYS_ADMIN)que devuelva-EPERMa los no privilegiados. - Investiga la lista de capabilities en
include/uapi/linux/capability.h. - Explica por qué
currentno vale en contexto de interrupción.