Линус Торвальдс против case-insensitive ФС: почему Unicode усложняет всё

В конце апреля 2025 Линус Торвальдс снова жёстко высказался про регистронезависимость (case insensitivity) в файловых системах на фоне обсуждения Bcachefs. Речь не только об одной ФС: о том, зачем вообще «игнорировать регистр» в мире Unicode и чем это бьёт по безопасности и предсказуемости.

С чего началось

Триггером стало исправление в Bcachefs, связанное с обработкой имён файлов в case-insensitive режиме. Линус отметил, что сюжет старый: разработчики снова и снова пытаются «удобно» схлопнуть File.txt и file.txt, а потом ловят краевые случаи Unicode, несовместимость с приложениями и дыры в модели «это один и тот же путь или нет».

Почему Unicode ломает простую картинку

На бумаге case folding кажется школьной задачей: A → a. В Unicode это огромная таблица правил, исключений, нормализаций (NFC/NFD), совмещённых символов и «почти одинаковых» последовательностей. Сделать folding «для всех сценариев без ошибок» практически нереально: разные стеки (ядро, glibc, пользовательские утилиты, сетевые протоколы) могут по-разному решать, что считается «тем же именем».

Даже визуально близкие символы и последовательности (в т.ч. с variation selector, emoji и т.п.) разные системы трактуют по-разному. Если ФС говорит «это одно имя», а приложение или слой выше «это два», получаются сюрпризы: подмена файлов, обход фильтров, расхождение ACL и ожиданий пользователя.

Зачем вообще case-insensitive

Идея простая: пользователю не думать о регистре, как на старых DOS/Windows/macOS-сценариях. На практике появляется новый класс багов:

  • приложение создаёт Config, ФС «склеивает» с config: тихая порча или неожиданный open;
  • проверки «файл существует / не существует» расходятся между libc, shell и ядром;
  • атакующий подбирает «похожие» имена, которые folding схлопывает неочевидным образом.

Позиция Торвальдса жёсткая: эпоха FAT, где регистронезависимость была вынужденной, прошла. Тащить те же допущения в современные ФС анахронизм с ценой в сложности и security surface.

Регистрозависимость как норма Linux

Классический Linux: A и a разные inode-имена. Это строже для новичка, но проще для кода: сравнение байт/строк, без скрытой семантики «почти как Unicode casefold». Меньше магии в VFS, меньше сюрпризов в бэкапах, rsync, git, контейнерах и кросс-платформенных деревах, где уже и так хватает боли с окончаниями строк и правами.

Совместимость с Windows/macOS-данными отдельная задача (samba, wine, импорт с NTFS/APFS). Решать её лучше явными слоями совместимости, а не размывая модель «имя = уникальная последовательность» по всему ядру.

Вывод

Критика Линуса снова сводится к простому тезису: удобство «не думать о регистре» дорого обходится, когда в игру вступает Unicode и разные реализации folding. Для современных ФС в Linux регистрозависимость не каприз, а способ сохранить однозначность и урезать класс security-багов. Если нужна case-insensitivity для конкретного продукта, это осознанный trade-off, а не «дефолт XXI века».

Исходное обсуждение и формулировки в переписке LKML (ссылка ниже).

Источники и ссылки


Комментарии загружаются…