2011-05-27 20 views
6

En el sistema Linux, un usuario no privilegiado inicia un programa. El proceso creado tiene las capacidades CAP_NET_RAW,CAP_NET_ADMIN con modo como effective,permitted,inheritable. Este proceso crea un proceso secundario llamando al fork y execv para invocar a otro programa udhcpc, pero el proceso hijo no hereda las capacidades CAP_NET_RAW,CAP_NET_ADMIN como se esperaba. Aunque antes de configurar las capacidades que he llamado prctl(PR_SET_KEEPCAPS, 1).fork y execve para heredar las capacidades del proceso padre sin privilegios

Cualquier sugerencia sobre qué hacer para heredar las capacidades del proceso principal sin privilegios al fork seguido de execve?

+0

que parece ser imposible en el momento de preservar las capacidades después de execve, sin establecer capacidades de archivo. Ver [\ [RFC \] Las capacidades aún no pueden ser heredadas por los programas normales] (http://www.gossamer-threads.com/lists/linux/kernel/1641892) – Lekensteyn

+0

Fork puede pasarlos, el ejecutivo no puede (excepto con ambiente). Exec puede pasar heredado, pero el archivo que se ejecuta también necesita este conjunto heredado. –

Respuesta

10

En execve(), los conjuntos de capacidades de archivo del archivo que se está ejecutando (en este caso, udhcpc) se inspeccionan y se combinan con los conjuntos de capacidades del subproceso. En particular, Inheritable conjunto del archivo es AND -ed con Inheritable conjunto del hilo para determinar el nuevo Permitted conjunto, y el bit del archivo Effective debe ajustarse para que el nuevo conjunto Effective ser copiado del conjunto Permitted.

Esto implica que en su caso debe usar setcap cap_net_raw,cap_net_admin=ei /path/to/udhcpc para obtener el efecto que desea (además de establecer las capacidades en el proceso principal, el prctl() no es necesario).

+0

Hola, Thaks por tu valiosa respuesta. Estoy usando el kernel 2.6.18-7.1. No puedo encontrar el comando setcap para proporcionar la capacidad de un ejecutable. Creo que está disponible en el último kernel. ¿Hay alguna forma alternativa de hacerlo en el núcleo 2.6.18-7.1.Gracias, Eswar – Eswar

+0

@ user736403: Lo siento, no estoy seguro de cuál era la situación en esos núcleos más antiguos. – caf

2

De acuerdo con "La interfaz de programación de Linux", de Michael Kerrisk (n Almidón Press, 2010):

Desde el kernel 2.6.24, es posible unir capacidades en un archivo. Se agregaron otras características en los kernels 2.6.25 y 2.6.26 en para completar la implementación de las capacidades.

Las herramientas sucap y execcap son lo que debe buscar. Sin embargo, si recuerdo, limitado a restringir, no otorgan capacidades. Mira:

http://www.linuxjournal.com/article/5737

y

http://lkml.indiana.edu/hypermail/linux/kernel/0503.1/2540.html

1

extraída del manual, se han producido algunos cambios. De acuerdo con él fork no cambia las capacidades. Y ahora hay un conjunto ambiental, parece que esto es por lo que estás tratando de hacer.

Ambient (since Linux 4.3): 
      This is a set of capabilities that are preserved across an execve(2) of a program that is not privileged. The ambient capability set obeys the invariant that no capability can ever 
      be ambient if it is not both permitted and inheritable. 

      The ambient capability set can be directly modified using 
      prctl(2). Ambient capabilities are automatically lowered if 
      either of the corresponding permitted or inheritable 
      capabilities is lowered. 

      Executing a program that changes UID or GID due to the set- 
      user-ID or set-group-ID bits or executing a program that has 
      any file capabilities set will clear the ambient set. Ambient 
      capabilities are added to the permitted set and assigned to 
      the effective set when execve(2) is called. 

    A child created via fork(2) inherits copies of its parent's 
    capability sets. See below for a discussion of the treatment of 
    capabilities during execve(2). 

...

 P'(ambient) = (file is privileged) ? 0 : P(ambient) 

     P'(permitted) = (P(inheritable) & F(inheritable)) | 
         (F(permitted) & cap_bset) | P'(ambient) 

     P'(effective) = F(effective) ? P'(permitted) : P'(ambient) 

     P'(inheritable) = P(inheritable) [i.e., unchanged] 

    where: 

     P   denotes the value of a thread capability set before the 
       execve(2) 

     P'  denotes the value of a thread capability set after the 
       execve(2) 

     F   denotes a file capability set 

     cap_bset is the value of the capability bounding set (described 
       below). 
Cuestiones relacionadas