Leccin 9: EXEC - PowerPoint PPT Presentation

1 / 35
About This Presentation
Title:

Leccin 9: EXEC

Description:

... se almacenan en el mismo formato: un ejemplo 'Java Handler', 'Scripts' ... En el futuro, los handlers de Java y EM86 ser n de este tipo. 29. formatos ejecutables ... – PowerPoint PPT presentation

Number of Views:36
Avg rating:3.0/5.0
Slides: 36
Provided by: ccd1
Category:
Tags: exec | handlers | leccin

less

Transcript and Presenter's Notes

Title: Leccin 9: EXEC


1
Lección 9 EXEC
  • Tinguaro Tadeo del Rosario
  • Juan José Muñoz García

2
Introducción
  • Un fork crea un proceso hijo que ejecuta el mismo
    programa, mientras que con un exec se puede
    lanzar a ejecutar un nuevo programa.
  • El exec permite crear un proceso que ejecuta un
    código distinto al del padre.
  • Si no existiera el fork y el exec, siempre
    estaría ejecutándose el proceso init, porque el
    resto serían simplemente hijos de él.

3
Familia de funciones
  • Realmente, no existe ninguna función llamada
    exec.
  • Siempre estaremos haciendo referencia al conjunto
    de funciones que poseen la misma funcionalidad,
    pero que se diferencian en el modo en el que se
    les pasan los argumentos.
  • La familia está formada por execl, execle,
    execve, execlp, execvp y execv.

4
Modo de uso
  • En caso de éxito en un exec no hay retorno,
    porque el proceso que llama, ejecuta ahora un
    nuevo programa.
  • Para crear nuevos procesos, generalmente se
    siguen dos pasos
  • Se crea una copia del proceso padre mediante fork
    o clone.
  • El hijo lanza a ejecutar, mediante exec el nuevo
    programa.

5
Modo de uso
if (fork()) // Esto lo ejecuta el
padre else // Esto lo ejecuta el
hijo execl(programa, programa) // Finaliza
el proceso hijo
6
Implementación del exec
  • El código fuente de la implementación del exec se
    encuentra en /fs/exec.c.
  • La función principal que lleva a cabo la
    implementación es do_execve.
  • Otras funciones importantes son
  • prepare_binprm prepara los parámetros del
    fichero ejecutable.
  • search_binary_handler busca el manejador para el
    tipo de ejecutable que se trate.

7
do_execve
  • La funcionalidad básica es la siguiente
  • Lee de memoria información característica del
    ejecutable (prepare_binprm) de los primeros 128
    bytes.
  • Prepara el entorno y argumentos del nuevo
    programa.
  • Busca el manejador para el tipo de ejecutable que
    se esté tratando (search_binary_handler).

8
do_execve - linux_binprm
  • Estructura utilizada para configurar parámetros
    de ejecución del proceso, antes de lanzarlo a
    ejecutar

struct linux_binprm char bufBINPRM_BUF_SIZE
// Para leer los primeros 128 bytes struct
page pageMAX_ARG_PAGES // Tabla pagina del
proceso unsigned long p // Longitud de la
memoria utilizada struct dentry dentry //
Identificador de fichero del ejecutable int
e_uid, e_gid // uid y gid efectivos int argc,
envc // Numero de argumentos y variables de
entorno char filename / Nombre del
ejecutable /
9
do_execve - linux_binprm
  • Estructura utilizada para configurar parámetros
    de ejecución del proceso, antes de lanzarlo a
    ejecutar
  • El UID real es el identificador del usuario que
    ha lanzado el
  • proceso.
  • El EUID es el identificador que usa el sistema
    para los controles
  • de acceso. Puede ser distinto al del usuario
    real (bit SETUID)
  • Si el fichero ejecutado tiene activo el bit
    SETUID, se cambia el
  • e_uid del proceso que hizo la llamada al del
    propietario del fichero
  • ejecutable.
  • Si no lo tiene activo, el e_uid será el del
    proceso que hizo la
  • llamada.

struct linux_binprm char bufBINPRM_BUF_SIZE
// Para leer los primeros 128 bytes struct
page pageMAX_ARG_PAGES // Tabla pagina del
proceso unsigned long p // Longitud de la
memoria utilizada struct dentry dentry //
Identificador de fichero del ejecutable int
e_uid, e_gid // uid y gid efectivos int argc,
envc // Numero de argumentos y variables de
entorno char filename / Nombre del
ejecutable /
10
do_execve - Tabla de páginas
Número de página
Tabla de página
Marco en memoria física
- Para reducir el tiempo de acceso a memoria
física, se utilizan tablas TLB - El registro PTBR
apunta a la dirección en memoria principal que
contiene la tabla de página
11
do_execve
10079 int do_execve(char filename, char
argv, 10080 char envp, struct
pt_regs regs) 10081 10082 struct
linux_binprm bprm 10083 struct dentry
dentry 10084 int retval 10085 int i 10086
10087 bprm.p PAGE_SIZEMAX_ARG_PAGES-sizeof(v
oid ) 10088 for (i0 iltMAX_ARG_PAGES i)
/ clear pg-tbl / 10089 bprm.pagei
0 10090 10091 dentry open_namei(filename,
0, 0) 10092 retval PTR_ERR(dentry) 10093
if (IS_ERR(dentry)) 10094 return retval
12
do_execve
10096 bprm.dentry dentry 10097
bprm.filename filename 10098 bprm.sh_bang
0 10099 bprm.java 0 10100 bprm.loader
0 10101 bprm.exec 0 10102 if ((bprm.argc
count(argv)) lt 0) 10103
dput(dentry) 10104 return bprm.argc 10105
10106 10107 if ((bprm.envc count(envp)) lt
0) 10108 dput(dentry) 10109 return
bprm.envc 10110 10111 10112 retval
prepare_binprm(bprm)
13
do_execve
10096 bprm.dentry dentry 10097
bprm.filename filename 10098 bprm.sh_bang
0 10099 bprm.java 0 10100 bprm.loader
0 10101 bprm.exec 0 10102 if ((bprm.argc
count(argv)) lt 0) 10103
dput(dentry) 10104 return bprm.argc 10105
10106 10107 if ((bprm.envc count(envp)) lt
0) 10108 dput(dentry) 10109 return
bprm.envc 10110 10111 10112 retval
prepare_binprm(bprm)
  • argv es un array de cadenas de argumentos
    pasados al nuevo programa.
  • envp es un array de cadenas, que se pasan como
    entorno al nuevo programa.
  • Tanto argv como envp deben terminar en un puntero
    nulo.

