1.0.3

Fixed (#365)

  • На Linux-сборках (с v0.33.0, ccbf162) инструменты read_file/edit_file/grep не могли открыть ни один файл — «path escapes base directory» (#365): safeopen_linux.go вызывал openat2(AT_FDCWD, абсолютный_путь, RESOLVE_BENEATH), а по openat2(2) RESOLVE_BENEATH отклоняет любой абсолютный path с EXDEV; FsGuard.resolve() всегда возвращает абсолютный путь, поэтому каждая попытка открытия была обречена (запись/листинг не используют safeopen, потому работали; на macOS/Windows другие реализации — локальная разработка на darwin баг не ловила). RESOLVE_BENEATH убран (контейнмент остаётся in-process: FsGuard.resolve + isUnder), сохранены RESOLVE_NO_MAGICLINKS|RESOLVE_NO_SYMLINKS и O_NOFOLLOW; добавлен ENOSYS-fallback на plain open для ядер без openat2 (< 5.6); мёртвая EXDEV-ветка удалена. Регрессионный тест safeopen_linux_test.go (//go:build linux); прогон в Docker golang:1.25.5: со старым кодом тест падает ровно с продакшен-ошибкой, с фиксом весь suite internal/security зелёный. Дочернее ужесточение: NewFsGuard канонизирует workspace через filepath.EvalSymlinksresolve()/isUnder() сравнивают каноничные пути, workspace за симлинком больше не отсекает собственные файлы как «outside workspace».