Writing configuration can mutate symlinks #89
Labels
No labels
Bug
BuildIssue
Claude-fixed
Enhancement
In Progress
Low priority
On Hold
Rejected
Security
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
keyop-go/nfq_forwarder#89
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
If the configuration given is a symlink to another file, writing the configuration will replace it with a plain file.
Root cause + fix
atomicWriteConfigFile(webui_config_edit.go) writes a save via a temp file created infilepath.Dir(path), thenos.Rename(tmpPath, path). POSIXrename()doesn't follow a symlinkat the destination - it unconditionally replaces whatever inode is at that path. If
pathis asymlink, the rename destroys it and puts a plain regular file there instead, exactly as reported.
Fix: resolve
pathviafilepath.EvalSymlinksonce at the top (falling back to the given pathif resolution fails, e.g. a genuinely-missing file - the existing Stat/CreateTemp/Rename calls
already surface any real problem on their own), and do every subsequent filesystem operation
(permission lookup, temp file directory, final rename target) against the resolved path instead
of the original. This also incidentally fixes a second, related latent bug: creating the temp
file in the symlink's own directory and then renaming onto a target that lives in a different
directory (a realistic case for a symlink) risks a cross-filesystem rename failing outright
(
EXDEV) even before the symlink-clobbering issue - the temp file needs to live in the samedirectory as wherever the rename target actually is.
Net effect: a symlinked
--configfile's symlink itself is left untouched by a web UI save -only the real target file's content changes.
Branch:
issue89_symlink_write.