You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Five P2 review findings on commit 6118ec3 (the round-2 P1 TOCTOU fix was
accepted). Bounded fixes:
- Committed-audit completeness: a committed `DELETE FROM t` (no WHERE) was
missing from the committed stream because the truncate optimization skips
sqlite3_update_hook (sqlite3.h documents this). The authorizer now returns
SQLITE_IGNORE for a user-table SQLITE_DELETE, which SQLite defines as
"proceed, but delete row-by-row" — disabling the truncate optimization so
the hook fires. DDL/internal `sqlite_*` deletes stay OK (DDL is reported as
a DELETE on sqlite_master). `allowed` is now `decision != SQLITE_DENY` so
IGNORE still records an allowed attempt. ON CONFLICT REPLACE deletes remain
hook-invisible — documented as preupdate-hook territory (open-knob #4).
- `.tables` now unions `sqlite_temp_schema`, so TEMP tables/views (which the
authorizer allows) are listed, matching the real sqlite3 shell.
- Open intent: a non-read-only open of an *existing* DB now reports `.write`
(was always `.create`), so a Kit `authorize` closure can permit writes to
an existing file while denying new-file creation.
- Cancellation: `run` now calls `Task.checkCancellation()` before the first
step. A task cancelled before any sqlite3_step would otherwise run to
completion (onCancel's interrupt() is a no-op when nothing is in flight).
Documented, not fixed (bounded): unbounded stdin is buffered before the
SQL-length cap applies (open-knob #5; needs an incremental capped read).
Tests: committed DELETE FROM t appears in the committed stream; `.tables`
lists a TEMP table.
Copy file name to clipboardExpand all lines: PLAN.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -317,7 +317,8 @@ public extension Shell {
317
317
1.**Journal mode** — WAL (best concurrency; `-wal`/`-shm` siblings) vs rollback (`-journal`; simplest). Both fine on native I/O.
318
318
2.**M7 shim VFS** — ship now vs defer (recommended: defer; §5 confinement is closed/enumerable without it). Partial symlink-race hardening is already in place: the **DB open** canonicalizes before `authorize` and opens with `SQLITE_OPEN_NOFOLLOW`, which is race-free (SQLite rejects the open if any component became a symlink after authorization). Two residual TOCTOU gaps are explicitly **M7-scope**: (a) the **audit-log append** uses leaf-only `O_NOFOLLOW`, so a *parent-directory* swapped to a symlink after authorization is still followed (needs `openat`-style walking from a trusted root fd); and (b) **WAL `-wal`/`-shm` sidecars** aren't separately authorized, so a Kit caller whose `authorize` grants a single file rather than its directory could see siblings created next to it.
319
319
3.**`:memory:`** — the supported answer for in-memory/non-identity-mount callers that can't use a host file URL.
320
-
4.**Value-level audit** — enable `SQLITE_ENABLE_PREUPDATE_HOOK` if old/new row values are needed (vs. table+rowid only).
320
+
4.**Value-level audit** — enable `SQLITE_ENABLE_PREUPDATE_HOOK` if old/new row values are needed (vs. table+rowid only). It is also the way to capture the remaining committed-DELETE case: the authorizer returns `SQLITE_IGNORE` for `SQLITE_DELETE` so `DELETE FROM t` is deleted row-by-row (defeating the truncate optimization) and thus seen by `sqlite3_update_hook`, but rows deleted via `ON CONFLICT REPLACE` are still not reported by the update hook — only the preupdate hook sees those.
321
+
5.**Bounded stdin** — SQL piped on stdin is currently read fully into memory before `SQLITE_LIMIT_SQL_LENGTH` (a prepare-time cap) applies. An incremental, capped stdin read (rejecting input past `EnginePolicy.maxSQLLength` as it's consumed) is a follow-up for hardening against a large-pipe memory DoS.
321
322
322
323
## 14. References (SwiftBash files this design mirrors)
0 commit comments