TGViewer
BashTex | Linux BashTex | Linux @bash_tex · 2.51K subscribers
Post #668 69
openat2(): как Linux защищает от выхода за пределы каталога

Допустим, приложение должно читать файлы только из /srv/uploads. Пользователь передаёт имя файла, а программа открывает его.

На первый взгляд достаточно проверить путь. Но если внутри каталога есть символические ссылки, всё становится сложнее.

▪️В чём проблема
Например, пользователь передаёт:

documents/report.pdf


Приложение проверяет, что путь находится внутри /srv/uploads, а затем вызывает open().

Но между проверкой и открытием файла кто-то может заменить один из каталогов символической ссылкой на /etc.

Получается классическая TOCTOU-проблема: проверили один объект, а открыли уже другой.

▪️Что меняет openat2()

В Linux есть системный вызов openat2(), который позволяет задать ограничения прямо во время разрешения пути.

Например:

struct open_how how = {
.flags = O_RDONLY,
.resolve = RESOLVE_BENEATH |
RESOLVE_NO_SYMLINKS
};


Здесь два важных ограничения:

RESOLVE_BENEATH - запрещает разрешение пути за пределами указанного каталога.

RESOLVE_NO_SYMLINKS - запрещает проходить через символические ссылки в любом компоненте пути.

▪️Как открыть файл

Сначала приложение получает дескриптор каталога:

int dirfd = open("/srv/uploads",
O_PATH | O_DIRECTORY);


Затем открывает файл относительно него:

int fd = syscall(SYS_openat2,
dirfd,
"documents/report.pdf",
&how,
sizeof(how));


Теперь ядро проверяет ограничения непосредственно при разрешении пути.

Если один из компонентов окажется символической ссылкой, операция завершится ошибкой.

▪️А если символические ссылки нужны?

Полностью запрещать их необязательно.

Можно использовать:

.resolve = RESOLVE_IN_ROOT


В этом режиме указанный каталог становится временным корнем для разрешения пути. Даже абсолютные пути и переходы через .. интерпретируются относительно него.

Это полезно, когда приложению нужно работать с деревом файлов, не позволяя обращаться к объектам за его пределами.

▪️Почему это важно
Обычная проверка строки пути не гарантирует безопасность: файловая система может измениться между проверкой и открытием.

openat2() позволяет перенести ограничения на уровень ядра и избежать многих ошибок при работе с недоверенными путями. При этом это не полноценная песочница: ограничения действуют на конкретное открытие файла, а не на все действия процесса.

BashTex 📱 #bash #linux
  • 👍 3
More from @bash_tex
  1. Oct 12, 2026xargs против while read: где быстрее и безопаснее Обе конструкции позволяют обработать спи…
  2. Oct 9, 2026BashTex 📱 #мем
  3. Oct 8, 2026Bridge FDB - как Linux bridge узнаёт, где находится MAC Linux bridge не знает заранее, за…
  4. Oct 7, 2026/dev/tcp - сетевое соединение средствами Bash В Bash есть малоизвестная возможность работа…
  5. Oct 6, 2026Ephemeral ports - почему заканчиваются исходящие TCP-порты Когда приложение устанавливает…
  6. Oct 5, 2026name_to_handle_at() - как получить файловый объект без обычного пути В Linux обычно обраща…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →