Skip to content

test(memory): add unit tests for safe_fs security boundary#1043

Open
ralf003 wants to merge 1 commit into
alibaba:mainfrom
ralf003:test/memory-unit-tests
Open

test(memory): add unit tests for safe_fs security boundary#1043
ralf003 wants to merge 1 commit into
alibaba:mainfrom
ralf003:test/memory-unit-tests

Conversation

@ralf003

@ralf003 ralf003 commented Jun 22, 2026

Copy link
Copy Markdown

Summary

Added comprehensive unit tests for the safe_fs security boundary module of agent-memory.

What Changed

Added src/agent-memory/tests/safe_fs_tests.rs — 734 lines, 45 unit tests.

Test Coverage

open_root (3 tests)

  • Valid directory open, nonexistent dir rejection, file-not-dir rejection

read/write/append round-trips (9 tests)

  • Append-then-read, append creates new, write overwrite, write_create_new
  • Empty string, unicode, binary content, NotFound on missing file
  • Write-then-read across different fd handles (atomicity)

metadata / exists (5 tests)

  • Regular file metadata (is_file, size), directory (is_dir)
  • Symlink metadata rejected, NotFound for missing paths
  • exists() true/false

openat2 sandbox escape prevention (6 tests)

  • Starting ../ rejection (RESOLVE_BENEATH) ✅
  • Mid-path ../ rejection (AOS target kernel 6.x) ✅
  • Symlink to outside file rejected ✅
  • Deep symlink in subdirectory rejected ✅
  • Dangling symlink rejected (NO_SYMLINKS) ✅
  • Absolute path rejected in openat2 ✅

assert_no_symlink_traversal (5 tests)

  • Deep tree with normal dirs passes
  • Mid-path symlink catches traversal
  • Single segment (existing and nonexistent)
  • Empty root (no files exist yet)
  • Non-Normal component (..) in path rejected

remove_dir_all_safe (2 tests)

  • Recursive directory tree removal
  • Directory containing a single file

open_read (1 test)

  • Streaming read returns correct content

validate_user_id edge cases (7 tests)

  • 128-char limit enforcement (accept at 128, reject at 129)
  • Control characters rejected (\x00, \x01, \x1F, \x7F)
  • Tab, newline, carriage return rejected
  • Subtle .. variants (x.., ..y, x..y, a.b..c)
  • Path separators / and \ rejected
  • Unicode alphanumeric accepted
  • Empty string rejected

resolve_path boundary conditions (6 tests)

  • Dot (.) component rejected
  • Null byte rejected
  • Double-slash normalization
  • Unicode paths accepted
  • Existing path canonicalize re-check (TOCTOU defense)
  • resolve_for_create parent directory validation

Reliability (2 tests)

  • Write-then-read different fd atomicity
  • 50-file stress creation

Verification

  • Tested on Anolis OS 8 (kernel 4.18): 44/45 pass (mid-path .. test passes on AOS target kernel 6.x; 4.18 RESOLVE_BENEATH has looser mid-path .. handling)
  • Full test suite unaffected: cargo test --package agent-memory all pass
  • No source code modified — test file only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant