Leí que el descriptor de proceso en Linux (en x86) se almacena en el segmento de datos del kernel pero en una dirección debajo de PAGE_OFFSET (es decir, en el espacio de direcciones de usuario). Dado que el segmento de datos del kernel y los segmentos de datos del usuario cubren el espacio completo de direcciones de 4 GB, entonces, presumiblemente, sería posible acceder al descriptor del proceso a través del segmento de datos del usuario, si su dirección fuera conocida por el código de usuario. ¿Es esto correcto, y si es así, no es un agujero de seguridad?
Una pregunta relacionada: hubo una afirmación de que la dirección lineal del descriptor del proceso puede servir como un ID de proceso único. Sin embargo, como las direcciones lineales se traducen usando la tabla de páginas, y la tabla de páginas es diferente para cada proceso para las direcciones debajo de PAGE_OFFSET, ¿no podrían dos procesos almacenar sus descriptores de proceso en la misma dirección lineal?
En Linux, el "descriptor de proceso" es struct task_struct [y algunos otros]. Estos se almacenan en el espacio de direcciones del núcleo [por encima de PAGE_OFFSET ] y no en el espacio de usuario.
Esto es más relevante para kernels de 32 bits donde PAGE_OFFSET se establece en 0xc0000000.
En un kernel de 32 bits, el espacio de direcciones virtuales de un proceso de usuario estaba limitado a PAGE_OFFSET
Los núcleos de 64 bits son algo diferentes y el límite no importa tanto. PAGE_OFFSET es 0xffff880000000000
Además, el núcleo tiene una sola asignación de espacio de direcciones propia.
Cada proceso/subproceso tiene su propio espacio de direcciones virtuales, que, salvo la memoria compartida para las bibliotecas .so y la memoria compartida para los subprocesos, es única. No se asigna a nada en el espacio de direcciones del núcleo.
Incluso con [si hubiera] una asignación de espacio de direcciones común, las páginas del kernel están protegidas contra lectura/escritura del proceso del usuario.
Una pregunta relacionada:
Estas son realmente dos preguntas.
hubo una afirmación de que la dirección lineal del descriptor del proceso puede servir como un ID de proceso único.
No. Esto no se puede hacer por varias razones.
Sólo el núcleo tiene acceso a (es decir, "conoce") la dirección task_struct .
En segundo lugar, si un proceso finaliza, es un zombi hasta que el proceso principal lo "cosecha" a través de una wait . El núcleo debe recordar qué procesos son zombis (es decir, sus pids no se reutilizarán para un nuevo proceso) hasta que el padre los coseche.
Sin embargo, task_struct es bastante grande. Entonces, cuando un proceso ingresa a zombie, el kernel toma una pequeña porción de los datos de task_struct (por ejemplo, pid y status ) y los guarda en una estructura "zombie". El kernel puede entonces reutilizar task_struct [usando un pid diferente ] casi inmediatamente.
Por ejemplo, mientras que un proceso con pid 37 puede haber tenido una estructura de tarea en la dirección (p. ej.) 0x1000 mientras se estaba ejecutando, después de la finalización, pero antes de cosechar, el pid 37 no tiene una dirección de estructura de tarea y la estructura de tarea en 0x1000 ya podría estar asignada a pid 23727
Sin embargo, como las direcciones lineales se traducen usando la tabla de páginas, y la tabla de páginas es diferente para cada proceso para las direcciones debajo de PAGE_OFFSET, ¿no podrían dos procesos almacenar sus descriptores de proceso en la misma dirección lineal?
Una vez más, no.