capabilities(7) visión general del sistema de capacidades de Linux

DESCRIPCIÓN

Con el propósito de realizar comprobaciones de permisos, las implementaciones tradicionales de Unix distinguen dos categorías de procesos: procesos privilegiados (cuyo identificador de usuario efectivo es 0, refiriéndose al superusuario o root) y procesos no privilegiados (cuyo identificador de usuario efectivo es distinto de cero). Los procesos privilegiados evitan todas las comprobaciones de permisos del núcleo, mientras que los procesos no privilegiados se ven sujetos a severas comprobaciones de permisos basadas en las credenciales del proceso (normalmente: ID de usuario efectivo, ID de grupo efectivo y lista de grupos adicionales).

Desde la versión 2.2 del núcleo, Linux ofrece un (hasta ahora incompleto) sistema de capacidades, que divide los privilegios asociados tradicionalmente al superusuario en unidades distintas que pueden ser activadas y desactivadas independientemente.

Lista de capacidades

Hasta la versión 2.4.18 de Linux, las siguientes capacidades están implementadas:
CAP_CHOWN
Permite cambios arbitrarios en los IDs de usuario y de grupo de los ficheros (vea chown(2)).
CAP_DAC_OVERRIDE
Evita las comprobaciones de permisos sobre operaciones de lectura, escritura y ejecución. (DAC = "control de acceso discrecional".)
CAP_DAC_READ_SEARCH
Evita comprobaciones de permisos sobre operaciones de lectura de ficheros y lectura y ejecución de directorios.
CAP_FOWNER
Evita comprobaciones de permisos sobre operaciones que normalmente requieren que el ID de usuario del sistema de ficheros del proceso coincida con el ID de usuario del fichero (p.e., utime(2)), excluyendo aquellas operaciones cubiertas por CAP_DAC_OVERRIDE y CAP_DAC_READ_SEARCH; ignora el bit pegajoso (sticky) en el borrado de ficheros.
CAP_FSETID
No borra los bits set-user-ID y set-group-ID cuando se modifica un fichero; permite establecer el bit set-group-ID para un fichero cuyo ID de grupo no coincide con el del sistema de ficheros o cualquier otro ID de grupo adicional del proceso invocador.
CAP_IPC_LOCK
Permite el bloqueo en memoria (mlock(2), mlockall(2), shmctl(2)).
CAP_IPC_OWNER
Evita comprobaciones de permisos para las operaciones sobre objetos System V IPC.
CAP_KILL
Evita comprobaciones de permisos para enviar señales (vea kill(2)).
CAP_LEASE
(Linux 2.4 en adelante) Permite que se establezcan arriendos sobre ficheros arbitrarios (vea fcntl(2)).
CAP_LINUX_IMMUTABLE
Permite establecer los atributos extendidos EXT2_APPEND_FL y EXT2_IMMUTABLE_FL sobre ficheros del sistema de ficheros ext2.
CAP_MKNOD
(Linux 2.4 en adelante) Permite la creación de ficheros especiales usando mknod(2).
CAP_NET_ADMIN
Permite varias operaciones relacionadas con redes (p.e., establecer opciones privilegiadas sobre conectores, habilitar la difusión de paquetes multidestino (multicasting), configuración de interfaces, modificar tablas de encaminamiento).
CAP_NET_BIND_SERVICE
Permite ligar conectores a puertos reservados del dominio de Internet (números de puerto menores que 1024).
CAP_NET_BROADCAST
(No se usa) Permite la difusión universal (broadcasting) de paquetes a través de un conector y la escucha de paquetes multidestino.
CAP_NET_RAW
Permite el uso de conectores de tipo RAW y PACKET.
CAP_SETGID
Permite manipulaciones arbitrarias de los IDs de grupo y de la lista de IDs de grupo adicionales de un proceso; permite el uso de IDs de grupo falsificados cuando se pasan credenciales de conectores a través de conectores de dominio Unix.
CAP_SETPCAP
Concede o elimina cualquier capacidad en el conjunto de capacidades permitidas del invocador a o desde cualquier otro proceso.
CAP_SETUID
Permite manipulaciones arbitrarias de los IDs de usuario de los procesos (setuid(2), etc.); permite el uso de IDs de usuario falsificados cuando se pasan credenciales de conectores a través de conectores de dominio Unix.
CAP_SYS_ADMIN
Permite una variedad de operaciones de administración del sistema incluyendo: quotactl(2), mount(2), swapon(2), sethostname(2), setdomainname(2), IPC_SET y operaciones IPC_RMID sobre objetos arbitrarios IPC de System V; permite el uso de IDs de usuario falsificados cuando se pasan credenciales de conectores.
CAP_SYS_BOOT
Permite llamadas a reboot(2).
CAP_SYS_CHROOT
Permite llamadas a chroot(2).
CAP_SYS_MODULE
Permite cargar y eliminar módulos del núcleo.
CAP_SYS_NICE
Permite aumentar el valor nice del proceso invocador (nice(2), setpriority(2)) y cambiar el valor nice de procesos arbitrarios; permite establecer políticas de planificación de tiempo real para el proceso invocador y establecer políticas de planificación y prioridades para procesos arbitrarios (sched_setscheduler(2), sched_setparam(2)).
CAP_SYS_PACCT
Permite llamadas a acct(2).
CAP_SYS_PTRACE
Permite el seguimiento detallado de procesos arbitrarios usando ptrace(2)
CAP_SYS_RAWIO
Permite operaciones sobre puertos de E/S (iopl(2) y ioperm(2)).
CAP_SYS_RESOURCE
Permite el uso de espacio reservado en sistemas de ficheros ext2; llamadas ioctl(2) para controlar el registro en ext3; sobrescribir los límites de las cuotas de disco; incrementar los límites de recursos (vea setrlimit(2)); sobrescribir el límite del recurso RLIMIT_NPROC; incrementar el límite msg_qbytes para una cola de mensajes por encima del limite en /proc/sys/kernel/msgmnb (vea msgop(2) y msgctl(2).
CAP_SYS_TIME
Permite la modificación del reloj del sistema (settimeofday(2), adjtimex(2)); permite la modificación del reloj de tiempo real (hardware)
CAP_SYS_TTY_CONFIG
Permite llamadas a vhangup(2).

Capacidades de procesos

Cada proceso tiene tres conjuntos de capacidades conteniendo cero o más de las capacidades citadas arriba:
Efectivas:
las capacidades usadas por el núcleo para llevar a cabo comprobaciones de permisos para el proceso.
Permitidas:
la capacidades que el proceso puede asumir (esto es, un superconjunto limitante para los conjuntos de efectivas y heredadas). Si un proceso elimina una capacidad de su conjunto de permitidas, no puede volver nunca a adquirir esa capacidad (a menos que ejecute un programa set-UID-root).
Heredadas:
las capacidades que se conservan tras llamadas a execve(2).

En la implementación actual, a un proceso se le conceden todas las capacidades permitidas y efectivas (sujetas a la operación del conjunto limitador de capacidades descrita más abajo) cuando ejecuta un programa set-UID-root o si un proceso con ID de usuario real cero ejecuta un nuevo programa.

Un hijo creado con fork(2) hereda copias de los conjuntos de capacidades del padre.

Usando capset(2), un proceso puede manipular su propio conjunto de capacidades o, si tiene la capacidad CAP_SETPCAP, los de otros procesos.

Conjunto limitador de capacidades

Cuando un programa se ejecuta mediante exec, a las capacidades permitidas y efectivas se les aplica un AND con el valor actual del así llamado conjunto limitador de capacidades, definido en el fichero /proc/sys/kernel/cap-bound. Este parámetro se puede usar para limitar de forma global las capacidades otorgadas a todos los procesos ejecutados posteriormente. En un sistema estándar, el conjunto limitador de capacidades siempre desactiva la capacidad CAP_SETPCAP. Para eliminar esta restricción, modifique la definición de CAP_INIT_EFF_SET en include/linux/capability.h y reconstruya el núcleo.

Implementación actual y futura

Una implementación completa de capacidades requiere:
1.
que para todas las operaciones privilegiadas, el núcleo compruebe si el proceso tiene la capacidad requerida en su conjunto efectivo.
2.
que el núcleo proporcione llamadas al sistema permitiendo modificar y recuperar los conjuntos de capacidades de un proceso.
3.
el soporte del sistema de ficheros para asociar capacidades a un fichero ejecutable, para que un proceso obtenga esas capacidades cuando el fichero sea ejecutado mediante exec.

Hasta la versión 2.4.18 de Linux, sólo se cumplen los dos primeros requisitos.

Finalmente, debería ser posible asociar tres conjuntos de capacidades a un fichero ejecutable, que en conjunción con los conjuntos de capacidades del proceso, determinen las capacidades de un proceso después de un exec:

Permitidas:
a este conjunto se le aplica la operación AND con el conjunto heredado del proceso para determinar qué capacidades heredadas le son permitidas al proceso después del exec.
Forzadas:
las capacidades permitidas automáticamente al proceso, sin importar las capacidades heredadas del proceso.
Efectivas:
aquellas capacidades en el nuevo conjunto permitido del proceso son también activadas en el nuevo conjunto efectivo. (F(efectivas) normalmente debería ser o todo ceros o todo unos. Ver más abajo.)

Mientras tanto, puesto que la implementación actual no soporta conjuntos de capacidades sobre ficheros, durante un exec:

1.
Se asume que inicialmente los tres conjuntos de capacidades del fichero están vacíos.
2.
Si se está ejecutando un programa set-UID-root o si el ID de usuario real del proceso es 0 (root), entonces se considera que los conjuntos de las capacidades permitidas y forzadas del fichero están llenos de unos (es decir, todas las capacidades están activas).
3.
Si se está ejecutando un programa set-UID-root program, entonces se considera que el conjunto de capacidades efectivas del fichero está lleno de unos.

Durante un exec, el núcleo calcula las nuevas capacidades del proceso usando el siguiente algoritmo:

P'(permitidas) = (P(heredadas) & F(permitidas)) | (F(forzadas) & cap_bset)
P'(efectivas) = P'(permitidas) & F(efectivas)
P'(heredadas) = P(heredadas)    [i.e., no se modifica]
donde:
P
denota el valor del conjunto de capacidades de un proceso antes del exec
P'
denota el valor del conjunto de capacidades de un proceso después del exec
F
denota un conjunto de capacidades de fichero
cap_bset
es el valor del conjunto limitador de capacidades.

OBSERVACIONES

El paquete libcap ofrece un conjunto de rutinas para establecer y obtener las capacidades de un proceso que resultan más cómodas y con menos probabilidad de cambiar que la interfaz provista por capset(2) y capget(2).

CONFORME A

Ningún estándar determina las capacidades, aunque la implementación de capacidades de Linux se basa en el retraído borrador del estándar POSIX 1003.1e.

FALLOS

No hay hasta ahora soporte del sistema de ficheros para permitir asociar capacidades a ficheros ejecutables.