vendor: github.com/moby/sys/user v0.4.1#7073
Conversation
- user: prevent possible DoS via unbounded parsing of user and group database files in GHSA-mjcv-p78q-w5fw. This fixes a similar issue as CVE-2026-47262 in containerd. - user: prevent falling back to looking up numeric usernames Improve handling of numeric user/group to prevent looking up numeric values as usernames. This fixes a similar issue as [CVE-2026-46680] in containerd. - user: update minimum go version to go1.18 - assorted testing and linting fixes. [CVE-2026-46680]: GHSA-fqw6-gf59-qr4w full diff: moby/sys@user/v0.4.0...user/v0.4.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
This PR vendors github.com/moby/sys/user v0.4.1, which delivers two security fixes:
- GHSA-mjcv-p78q-w5fw (DoS via unbounded file parsing):
ParseGroupFileFilter,GetExecUserPath, and related functions now route throughopenUserFile, which enforces a 10 MiB cap and rejects non-regular files. - CVE-2026-46680 (numeric username fallback): A new
parseNumerichelper with explicitisUID/isGIDbooleans cleanly replaces the oldstrconv.Atoierror-code pattern, preventing numeric strings from being treated as usernames.
One low-severity observation about an edge case in the new limitedFile.Read is noted inline. The fix is otherwise correct and well-structured.
|
|
||
| func (l *limitedFile) Read(p []byte) (int, error) { | ||
| n, err := l.LimitedReader.Read(p) | ||
| if l.LimitedReader.N == 0 { |
There was a problem hiding this comment.
[LOW] Edge-case: real I/O error may be silently replaced by the "file exceeds limit" error
When l.LimitedReader.Read(p) returns both n > 0 bytes and a non-EOF error (e.g. a transient I/O error) in the same call, and doing so exhausts N to exactly 0, the code discards the underlying error and instead returns the oversized-file PathError. The caller then sees "file exceeds 10485760 bytes" even though the file may be within the limit and the real cause was an I/O failure — making debugging harder.
In the common/intended case (file genuinely too large) io.LimitedReader returns io.EOF when exhausted, so the replacement is always the "too large" error as intended. The edge case requires the last read to partially succeed and fail simultaneously, which is extremely unlikely for a regular local file. No security or correctness impact under normal conditions.
Consider preserving the underlying error when it is non-nil and not io.EOF:
func (l *limitedFile) Read(p []byte) (int, error) {
n, readErr := l.LimitedReader.Read(p)
if l.LimitedReader.N == 0 {
oversizeErr := &os.PathError{
Op: "read",
Path: l.name,
Err: fmt.Errorf("file exceeds %d bytes", maxUserFileBytes),
}
if readErr != nil && readErr != io.EOF {
return n, readErr // preserve the real error
}
return n, oversizeErr
}
return n, readErr
}
full diff: moby/sys@user/v0.4.0...user/v0.4.1
- What I did
- How I did it
- How to verify it
- Human readable description for the release notes
- A picture of a cute animal (not mandatory but encouraged)