-
Notifications
You must be signed in to change notification settings - Fork 868
*: enable gosec linter #1804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
*: enable gosec linter #1804
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request enables the gosec security linter for the codebase and addresses the security warnings it identified. The changes focus on preventing integer overflow vulnerabilities, improving error handling, enhancing TLS security, and addressing file permission issues.
Key changes include:
- Adding bounds checking for integer conversions (int64/uint64 to uint32, uint to int, etc.) to prevent overflow
- Adding error handling for hash write operations that were previously ignored
- Setting minimum TLS version to 1.2 for secure HTTP transport
- Adding validation for negative values and out-of-range conversions throughout packfile, index, and commit graph code
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| .golangci.yaml | Enables gosec linter and excludes it from test files |
| worktree_status.go | Adds bounds checking for file size to uint32 conversion |
| worktree_linux.go | Adds masking for dev/inode uint64 to uint32 conversions |
| worktree_bsd.go | Adds clamping for dev (int32) and masking for inode conversions |
| worktree.go | Adds bounds checking for file size conversion in addIndexFromFile |
| utils/merkletrie/internal/fsnoder/*.go | Adds blank identifier for hash.Write() error returns |
| utils/merkletrie/filesystem/node.go | Adds validation for CRLF count conversion |
| storage/filesystem/mmap/scan.go | Adds overflow checks for offset and size conversions |
| storage/filesystem/mmap/fsobject.go | Adds validation for OFS delta offset calculations |
| storage/filesystem/dotgit/writers.go | Adds checks for negative values before uint conversions |
| plumbing/transport/ssh/sshagent/pageant_windows.go | Adds bounds checking and gosec exceptions for required unsafe operations |
| plumbing/transport/ssh/knownhosts/knownhosts.go | Adds #nosec comment for expected file open behavior |
| plumbing/transport/ssh/auth_method.go | Adds #nosec comment for user-supplied key file reads |
| plumbing/transport/http/common.go | Sets minimum TLS version to 1.2 for secure connections |
| plumbing/reference.go | Refactors Strings() to use early returns instead of array initialization |
| plumbing/object/rename.go | Adds overflow checks and validation for similarity index operations |
| plumbing/object/patch.go | Changes types from uint to int and adds negative value checks |
| plumbing/hash.go | Adds blank identifier for hash.Write() error returns |
| plumbing/format/packfile/*.go | Extensive overflow checks for size/offset conversions in pack processing |
| plumbing/format/index/*.go | Adds validation for timestamps, stages, and entry counts |
| plumbing/format/idxfile/*.go | Adds overflow checks for offset and fanout operations |
| plumbing/format/commitgraph/*.go | Adds bounds checking for hash counts, edge counts, and timestamp conversions |
| internal/transport/test/receive_pack.go | Changes test file permissions from 0o644 to 0o600 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
plumbing/format/index/decoder.go
Outdated
| if len(header) < 1 { | ||
| return ErrUnknownExtension | ||
| } |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is redundant. The header slice was just created with make([]byte, 4) on line 250, so it will always have length 4 and never be less than 1. This check can never be true.
| if len(header) < 1 { | |
| return ErrUnknownExtension | |
| } |
worktree_bsd.go
Outdated
| dev32 := max(os.Dev, int32(0)) | ||
| e.Dev = uint32(dev32) //nolint:gosec // G115: dev32 clamped to non-negative. |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here is incorrect. On BSD systems, os.Dev is an int32, and when it's negative, using max(os.Dev, int32(0)) will result in 0, not the actual device number. This differs from the Linux implementation which uses bitwise masking to preserve the full value. If os.Dev is negative (which is a valid signed value), this code will incorrectly map it to 0, potentially causing device number collisions. Consider using the same approach as Linux: convert to uint32 directly or use bitwise masking to preserve all bits.
| for _, file := range files { | ||
| path := filepath.Join(objectPath, file.Name()) | ||
| err = os.Chmod(path, 0o644) | ||
| err = os.Chmod(path, 0o600) |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file permission was changed from 0o644 (read/write for owner, read-only for group and others) to 0o600 (read/write for owner only). While this is more restrictive and better from a security perspective, this changes the behavior of test files. The comment on line 237-239 states these are fixture files that need write permissions to avoid errors when deleting or modifying. Consider if 0o600 is intentional here or if the original 0o644 was sufficient for the test's purpose.
| err = os.Chmod(path, 0o600) | |
| err = os.Chmod(path, 0o644) |
plumbing/object/rename.go
Outdated
| return 0 | ||
| } | ||
| // hashBits is capped by grow() (max 30), keep shift safe and well-defined. | ||
| if hashBits > 62 { |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check hashBits > 62 on line 791 may be too permissive. According to the comment and the guard in the grow() function (line 798), hashBits is capped at 30. However, if hashBits is between 31 and 62, the shift operation 1 << uint(hashBits) on line 794 could overflow for values above 30. Consider either using the same limit as grow() (hashBits > 30) or documenting why 62 is the correct upper bound.
| if hashBits > 62 { | |
| if hashBits > 30 { |
ae85e2e to
2309986
Compare
2309986 to
666d1e1
Compare
666d1e1 to
8d0e3bf
Compare
40141e2 to
278ddb4
Compare
Signed-off-by: ferhat elmas <elmas.ferhat@gmail.com>
278ddb4 to
2be2a53
Compare
|
@pjbgf last one in the series should be good to go |
related to #1753