Какую команду вы используете для установки значения по умолчанию? Вы можете установить его через команду systemctl:
systemctl set-default multi-user.target
Или с помощью ссылки default.target:
ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'
Сначала рассмотрим реализацию FUSE no_allow_others
.
Требуется, чтобы действующие, реальные и сохраненные UID (идентификаторы пользователя )совпадали. (И то же самое для GID ). Это преднамеренно предотвращает доступ установленной -UID-программы к монтированию.
https://github.com/torvalds/linux/blob/v4.18/fs/fuse/dir.c#L1024
Calling into a user-controlled filesystem gives the filesystem
daemon ptrace-like capabilities over the current process. This
means, that the filesystem daemon is able to record the exact
filesystem operations performed, and can also control the behavior
of the requester process in otherwise impossible ways. For example
it can delay the operation for arbitrary length of time allowing
DoS against the requester.
Теперь давайте проследим, что делает fusermount
. Мы можем попробовать посмотреть на
strace -f bindfs...
и
sudo perf trace -o trace.txt -a sleep 2; sleep 1; bindfs...
Первый выдает фатальную ошибку «Отказано в доступе», потому что установленный -UID root не работает при работе под strace
. Второй преуспевает, но не может отображать строковые параметры, такие как пути. Я думаю, что две трассировки показывают один и тот же общий путь кода до фатальной ошибки. Это означает, что мы можем использовать результаты strace
для заполнения отсутствующих строковых параметров.
Последний вызов в результатах strace
—:
[pid 30609] mount("/home/alan-sysop/mnt", ".", "fuse", MS_NOSUID|MS_NODEV, "default_permissions,fd=5,rootmod"...) = -1 EPERM (Operation not permitted)
Интересно! "."
означает текущий каталог. Так что fusermount
должно быть уже работало в точке монтирования... каким-то образом. Этот трюк иногда можно использовать для доступа к каталогу, к которому вы в настоящее время не можете получить доступ, используя его абсолютный путь.
Если мы прокрутим вверх, то увидим, что fusermount
действительно перешел в этот каталог. И это также было связано с некоторыми системными вызовами, связанными с UID -(и связанными с GID -).
[pid 30609] getuid() = 1000
[pid 30609] setfsuid(1000) = 1000
[pid 30609] getgid() = 1000
[pid 30609] setfsgid(1000) = 1000
[pid 30609] openat(AT_FDCWD, "/etc/fuse.conf", O_RDONLY) = 6
...
[pid 30609] lstat("/home/alan-sysop/mnt", {st_mode=S_IFDIR|0775, st_size=4096,...}) = 0
[pid 30609] getuid() = 1000
[pid 30609] chdir("/home/alan-sysop/mnt") = 0
[pid 30609] lstat(".", {st_mode=S_IFDIR|0775, st_size=4096,...}) = 0
[pid 30609] access(".", W_OK) = 0
[pid 30609] getuid() = 1000
[pid 30609] setfsuid(1000) = 1000
[pid 30609] setfsgid(1000) = 1000
Результаты UID "неправильные" в сеансе strace
. Мы можем лучше увидеть танцевальную часть UID в сеансе perf trace
. (Я удалил левые -большинство столбцов для удобочитаемости ).
getuid( ) = 1000
setfsuid(uid: 1000 ) = 0
getgid( ) = 1000
setfsgid(gid: 1000 ) = 1000
openat(dfd: CWD, filename: 0xa428e2bc ) = 6
...
close(fd: 6 ) = 0
lstat(filename: 0xa63882a0, statbuf: 0x7ffe7bd4f6d0 ) = 0
getuid( ) = 1000
chdir(filename: 0xa63882a0 ) = 0
lstat(filename: 0xa428eca5, statbuf: 0x7ffe7bd4f6d0 ) = 0
access(filename: 0xa428eca5, mode: W ) = 0
getuid( ) = 1000
setfsuid( ) = 1000
setfsgid(gid: 1000 ) = 1000
getuid( ) = 1000
Вызовы setfsuid()
находятся в функциях drop_privs()
и restore_privs()
в fusermount.c .
Вызов chdir()
незаметно скрыт в функции с именем check_perm()
.
Почему это работает в NFS? Ответьте :, потому что NFS просматриваетfsuid
(и fsgid
), для которых задан корневой UID, отличный от -.
Почему это не работает на FUSE, если у вас нет allow_others
? Ответьте :, потому что FUSE проверяет «настоящий» UID, а не fsuid
.