Skip to content

fix: include character device files in policy group resolution#218

Merged
lukehinds merged 1 commit intoalways-further:mainfrom
pierres:fix/character-device-policy-resolution
Mar 3, 2026
Merged

fix: include character device files in policy group resolution#218
lukehinds merged 1 commit intoalways-further:mainfrom
pierres:fix/character-device-policy-resolution

Conversation

@pierres
Copy link
Contributor

@pierres pierres commented Mar 3, 2026

Summary

add_fs_capability() in the CLI policy resolver gated non-directory paths on path.is_file(). Rust's Path::is_file() returns false for character devices, so device files listed in policy groups (/dev/urandom, /dev/null, /dev/zero, /dev/random, /dev/full, /dev/tty, /dev/console) were silently dropped from the capability set.

This is the CLI-side counterpart to #138, which fixed the same is_file() check in the library's FsCapability::new_file(). The library fix was necessary but insufficient — the CLI policy resolver dropped device paths before they ever reached the library.

Reproduction

nono run --profile claude-code --allow-cwd -- claude -v

Bun (which Claude Code and opencode are built on) segfaults at 0xBBADBEEF:

panic(main thread): Segmentation fault at address 0xBBADBEEF
oh no: Bun has crashed.

strace shows the cause — /dev/urandom is blocked by Landlock, and Bun crashes immediately after:

openat(AT_FDCWD, "/dev/urandom", O_RDONLY) = -1 EACCES (Permission denied)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xbbadbeef} ---

Bun uses open("/dev/urandom") rather than the getrandom(2) syscall, so Landlock enforcement on the device file path applies.

Fix

Changed the else if path.is_file() branch to else, matching the library's FsCapability::new_file() which rejects only directories. After the fix, the verbose capability list shows 31 system/group paths (was 24 — the 7 missing were all character devices).

Test plan

  • Added test_resolve_character_device_files — verifies device files in a policy group are resolved into capabilities
  • Added test_embedded_policy_includes_device_files — verifies the real system_read_linux group includes /dev/urandom, /dev/null, /dev/zero, /dev/random
  • Both tests fail without the fix, pass with it
  • cargo clippy --workspace --all-targets --all-features -- -D warnings -D clippy::unwrap_used passes
  • cargo fmt --all -- --check passes
  • cargo test --workspace passes (one pre-existing flaky failure in test_check_sensitive_path unrelated to this change)
  • Manual verification: nono run --profile claude-code --allow-cwd -- claude -v succeeds

Fixes #154 (Bun segfault component — the /$bunfs virtual path issue is separate)

@github-actions github-actions bot added the bug Something isn't working label Mar 3, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the nono-cli policy resolver where character device files, such as /dev/urandom, were mistakenly omitted from Landlock policy groups. This omission occurred because Rust's Path::is_file() method returns false for these device types, causing the CLI to silently drop them. The fix modifies the capability resolution logic to correctly include all non-directory paths, preventing applications like Bun from crashing due to permission denied errors on essential device files.

Highlights

  • Character Device File Resolution: Resolved an issue where character device files (e.g., /dev/urandom) were incorrectly excluded from policy groups due to Path::is_file() returning false for them.
  • Policy Resolver Logic Update: Modified the add_fs_capability function in nono-cli to accept all non-directory paths, aligning its behavior with FsCapability::new_file() which only rejects directories.
  • New Test Coverage: Introduced two new tests, test_resolve_character_device_files and test_embedded_policy_includes_device_files, to ensure character devices are correctly resolved into capabilities within policy groups.
Changelog
  • crates/nono-cli/src/policy.rs
    • Modified the add_fs_capability function to no longer gate on path.is_file() for non-directory paths, ensuring character devices are included.
    • Removed a debug log message for paths that are neither files nor directories, as the new logic handles them.
    • Added test_resolve_character_device_files to verify that character device files specified in policy groups are correctly resolved.
    • Added test_embedded_policy_includes_device_files to confirm that essential device files like /dev/urandom are present in the system_read_linux group's capabilities.
Activity
  • Added test_resolve_character_device_files to verify device files in policy groups are resolved into capabilities.
  • Added test_embedded_policy_includes_device_files to verify the system_read_linux group includes /dev/urandom, /dev/null, /dev/zero, /dev/random.
  • Confirmed both new tests fail without the fix and pass with it.
  • Ensured cargo clippy --workspace --all-targets --all-features -- -D warnings -D clippy::unwrap_used passes.
  • Ensured cargo fmt --all -- --check passes.
  • Ensured cargo test --workspace passes (noting one pre-existing flaky failure unrelated to this change).
  • Manually verified the fix by running nono run --profile claude-code --allow-cwd -- claude -v, which now succeeds.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

`add_fs_capability()` gated non-directory paths on `path.is_file()`.
Rust's `Path::is_file()` returns false for character devices, so
/dev/urandom, /dev/null, etc. were silently dropped from the capability
set despite being listed in policy groups.

Align with FsCapability::new_file(), which already accepts any
non-directory path since always-further#138.

Signed-off-by: Pierre Schmitz <[email protected]>
@pierres pierres force-pushed the fix/character-device-policy-resolution branch from 3342444 to 8dc16ff Compare March 3, 2026 11:09
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses the issue where character device files were not being correctly included in policy group resolution due to an incorrect is_file() check. The change to add_fs_capability to treat all non-directory paths as files, aligning with FsCapability::new_file(), is a precise and correct fix. The addition of dedicated tests for character device files significantly improves the robustness of the policy resolver. The changes are well-reasoned and thoroughly tested.

@lukehinds lukehinds merged commit ce66102 into always-further:main Mar 3, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to start opencode on ubuntu 24.04.1

2 participants