14
do_execve
10114 if (retval gt 0) 10115 bprm.p
copy_strings(1, bprm.filename, bprm.page, 10116
bprm.p, 2) 10117
bprm.exec bprm.p 10118 bprm.p
copy_strings(bprm.envc,envp,bprm.page, 10119
bprm.p,0) 10120 bprm.p
copy_strings(bprm.argc,argv,bprm.page, 10121
bprm.p,0) 10122 if
(!bprm.p) 10123 retval -E2BIG 10124
10125 10126 if (retval gt 0) 10127
retval search_binary_handler(bprm,regs) 10128
if (retval gt 0) 10129 / execve success
/ 10130 return retval
15
do_execve
10132 / Something went wrong, return the inode
and free the 10133 argument pages/ 10134
if (bprm.dentry) 10135 dput(bprm.dentry) 1013
6 10137 for (i0 iltMAX_ARG_PAGES
i) 10138 free_page(bprm.pagei) 10139
10140 return retval 10141
16
do_execve - count
9480 static int count(char argv) 9481 9482
int i 0 9484 if (argv ! NULL) 9485
for () 9486 char p 9487 int
error 9488 9489 error get_user(p,argv)
9490 if (error) 9491 return
error 9492 if (!p) 9493
break 9494 argv 9495 i 9496
9497 9498 return i 9499
17
do_execve - prepare_binprm
9832 int prepare_binprm(struct linux_binprm
bprm) 9833 9834 int mode 9835 int
retval,id_change,cap_raised 9836 struct inode
inode bprm-gtdentry-gtd_inode 9838 mode
inode-gti_mode 9839 if (!S_ISREG(mode)) 9840
return -EACCES 9841 if (!(mode 0111)) 9842
return -EACCES 9843 if (IS_NOEXEC(inode)) 98
44 return -EACCES 9845 if
(!inode-gti_sb) 9846 return -EACCES 9847 if
((retval permission(inode, MAY_EXEC)) !
0) 9848 return retval 9850 if
(inode-gti_writecount gt 0) 9851 return
-ETXTBSY
Comprueba que es un fichero regular ejecutable,
que tiene permiso de ejecución y que no se está
escribiendo
18
do_execve - prepare_binprm
9853 bprm-gte_uid current-gteuid 9854
bprm-gte_gid current-gtegid 9855 id_change
cap_raised 0 9856 9857 / Set-uid? / 9858
if (mode S_ISUID) 9859 bprm-gte_uid
inode-gti_uid 9860 if (bprm-gte_uid !
current-gteuid) 9861 id_change 1 9862
9863 /Set-gid?/ 9868 if ((mode (S_ISGID
S_IXGRP)) 9869 (S_ISGID S_IXGRP))
9870 bprm-gte_gid inode-gti_gid 9871
if (!in_group_p(bprm-gte_gid)) 9872
id_change 1 9873
Si el setuid y/o setgid están activos, los
nuevos procesos se tratarán como usuarios /
grupos diferentes
19
do_execve - prepare_binprm
9933 return read_exec(bprm-gtdentry,0,bprm-gtbuf,1
28,1)
Finalmente, leemos los primeros 128 bytes del
fichero, y lo introducimos en la estructura
bprm. Una posible optimización del kernel sería
reemplazar 128 por un define. El buffer sirve
para identificar el tipo de ejecutable que
estamos tratando
20
do_execve - copy_string
9519 unsigned long copy_strings( 9520 int
argc,char argv, 9521 unsigned long page,
unsigned long p, int from_kmem) 9522 9531
while (argc-- gt 0) 9537 get_user(str,
argvargc) 9542 len strlen_user(str)
9549 while (len) 9553 offset pos
PAGE_SIZE 9555 pag (char )
pagepos/PAGE_SIZE 9556 (unsigned
long ) get_free_page(GFP_USER)) 9561
bytes_to_copy PAGE_SIZE - offset 9564
copy_from_user(pag offset, str,
bytes_to_copy) 9567 len -
bytes_to_copy 9568 9569 9572 return
p 9573
21
do_execve - copy_string
9519 unsigned long copy_strings( 9520 int
argc,char argv, 9521 unsigned long page,
unsigned long p, int from_kmem) 9522 9531
while (argc-- gt 0) 9537 get_user(str,
argvargc) 9542 len strlen_user(str)
9549 while (len) 9553 offset pos
PAGE_SIZE 9555 pag (char )
pagepos/PAGE_SIZE 9556 (unsigned
long ) get_free_page(GFP_USER)) 9561
bytes_to_copy PAGE_SIZE - offset 9564
copy_from_user(pag offset, str,
bytes_to_copy) 9567 len -
bytes_to_copy 9568 9569 9572 return
p 9573
22
do_execve - search_binary_handler
9996 int search_binary_handler(struct
linux_binprm bprm, 9997
struct pt_regs regs) 9998 10036 for (try0
trylt2 try) 10037 for (fmt formats
fmt fmt fmt-gtnext) 10038 int
(fn)(struct linux_binprm , struct pt_regs
) 10039 fmt-gtload_binary 10040
if (!fn) 10041 continue 10042
retval fn(bprm, regs) 10043 if (retval
gt 0) 10044 if (bprm-gtdentry) 10045
dput(bprm-gtdentry) 10046
bprm-gtdentry NULL 10047
current-gtdid_exec 1 10048 return
retval 10049
MANEJADOR BINARIO Mecanismo del núcleo
para tratar la variedad de formatos binarios de
manera consistente. No todos los programas se
almacenan en el mismo formato un ejemplo Java
Handler, Scripts.
23
do_execve - search_binary_handler
10050 if (retval ! -ENOEXEC) 10051
break 10052 / We don't have the dentry
anymore / 10053 if (!bprm-gtdentry) 10054
return retval 10055 10056 if
(retval ! -ENOEXEC) 10057 break 10059
else 10068 sprintf(modname,
"binfmt-04x", 10069 (unsigned
short )(bprm-gtbuf2)) 10070
request_module(modname) 10072 10073
10074 return retval 10075
Si no se encuentra ningún manejador se hace un
segundo intento, obteniendo primero un código de
formato nuevo, que indique el posible tipo de
fichero binario
24
formatos ejecutables
  • No todos los programas están almacenados en el
    mismo formato
  • Linux usa manejadores binarios para abstraer las
    diferencias entre los distintos formatos
  • Para cada formato se usa un manejador específico
  • ELF es el formato nativo de ejecutables Linux

