Repository navigation
Escape space in mtree filename output to prevent keyword injection - #344
Merged
Merged
Conversation
mtreeFilename() escaped backslash, '#', control bytes, and bytes >126 but not space (0x20). mtree(5) lines are space-delimited keyword=value pairs following the filename, so an untrusted catar entry name like "usr ignore" was emitted verbatim, letting mtree(8) parse "ignore" (also "optional"/"nochange") as a value-less keyword that suppresses integrity verification of the whole subtree. Symlink targets, passed through the same function, were a second injection vector. Add space to the octal-escape set, matching the escaped set used by libarchive and BSD mtree (non-printable, '\', ' ', '\t', '#'); space becomes \040 and still round-trips through mtree(8) readers. Update the doc comment and add tests covering the escaping and a regression guard for the keyword-injection attack.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
mtreeFilename()escaped backslash,#, control bytes (c < 32), and bytes> 126, but not space (0x20). mtree(5) lines are space-delimitedkeyword=valuepairs following the filename (joined viastrings.Join(attr, " ")), so an untrusted catar entry name containing a space was emitted verbatim:mtree(8) then parses
usras the filename andignoreas a value-less keyword that suppresses verification of the entire subtree.optionalandnochangesuppress detection similarly. The attack is reachable:safeComponent()explicitly treats names with spaces as valid, andCreateSymlinkpasses the attacker-controlledtargetthrough the same function — a second injection vector.Fix
Add space to the octal-escape set in
mtreeFilename(), matching the escaped set used by libarchive and BSD mtree (non-printable,\,,\t,#; tab and other control bytes were already covered byc < 32). Space becomes\040, which mtree(8) readers decode back correctly, so legitimate spaced filenames still round-trip. The doc comment is updated to document the space rule and the rationale.Tests
TestMtreeFilename— table covering space →\040,\,#, tab, newline, DEL, and multi-byte UTF-8, plus an untouched plain name.TestMtreeFSNoKeywordInjection— drivesMtreeFS.CreateDirwithName: "usr ignore"and asserts the filename is a single escaped field and no bareignorekeyword field appears.Full suite (
go test ./...) passes; binary builds.