diff --git a/.golangci.yml b/.golangci.yml index d360606f7254..6b13b2dedf1f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -72,7 +72,6 @@ linters-settings: excludes: - G104 # G104: Errors unhandled; (TODO: reduce unhandled errors, or explicitly ignore) - G113 # G113: Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772); (only affects go < 1.16.14. and go < 1.17.7) - - G115 # G115: integer overflow conversion; (TODO: verify these: https://github.com/docker/cli/issues/5584) - G306 # G306: Expect WriteFile permissions to be 0600 or less (too restrictive; also flags "0o644" permissions) - G307 # G307: Deferring unsafe method "*os.File" on type "Close" (also EXC0008); (TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close") govet: diff --git a/cli/command/container/cp.go b/cli/command/container/cp.go index 85e9f6164f2c..e70429c0a205 100644 --- a/cli/command/container/cp.go +++ b/cli/command/container/cp.go @@ -108,7 +108,7 @@ func copyProgress(ctx context.Context, dst io.Writer, header string, total *int6 } // Write to the buffer first to avoid flickering and context switching - fmt.Fprint(buf, aec.Column(uint(len(header)+1))) + fmt.Fprint(buf, aec.Column(uint(len(header)+1))) // #nosec G115 -- Ignore "integer overflow conversion int -> uint" (go len value always start from 0) fmt.Fprint(buf, aec.EraseLine(aec.EraseModes.Tail)) fmt.Fprint(buf, progressHumanSize(n)) diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index 8cc44b762da9..14cf7797dd8b 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -620,7 +620,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con BlkioDeviceReadIOps: copts.deviceReadIOps.GetList(), BlkioDeviceWriteIOps: copts.deviceWriteIOps.GetList(), IOMaximumIOps: copts.ioMaxIOps, - IOMaximumBandwidth: uint64(copts.ioMaxBandwidth), + IOMaximumBandwidth: uint64(copts.ioMaxBandwidth), // #nosec G115 -- ignore "integer overflow conversion int64 -> uint64" (Using MemBytes value, which alway assumed to be positive) Ulimits: copts.ulimits.GetList(), DeviceCgroupRules: copts.deviceCgroupRules.GetAll(), Devices: deviceMappings, diff --git a/cli/command/container/stats_helpers.go b/cli/command/container/stats_helpers.go index c7084c17b532..2c47956c9d72 100644 --- a/cli/command/container/stats_helpers.go +++ b/cli/command/container/stats_helpers.go @@ -184,9 +184,13 @@ func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *container.St func calculateCPUPercentWindows(v *container.StatsResponse) float64 { // Max number of 100ns intervals between the previous time read and now - possIntervals := uint64(v.Read.Sub(v.PreRead).Nanoseconds()) // Start with number of ns intervals - possIntervals /= 100 // Convert to number of 100ns intervals - possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors + preRead := v.Read.Sub(v.PreRead).Nanoseconds() + if preRead <= 0 { + return 0.00 // Avoid calculation with 0 or negative + } + possIntervals := uint64(preRead) // Start with number of ns intervals + possIntervals /= 100 // Convert to number of 100ns intervals + possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors // Intervals used intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage diff --git a/cli/command/image/tree.go b/cli/command/image/tree.go index a095173bd7d3..a57d2612c700 100644 --- a/cli/command/image/tree.go +++ b/cli/command/image/tree.go @@ -193,7 +193,7 @@ func printImageTree(dockerCLI command.Cli, view treeView) error { out.PrintlnWithColor(tui.ColorWarning, "WARNING: This is an experimental feature. The output may change and shouldn't be depended on.") - out.Println(generateLegend(out, width)) + out.Println(generateLegend(out, int(width))) // #nosec G115 -- ignore "overflow conversion uint -> int", int expansion won't cause lost of value out.Println() possibleChips := getPossibleChips(view) @@ -259,7 +259,7 @@ func printImageTree(dockerCLI command.Cli, view treeView) error { }, } - columns = adjustColumns(width, columns, view.images) + columns = adjustColumns(int(width), columns, view.images) // #nosec G115 -- ignore "overflow conversion uint -> int", int expansion won't cause lost of value // Print columns for i, h := range columns { @@ -289,8 +289,8 @@ func printImageTree(dockerCLI command.Cli, view treeView) error { // adjustColumns adjusts the width of the first column to maximize the space // available for image names and removes any columns that would be too narrow // to display their content. -func adjustColumns(width uint, columns []imgColumn, images []topImage) []imgColumn { - nameWidth := int(width) +func adjustColumns(width int, columns []imgColumn, images []topImage) []imgColumn { + nameWidth := width for idx, h := range columns { if h.Width == 0 { continue @@ -316,7 +316,7 @@ func adjustColumns(width uint, columns []imgColumn, images []topImage) []imgColu return columns } -func generateLegend(out tui.Output, width uint) string { +func generateLegend(out tui.Output, width int) string { var legend string legend += out.Sprint(tui.InfoHeader) for idx, chip := range allChips { @@ -327,7 +327,7 @@ func generateLegend(out tui.Output, width uint) string { } legend += " " - r := int(width) - tui.Width(legend) + r := width - tui.Width(legend) if r < 0 { r = 0 } @@ -388,7 +388,7 @@ func printNames(out tui.Output, headers []imgColumn, img topImage, color, untagg // name will be printed alongside other columns. if nameIdx < len(img.Names)-1 { _, fullWidth := out.GetTtySize() - _, _ = fmt.Fprintln(out, color.Apply(tui.Ellipsis(name, int(fullWidth)))) + _, _ = fmt.Fprintln(out, color.Apply(tui.Ellipsis(name, int(fullWidth)))) // #nosec G115 -- ignore "overflow conversion uint -> int", int expansion won't cause lost of value } else { _, _ = fmt.Fprint(out, headers[0].Print(color, name)) } diff --git a/cli/command/service/logs.go b/cli/command/service/logs.go index f1b61627fbd7..74586d51c2c6 100644 --- a/cli/command/service/logs.go +++ b/cli/command/service/logs.go @@ -121,7 +121,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro if service.Spec.Mode.Replicated != nil && service.Spec.Mode.Replicated.Replicas != nil { // if replicas are initialized, figure out if we need to pad them replicas := *service.Spec.Mode.Replicated.Replicas - maxLength = getMaxLength(int(replicas)) + maxLength = getMaxLength(int(replicas)) // #nosec G115 -- ignore "integer overflow conversion uint64 -> int" (The only fail case is having 2^32 or more replicas on 32bit system) } } diff --git a/cli/command/service/progress/progress.go b/cli/command/service/progress/progress.go index 09da18774c7a..41b34b92d85c 100644 --- a/cli/command/service/progress/progress.go +++ b/cli/command/service/progress/progress.go @@ -301,7 +301,7 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. u.slotMap = make(map[int]int) // Draw progress bars in order - writeOverallProgress(u.progressOut, 0, int(replicas), rollback) + writeOverallProgress(u.progressOut, 0, int(replicas), rollback) // #nosec G115 -- ignore "overflow conversion uint64 -> int", safe for less than 2^32 replica in 32bit system if replicas <= maxProgressBars { for i := uint64(1); i <= replicas; i++ { @@ -340,7 +340,7 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. } if !u.done { - writeOverallProgress(u.progressOut, int(running), int(replicas), rollback) + writeOverallProgress(u.progressOut, int(running), int(replicas), rollback) // #nosec G115 -- ignore "overflow conversion uint64 -> int", safe for less than 2^32 running tasks in 32bit system if running == replicas { u.done = true @@ -383,6 +383,7 @@ func (*replicatedProgressUpdater) tasksBySlot(tasks []swarm.Task, activeNodes ma } func (u *replicatedProgressUpdater) writeTaskProgress(task swarm.Task, mappedSlot int, replicas uint64) { + // #nosec G115 -- ignore "overflow conversion uint64 -> int", mappedSlot never negative if u.done || replicas > maxProgressBars || uint64(mappedSlot) > replicas { return } @@ -572,8 +573,8 @@ type replicatedJobProgressUpdater struct { } func newReplicatedJobProgressUpdater(service swarm.Service, progressOut progress.Output) *replicatedJobProgressUpdater { - concurrent := int(*service.Spec.Mode.ReplicatedJob.MaxConcurrent) - total := int(*service.Spec.Mode.ReplicatedJob.TotalCompletions) + concurrent := int(*service.Spec.Mode.ReplicatedJob.MaxConcurrent) // #nosec G115 -- ignore "overflow conversion uint64 -> int", safe for less than 2^32 MaxConcurrent in 32bit system + total := int(*service.Spec.Mode.ReplicatedJob.TotalCompletions) // #nosec G115 -- ignore "overflow conversion uint64 -> int", safe for less than 2^32 TotalCompletions in 32bit system return &replicatedJobProgressUpdater{ progressOut: progressOut, diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index d5237d72912b..77434dc9b6f2 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -460,6 +460,7 @@ func convertHealthcheck(healthcheck *composetypes.HealthCheckConfig) (*container if healthcheck.StartInterval != nil { startInterval = time.Duration(*healthcheck.StartInterval) } + // #nosec G115 -- ignore "overflow conversion uint64 -> int", safe to convert for retries value less than 2^32 in a 32bit system if healthcheck.Retries != nil { retries = int(*healthcheck.Retries) } @@ -488,7 +489,7 @@ func convertRestartPolicy(restart string, source *composetypes.RestartPolicy) (* Condition: swarm.RestartPolicyConditionAny, }, nil case policy.IsOnFailure(): - attempts := uint64(policy.MaximumRetryCount) + attempts := uint64(policy.MaximumRetryCount) // #nosec G115 -- ignore "overflow onversion int -> uint64", validation for negative value exist on MaximumRetryCount init return &swarm.RestartPolicy{ Condition: swarm.RestartPolicyConditionOnFailure, MaxAttempts: &attempts, diff --git a/opts/swarmopts/port.go b/opts/swarmopts/port.go index e15c6b83023c..d45910343ae1 100644 --- a/opts/swarmopts/port.go +++ b/opts/swarmopts/port.go @@ -171,8 +171,8 @@ func ConvertPortToPortConfig( ports = append(ports, swarm.PortConfig{ // TODO Name: ? Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())), - TargetPort: uint32(port.Int()), - PublishedPort: uint32(i), + TargetPort: uint32(port.Int()), // #nosec G115 -- ignore "integer overflow conversion int -> uint32" (All known port is in range of uint32, including dynamic port) + PublishedPort: uint32(i), // #nosec G115 -- ignore "integer overflow conversion uint64 -> uint32" (All known port is in range of uint32, including dynamic port) PublishMode: swarm.PortConfigPublishModeIngress, }) }