Skip to content

fix(security): cap persistent file descriptors - #1780

Merged
chaliy merged 1 commit into
mainfrom
2026-05-26-threat-model-fd-limits
May 26, 2026
Merged

chaliy merged 1 commit into
mainfrom
2026-05-26-threat-model-fd-limits

Conversation

@chaliy

@chaliy chaliy commented May 26, 2026

Copy link
Copy Markdown
Contributor

What

Adds a first-class persistent file descriptor limit for Bashkit exec redirections and updates the threat model/docs. Also fixes N>&- parsing so output-fd close is modeled distinctly from input-fd close.

Why

Persistent custom fds are session state. Without a cap, scripts can grow fd tables/buffers across many exec N>... calls.

How

  • Adds ExecutionLimits::max_file_descriptors with a default of 1024.
  • Checks persistent fd capacity before opening/duplicating custom fds.
  • Keeps standard fds 0/1/2 and fd reuse/close from consuming extra slots.
  • Adds threat-model coverage as TM-DOS-063 and caller-risk guidance for rendered HTML output.
  • Adds regression tests for fd exhaustion and fd reuse/close.

Risk

  • Low
  • Scripts that intentionally keep more than 1024 custom persistent fds open now fail with a resource limit error.

Checklist

  • Tests added or updated
  • Backward compatibility considered

Verified:

  • just pre-pr

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit ed6d90a Commit Preview URL May 26 2026, 04:27 AM

@chaliy
chaliy merged commit 78ec5b2 into main May 26, 2026
37 checks passed
@chaliy
chaliy deleted the 2026-05-26-threat-model-fd-limits branch May 26, 2026 04:39
@chaliy chaliy mentioned this pull request May 27, 2026
6 tasks
chaliy added a commit that referenced this pull request May 27, 2026
## Summary

Maintenance release rolling up 50 commits since v0.7.1.

## Highlights

- **Maintenance release** — rolls up ~25 `rg` hardening fixes, a CoW
subshell-snapshot perf landmark (#1767), security tightening (FD cap
#1780, tool-hook enforcement for `command` #1781), a `BuiltinHelper`
refactor (#1788), and test/build hygiene work.

## Publish-readiness report

| Check | Result |
|-------|--------|
| `cargo fmt --check` | clean |
| `cargo clippy --all-targets -- -D warnings` | clean |
| `cargo test --features http_client` | 2965 pass (environmental rg-diff
failure resolved with pinned ripgrep 15.1) |
| `cargo publish --dry-run -p bashkit` (with CI's monty strip) |
succeeds |
| `cargo publish --dry-run -p bashkit-cli` | packaging succeeds;
resolution fails only because bashkit 0.7.2 isn't on crates.io yet
(chicken-and-egg, resolves post-merge per `publish.yml`) |
| Version sync (Cargo.toml, bashkit-cli/Cargo.toml,
bashkit-js/package.json, Cargo.lock) | all 0.7.2 |
| Registry version checks (crates.io / npm / PyPI) | all currently
0.7.1; 0.7.2 > 0.7.1 |

## Test plan

- [ ] CI green on this PR
- [ ] Merge → `release.yml` creates GitHub Release + tag `v0.7.2`
- [ ] `publish.yml` publishes bashkit + bashkit-cli to crates.io
- [ ] `publish-python.yml` publishes wheels to PyPI
- [ ] `publish-js.yml` publishes `@everruns/bashkit` to npm
- [ ] `cli-binaries.yml` ships prebuilt binaries and bumps Homebrew tap
chaliy added a commit that referenced this pull request May 30, 2026
## What
Adds a first-class persistent file descriptor limit for Bashkit exec
redirections and updates the threat model/docs. Also fixes `N>&-`
parsing so output-fd close is modeled distinctly from input-fd close.

## Why
Persistent custom fds are session state. Without a cap, scripts can grow
fd tables/buffers across many `exec N>...` calls.

## How
- Adds `ExecutionLimits::max_file_descriptors` with a default of 1024.
- Checks persistent fd capacity before opening/duplicating custom fds.
- Keeps standard fds 0/1/2 and fd reuse/close from consuming extra
slots.
- Adds threat-model coverage as TM-DOS-063 and caller-risk guidance for
rendered HTML output.
- Adds regression tests for fd exhaustion and fd reuse/close.

## Risk
- Low
- Scripts that intentionally keep more than 1024 custom persistent fds
open now fail with a resource limit error.

## Checklist
- [x] Tests added or updated
- [x] Backward compatibility considered

Verified:
- `just pre-pr`
chaliy added a commit that referenced this pull request May 30, 2026
## Summary

Maintenance release rolling up 50 commits since v0.7.1.

## Highlights

- **Maintenance release** — rolls up ~25 `rg` hardening fixes, a CoW
subshell-snapshot perf landmark (#1767), security tightening (FD cap
#1780, tool-hook enforcement for `command` #1781), a `BuiltinHelper`
refactor (#1788), and test/build hygiene work.

## Publish-readiness report

| Check | Result |
|-------|--------|
| `cargo fmt --check` | clean |
| `cargo clippy --all-targets -- -D warnings` | clean |
| `cargo test --features http_client` | 2965 pass (environmental rg-diff
failure resolved with pinned ripgrep 15.1) |
| `cargo publish --dry-run -p bashkit` (with CI's monty strip) |
succeeds |
| `cargo publish --dry-run -p bashkit-cli` | packaging succeeds;
resolution fails only because bashkit 0.7.2 isn't on crates.io yet
(chicken-and-egg, resolves post-merge per `publish.yml`) |
| Version sync (Cargo.toml, bashkit-cli/Cargo.toml,
bashkit-js/package.json, Cargo.lock) | all 0.7.2 |
| Registry version checks (crates.io / npm / PyPI) | all currently
0.7.1; 0.7.2 > 0.7.1 |

## Test plan

- [ ] CI green on this PR
- [ ] Merge → `release.yml` creates GitHub Release + tag `v0.7.2`
- [ ] `publish.yml` publishes bashkit + bashkit-cli to crates.io
- [ ] `publish-python.yml` publishes wheels to PyPI
- [ ] `publish-js.yml` publishes `@everruns/bashkit` to npm
- [ ] `cli-binaries.yml` ships prebuilt binaries and bumps Homebrew tap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant