Может ли программа перехватывать доступ к определенным областям памяти процесса?

It sounds like the alternative implementation of pivot_root() would put the calling process in a new, altered mount namespace. Is that a valid reading?

No. En mi opinión, esto no está muy claro, pero hay una lectura mucho más consistente y correcta.

La parte esencial de pivote _raíz (), que debe ser la misma en cualquier implementación, es:

pivot_root() moves the root filesystem of the calling process to the directory put_old and makes new_root the new root filesystem of the calling process.

La ​​parte esencial de pivote _raíz ()no se limita solo al proceso de llamada. La operación descrita en esta cita funciona en el espacio de nombres de montaje del proceso de llamada. Afectará la vista de todos los procesos en el mismo espacio de nombres de montaje.

Considere el efecto que tiene el cambio esencial en un segundo proceso -o subproceso del núcleo -cuyo directorio de trabajo era el antiguo sistema de archivos raíz. Su directorio actual seguirá siendo el antiguo sistema de archivos raíz. Esto mantendrá ocupado el punto de montaje /put_oldy, por lo tanto, no será posible desmontar el antiguo sistema de archivos raíz.

Si controla este segundo proceso, resuelva esto, según la página de manual, configurando su directorio de trabajo en la nueva raíz _antes de que se llame a la raíz ()del pivote _. Después de llamar a pivote _raíz (), su directorio actual seguirá siendo el nuevo sistema de archivos raíz.

Entonces, el proceso S (ystemd )se configuró para señalar al proceso P (lymouth ), para cambiar el directorio de trabajo antes de que S llame a pivot _root (). No hay problema. Pero también tenemos subprocesos del núcleo, que comienzan en /. La implementación actual de pivot _root ()se ocupa de los subprocesos del kernel por nosotros; es equivalente a configurar los directorios de trabajo de los subprocesos del kernel y cualquier otro proceso en new_rootantes de la parte esencial de pivot _root ().

Excepto, la implementación actual de pivot _root ()solo cambia el directorio de trabajo de un proceso si el directorio de trabajo anterior era /. Entonces, en realidad es bastante fácil ver la diferencia que esto hace:

$ unshare -rm
# cd /tmp    # work in a subdir instead of '/', and pivot_root() will not change it
# /bin/pwd
/tmp
# mount --bind /new-root /new-root
# pivot_root /new-root /new-root/mnt
# /bin/pwd
/mnt/tmp    # see below: if pivot_root had not updated our current chroot, this would still show /tmp

vs.

$ unshare -rm
# cd /
# /bin/pwd
/
# ls -lid.
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jun 13 01:17.
# ls -lid /newroot
6424395 dr-xr-xr-x. 20 nfsnobody nfsnobody 4096 May 10 12:53 /new-root
# mount --bind /new-root /new-root
# pivot_root /new-root /new-root/mnt
# /bin/pwd
/
# ls -lid.
6424395 dr-xr-xr-x. 20 nobody nobody 4096 May 10 12:53.
# ls -lid /
6424395 dr-xr-xr-x. 20 nobody nobody 4096 May 10 12:53 /
# ls -lid /mnt
2 dr-xr-xr-x. 19 nobody nobody 4096 Jun 13 01:17 /mnt

Ahora entiendo lo que sucede con el directorio de trabajo, me resulta más fácil entender lo que sucede con chroot (). El chroot actual del proceso que llama a pivot _root ()puede ser una referencia al sistema de archivos raíz original, tal como puede ser su directorio de trabajo actual.

Tenga en cuenta que si hace chdir ()+pivot _root ()pero olvidó hacer chroot (), su directorio actual estaría fuera de su chroot actual. Cuando su directorio actual está fuera de su chroot actual, las cosas se vuelven bastante confusas. Probablemente no desee ejecutar su programa en este estado.

# cd /
# python
>>> import os
>>> os.chroot("/newroot")
>>> os.system("/bin/pwd")
(unreachable)/
0
>>> os.getcwd()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory
>>> os.system("ls -l./proc/self/cwd")
lrwxrwxrwx. 1 root root 0 Jun 17 13:46./proc/self/cwd -> /
0
>>> os.system("ls -lid./proc/self/cwd/")
2 dr-xr-xr-x. 19 root root 4096 Jun 13 01:17./proc/self/cwd/
0
>>> os.system("ls -lid /")
6424395 dr-xr-xr-x. 20 root root 4096 May 10 12:53 /
0

POSIX no especifica el resultado de pwdo getcwd ()en esta situación :). POSIX no advierte que podría obtener un error "No existe tal archivo o directorio" (ENOENT )de getcwd (). Las páginas de manual de Linux señalan que este error es posible, si el directorio de trabajo se desvinculó (, p. conrm). Creo que este es un muy buen paralelo.

1
26.07.2019, 23:26
1 ответ
  1. Да

  2. Поместите переменные в отдельную страницу памяти,вероятно, с помощью скрипта компоновщика. Используйте mprotect, чтобы пометить страницу как no access. Используйте sigactionдля настройки обработчика SIGSEGV, укажите SA _SIGINFO, чтобы получить информацию о задействованном адресе.

  3. Никаких особых привилегий не требуется.

  4. Это делалось много раз. Первоначальная оболочка Bourne перехватывала SIGSEGV для управления памятью, но это было до дней sigaction. В вашем обработчике вы можете делать все, что необходимо, чтобы все исправить и вернуться. Обычно для этого требуется достаточное количество знаний о шаблонах доступа и сгенерированном машинном коде.

1
27.01.2020, 23:41

Теги

Похожие вопросы