tarfs: DirEntry.Type returns the full mode instead of the type bits
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go
- Domain
- operating-systems
Research direction
Start with the two Type methods shown in the tarfs implementation and the fs.DirEntry/FileInfo contract. Reproduce the setuid example, then verify both implementations return only type bits while Mode remains unchanged. Treat the Open(".")/fstest.TestFS issue as a separate conformance decision.
Written by the indexing model from the issue text.
Description
fs.DirEntry.Type is documented to return "the type bits for the entry -- the type bits are those returned by [FileMode.Type]". tarfs returns the full mode, permission bits included, from both of its DirEntry implementations:
func (e Entry) Type() fs.FileMode { return e.fi.Mode() }
func (e *entry) Type() fs.FileMode { return e.fileMode }
*entry values are what ReadDir hands back (they are stored in fsys.dirs as fs.DirEntry), so every ReadDir result violates the contract. fs.WalkDir also calls Type() on them.
Reproduction
An archive with a setuid regular file at usr/setuid (mode 0o4755):
ReadDir entry "setuid" Type()=urwxr-xr-x Mode()=urwxr-xr-x Mode().Type()=----------
contract says Type() should equal Mode().Type(): false
For a regular file Type() should be 0 (no type bits set). Callers that switch on d.Type() to classify entries, or compare it against fs.ModeDir/fs.ModeSymlink, get the wrong answer for any member with permission bits — which is every member.
Suggested fix
func (e *entry) Type() fs.FileMode { return e.fileMode.Type() }
and the same on Entry.Type. Both should change together; fixing only one would leave the two implementations disagreeing.
Mode() is unaffected and should keep returning the full mode, which is what fs.FileInfo.Mode documents.
Related, found by the same probe
fstest.TestFS does not pass against a tarfs.FS:
.: Open: file does not exist
expected but not found: usr/setuid
Stat(".") synthesizes a root entry but Open(".") does not, so the conformance walk cannot start. That is a separate gap from the Type() issue and may well be intentional given how the package is used, but it means fs.WalkDir from the root does not work either. Worth deciding whether full fs.FS conformance is a goal for this package; if it is, fstest.TestFS would be a good addition to the test suite and would have caught the Type() bug on its own.
Impact
Low today. Both Type() implementations have had this behavior for as long as the package has existed, and no in-tree consumer appears to switch on d.Type() -- pkg/apk/apk reads headers rather than walking the FS. Filing it because it is a silent contract violation on an exported type, so a future caller using the standard fs.DirEntry idiom would get wrong results with no error.
- Dominant language
- Go
- Stars
- 1.7k
- Forks
- 228
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 62
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from chainguard-dev/apko
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
chainguard-dev/apko#2496 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
chainguard-dev/apko#2494 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
chainguard-dev/apko#2484 ·
-
Difficulty 2/5 Half a day Newbie friendliness 76/100
chainguard-dev/apko#2483 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
chainguard-dev/apko#2423 ·
All issues in chainguard-dev/apko
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 84/100
-
enhancement needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
kind/cleanup
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
kubernetes-sigs/kueue#15947 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
sympozium-ai/sympozium#627 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100