Restore gets three ordering steps wrong. Each one leaves a restore that differs from what the README promises: "Preserves file permissions, timestamps, ownership (ownership requires root), symlinks, and empty directories" (README.md:367-368, also :489).
Directory mode is set before the children are written. Directories go on the ready queue first (internal/vaultik/restore_plan.go:58-65) and get their stored mode at once (internal/vaultik/restore.go:1003-1013). Their children are created later (restore.go:1080-1086). Measured on next at 0700901: restoring a 0555 directory holding one file, as uid 1000, fails with creating output file: ... permission denied. With --skip-errors, the files inside are simply not restored. Read-only trees such as a Go module cache are common.
Directory time is set before the children are written (restore.go:1015). Creating the children then bumps the directory's mtime. Measured: a non-empty directory came back with the time of the restore, while the file inside kept its stored 2001-02-03.
Mode is applied before ownership (restore.go:1117-1118; the chown is at :1030). On Linux, chown clears the setuid and setgid bits of a regular file, so a restore as root loses them on sudo, ping and the like. Observed unprivileged on this host: mode 4755 became 755 after a same-owner chown. The root case was not run.
Symlinks get no owner and no time.restoreSymlink (internal/vaultik/restore.go:977-996) skips both, so a restore as root leaves every symlink owned by root. Since #216 the scanner records the right symlink owner.
Definition of done
Ownership is applied before mode, so setuid and setgid survive a restore as root.
A directory's mode and times are applied after everything inside it has been written.
A symlink restored as root gets its recorded owner (Lchown), and its recorded mtime where the platform supports it.
Tests, run as a normal user: a read-only directory with a file inside restores completely; a non-empty directory keeps its stored mtime; a setuid file restored by a same-owner restore keeps its mode bits.
make check passes.
Model: fable-5-1 (audit); opus-5-5 (issue)
Restore gets three ordering steps wrong. Each one leaves a restore that differs from what the README promises: "Preserves file permissions, timestamps, ownership (ownership requires root), symlinks, and empty directories" (`README.md:367-368`, also `:489`).
- **Directory mode is set before the children are written.** Directories go on the ready queue first (`internal/vaultik/restore_plan.go:58-65`) and get their stored mode at once (`internal/vaultik/restore.go:1003-1013`). Their children are created later (`restore.go:1080-1086`). Measured on `next` at `0700901`: restoring a `0555` directory holding one file, as uid 1000, fails with `creating output file: ... permission denied`. With `--skip-errors`, the files inside are simply not restored. Read-only trees such as a Go module cache are common.
- **Directory time is set before the children are written** (`restore.go:1015`). Creating the children then bumps the directory's mtime. Measured: a non-empty directory came back with the time of the restore, while the file inside kept its stored 2001-02-03.
- **Mode is applied before ownership** (`restore.go:1117-1118`; the chown is at `:1030`). On Linux, `chown` clears the setuid and setgid bits of a regular file, so a restore as root loses them on `sudo`, `ping` and the like. Observed unprivileged on this host: mode 4755 became 755 after a same-owner chown. The root case was not run.
- **Symlinks get no owner and no time.** `restoreSymlink` (`internal/vaultik/restore.go:977-996`) skips both, so a restore as root leaves every symlink owned by root. Since https://git.eeqj.de/sneak/vaultik/issues/216 the scanner records the right symlink owner.
## Definition of done
1. Ownership is applied before mode, so setuid and setgid survive a restore as root.
2. A directory's mode and times are applied after everything inside it has been written.
3. A symlink restored as root gets its recorded owner (`Lchown`), and its recorded mtime where the platform supports it.
4. Tests, run as a normal user: a read-only directory with a file inside restores completely; a non-empty directory keeps its stored mtime; a setuid file restored by a same-owner restore keeps its mode bits.
5. `make check` passes.
Model: fable-5-1 (audit); opus-5-5 (issue)
clawbot
self-assigned this 2026-10-06 01:49:42 +02:00
Fixed in #245. Directories are created owner-only and get their stored owner, mtime and mode after the restore loop, deepest first. A file is chowned before its mode is set, and a symlink gets its owner (as root) and mtime on the link itself.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/vaultik/pulls/245. Directories are created owner-only and get their stored owner, mtime and mode after the restore loop, deepest first. A file is chowned before its mode is set, and a symlink gets its owner (as root) and mtime on the link itself.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Restore gets three ordering steps wrong. Each one leaves a restore that differs from what the README promises: "Preserves file permissions, timestamps, ownership (ownership requires root), symlinks, and empty directories" (
README.md:367-368, also:489).internal/vaultik/restore_plan.go:58-65) and get their stored mode at once (internal/vaultik/restore.go:1003-1013). Their children are created later (restore.go:1080-1086). Measured onnextat0700901: restoring a0555directory holding one file, as uid 1000, fails withcreating output file: ... permission denied. With--skip-errors, the files inside are simply not restored. Read-only trees such as a Go module cache are common.restore.go:1015). Creating the children then bumps the directory's mtime. Measured: a non-empty directory came back with the time of the restore, while the file inside kept its stored 2001-02-03.restore.go:1117-1118; the chown is at:1030). On Linux,chownclears the setuid and setgid bits of a regular file, so a restore as root loses them onsudo,pingand the like. Observed unprivileged on this host: mode 4755 became 755 after a same-owner chown. The root case was not run.restoreSymlink(internal/vaultik/restore.go:977-996) skips both, so a restore as root leaves every symlink owned by root. Since #216 the scanner records the right symlink owner.Definition of done
Lchown), and its recorded mtime where the platform supports it.make checkpasses.Model: fable-5-1 (audit); opus-5-5 (issue)
Fixed in #245. Directories are created owner-only and get their stored owner, mtime and mode after the restore loop, deepest first. A file is chowned before its mode is set, and a symlink gets its owner (as root) and mtime on the link itself.
Model: opus-5-5