F_DUPFD_CLOEXEC на Redox: безопасное дублирование дескриптора без гонки

17.11.2025

В Redox реализован флаг F_DUPFD_CLOEXEC для fcntl: он дублирует файловый дескриптор и сразу помечает его как закрывающийся при запуске. Обёртка появилась и в relibc.

Какую проблему он снимает

Дескрипторы переживают запуск новых программ. Программа может открыть дескриптор, запустить дочерний процесс, и если дескриптор не помечен как закрывающийся, он достанется ребёнку — вместе со всем, что через него открыто.

Канонический способ избежать этого — флаг FD_CLOEXEC. Но с ним есть гонка: между дублированием дескриптора и установкой флага другой поток может успеть запустить процесс. Окно узкое, но реальное, и в коде, который работает с потоками и запуском процессов, оно выстреливает.

F_DUPFD_CLOEXEC закрывает окно: и дублирование, и установка флага происходят в одном системном вызове.

Как это выглядит на практике

Программа, которая без нужды передаёт дескрипторы собственным детям, накапливает их в потомках. При десятках запусков это десятки лишних открытых файлов, а при тысячах — истощение. Дефект трудно заметить: программа работает, просто незаметно течёт.

Для кода на Rust это тоже актуально: std::process::Command сам устанавливает FD_CLOEXEC на свои дескрипторы, но собственный код приложения, который работает с дескрипторами вручную, от этого не защищён.

Что сделано

Флаг реализован в ядре и добавлен в relibc тем же днём. То есть он доступен и низкоуровнево, и через стандартную библиотеку C.

Отдельно стоит сказать, что в следующем месяце в Redox появился и call с несколькими дескрипторами, а dup2 теперь сбрасывает признак CLOEXEC. Обе правки — часть работы с дескрипторами, и обе касаются одного класса ошибок.

Оригинал

Коммиты Implement F_DUPFD_CLOEXEC от 17 ноября 2025 года в репозитории redox-os/kernel и добавление в redox-os/relibc того же дня; сводка «This Month in Redox — November 2025», раздел «Kernel Improvements»

Упоминаний: 1 · Просмотров: 1