diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-17 14:02:24 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-17 14:02:24 +0200 |
| commit | a65e8a0587d3e5c971bef3062dd0d8a3b5cb53b7 (patch) | |
| tree | 82c606411fd814cb5003633cfa592393abcbe057 /docs/design.md | |
| parent | b44222fc2b061382dc601014cde287cc41b857ca (diff) | |
| download | krino-a65e8a0587d3e5c971bef3062dd0d8a3b5cb53b7.tar.gz krino-a65e8a0587d3e5c971bef3062dd0d8a3b5cb53b7.zip | |
a symlink in the sorted directory no longer redirects a step
Placeholders were already stopped from sending a file out of the
directory a rule named. A symlink is a name too, and the directory
krino sorts is by the threat model's own premise a place the internet
writes into: a link named after a rule's destination sent moves and
copies anywhere, and under (on-conflict overwrite) trashed a file
OUTSIDE the sorted directory - while the plan showed the in-tree text
and the run reported success.
A step whose destination passes through a symlink at or below the
directory being sorted now fails. A destination the configuration names
outside it - ~/docs on another disk - is the user's own arrangement and
is followed as before; both cases have a test.
End to end, the review's scenario (Out -> ~/secret, overwrite):
before: 1 applied, the user's file replaced and trashed
after: 0 applied 1 failed, the file untouched, nothing trashed
Two bookkeeping bugs in MkdirAllTracked went with it: a dangling
symlink read as a missing directory and was then recorded as one krino
had created - undo would have unlinked a link krino never made - and a
directory created by someone else between the check and the mkdir was
recorded the same way.
Diffstat (limited to 'docs/design.md')
| -rw-r--r-- | docs/design.md | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/docs/design.md b/docs/design.md index 6299288..e2c3cf6 100644 --- a/docs/design.md +++ b/docs/design.md @@ -924,7 +924,13 @@ What that means, and the tests that hold it (plans 8 and 9): resolve at or under the directory its text names before the first placeholder, so a capture of "..", "~" or nothing cannot move it elsewhere; a rename whose placeholders produce "", "." or ".." is skipped - with a reason. + with a reason. A symlink is a name too: a step whose destination passes + through a symlink **inside the directory being sorted** fails rather than + following it, since anything at all may be written there - by a download, + or an unpacked archive - and the plan the user approved shows only the + text. A destination the configuration itself names outside that + directory, `~/docs` on another disk say, is the user's own arrangement + and is followed as before. - A file is acted on only while it is still the file that was planned: same size and modification time, still a regular file (not a symlink put in its place), and, at its planned path, the same inode. A step that had |