25
formatos ejecutables
  • ELF sustituye a otro formato llamado a.out, que
    es el que se utilizaba como nativo en versiones
    anteriores del kernel
  • Los manejadores binarios reconocen cualquier
    número mágico que se encuentre al comienzo de un
    fichero

26
formatos ejecutables
  • También pueden realizar el reconocimiento del
    formato por alguna propiedad del nombre
  • Por ejemplo, los binarios java se identifican por
    su extensión class o por su número mágico
    0xCAFEBADE

27
formatos ejecutables
  • El kernel 2.2 soporta los siguientes manejadores
  • a.out antiguo formato nativo de linux. Está en
    desuso, pero aún se le proporciona soporte
  • ELF formato actual de los binarios Linux. A
    pesar de ser el formato nativo, se incluye un
    manejador para homogeneizar el núcleo, y hacerlo
    más sencillo

28
formatos ejecutables
  • EM86 empleado para ejecutar binarios Linux en
    máquinas con arquitectura Alpha
  • Misc el manejador de este formato puede
    reconocer gran variedad de formatos por
    extensión, o por número mágico. La gran ventaja
    que tiene, es que es configurable en tiempo de
    ejecución, no solo de compilación, y por lo tanto
    no es necesario recompilar el núcleo para dar
    soporte a un nuevo formato. En el futuro, los
    handlers de Java y EM86 serán de este tipo

29
formatos ejecutables
  • Scripts utilizado para ejecutar scripts del
    shell. Trata los ficheros cuyos 2 primeros
    caracteres sean !

30
Un ejemplo java handler
  • En fs/binfmt_java.c se encuentran las funciones
    encargadas de manejar los ficheros java, tanto
    ejecutables como applets

31
java handler - do_load_java
do_load_java Hace todo lo necesario para la
carga de ficheros .class de Java
static int do_load_java(struct linux_binprm
bprm,struct pt_regs regs) unsigned char ucp
(unsigned char ) bprm-gtbuf if ((ucp0 !
0xca) (ucp1 ! 0xfe) (ucp2 ! 0xba)
(ucp3 ! 0xbe)) return -ENOEXEC if
(bprm-gtjava) return -ENOEXEC bprm-gtjava
1 dput(bprm-gtdentry) bprm-gtdentry
NULL remove_arg_zero(bprm) len strlen
(bprm-gtfilename) if (len gt 6 !strcmp
(bprm-gtfilename len - 6, ".class")) bprm-gtfile
namelen - 6 0
32
java handler - do_load_java
if ((i_name strrchr (bprm-gtfilename, '/')) !
NULL) i_name else i_name
bprm-gtfilename bprm-gtp copy_strings(1,
i_name, bprm-gtpage, bprm-gtp, 2) bprm-gtargc i_
name binfmt_java_interpreter bprm-gtp
copy_strings(1, i_name, bprm-gtpage, bprm-gtp,
2) bprm-gtargc if (!bprm-gtp) return -E2BIG
33
java handler - do_load_java
bprm-gtfilename binfmt_java_interpreter dentry
open_namei(binfmt_java_interpreter, 0,
0) retval PTR_ERR(dentry) if
(IS_ERR(dentry)) return retval bprm-gtdentry
dentry retval prepare_binprm(bprm) if
(retval lt 0) return retval return
search_binary_handler(bprm,regs)
Se ejecuta el intérprete, como se hacía en
do_execve - Comprueba que exista el ejecutable
del intérprete - Prepara los argumentos con
prepare_binprm - Se busca el manejador para el
intérprete (probablemente sea do_load_elf_binary)
34
java handler - load_java
  • De cara al exterior, puede parecer que es la
    función que realiza la ejecución del .class, pero
    realmente solo llama a do_load_java

static int load_java(struct linux_binprm
bprm,struct pt_regs regs) int
retval MOD_INC_USE_COUNT retval
do_load_java(bprm,regs) MOD_DEC_USE_COUNT retu
rn retval
35
FIN
Write a Comment
User Comments (0)
About PowerShow.com