Обновить

44 CVE в uutils: что Rust ловит, а что нет на границе с системой

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели6K
Всего голосов 1: ↑1 и ↓0+1
Комментарии3

Комментарии 3

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

По работе с памятью приколов не навертели и хорошо. А алгоритмы поправят. 😁

Реалистичный паттерн: каждый шрам = новый newtype или smart constructor с приватным полем. Тогда чтобы получить значение, ты обязан пройти через проверку. Это и есть “шрам в сигнатуре”.

Но причём тут Rust? Это как раз проблема Си что он стёр намерения. Rust же даёт возможность фиксировать шрамы в сигнатурах, значит не превратится в легаси.

Советы от LLM, но стоит прислушаться

Самые дешёвые:

1… Правильные базовые типы

  • имена файлов: &Path / &OsStr, не String

  • данные файла: &[u8], не &str, пока UTF-8 не доказан

  • размеры: u64/u128 + checked_* + try_from Это уже сохраняет кучу шрамов.

2… Именованные guard-функции

  • checked_alloc_len(count, elem_size)

  • read_retry_eintr

  • write_all_or_broken_pipe

  • parse_block_size Шрам должен жить не в комментарии, а в одной функции, которую все зовут.

3… enum вместо bool

  • FollowSymlinks::{Never, Cmdline, Always}

  • OverwriteMode::{NoClobber, Force, Interactive} Это дешёвый способ зафиксировать намерение.

4… Newtype с приватным полем

  • BlockSize, MaxDepth, Suffix, LineCount

  • получение только через TryFrom/constructor Шрам переезжает в constructor.

Средние:

5… Разделять сырое и проверенное

  • CliPath

  • ResolvedPath

  • UserPattern

  • ValidatedPattern Не смешивать “пришло снаружи” и “уже проверено”.

6… Модульные границы для опасных тем

  • fs

  • pathbytes

  • locale

  • parse_size

  • tempfile Снаружи не дают делать syscall “как попало”.

7… FD-oriented API

  • openat, fstatat, работа от DirFd

  • меньше TOCTOU и symlink-race Для coreutils это один из самых ценных шрамов.

8… Явные ошибки

  • enum Error { Overflow, InvalidSuffix, InvalidEncoding, … } Тогда знание видно в сигнатуре, а не только в тексте.

Дорогие:

9… Typestate

  • ParsedArgs -> ValidatedArgs

  • Walker<Physical> / Walker<Logical>

  • TempFile<Open> / TempFile<Persisted> Нужно только там, где реально есть фазы.

10… Pure core + thin shell

  • алгоритм отдельно

  • syscalls/CLI/locale отдельно Так шрамы легче закреплять и тесты живут дольше.

11… Изолировать unsafe

  • маленький модуль

  • у каждого unsafe блока // Safety: … Это тоже шрам, но уже текстовый и локальный.

12… Fuzz/property/corpus Не типы, но для coreutils часть шрамов только так и держится.

Если совсем кратко, патч после бага должен оставлять один из трёх следов:

  • новый тип

  • новый constructor/guard

  • новый API-барьер

Топ-3 по ROI для coreutils:

  • не использовать String для путей

  • вся арифметика размеров только через checked wrappers

  • fd/openat стиль вместо “всё через path string”

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

🧮 Модель: #GPT 5.4 Pro

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации