Skip to content
This repository has been archived by the owner on Sep 8, 2023. It is now read-only.

Commit

Permalink
fix integer bounds checks (hashicorp#11815)
Browse files Browse the repository at this point in the history
* driver: fix integer conversion error

The shared executor incorrectly parsed the user's group into int32 and
then cast to uint32 without bounds checking. This is harmless because
an out-of-bounds gid will throw an error later, but it triggers
security and code quality scans. Parse directly to uint32 so that we
get correct error handling.

* helper: fix integer conversion error

The autopilot flags helper incorrectly parses a uint64 to a uint which
is machine specific size. Although we don't have 32-bit builds, this
sets off security and code quality scaans. Parse to the machine sized
uint.

* driver: restrict bounds of port map

The plugin server doesn't constrain the maximum integer for port
maps. This could result in a user-visible misconfiguration, but it
also triggers security and code quality scans. Restrict the bounds
before casting to int32 and return an error.

* cpuset: restrict upper bounds of cpuset values

Our cpuset configuration expects values in the range of uint16 to
match the expectations set by the kernel, but we don't constrain the
values before downcasting. An underflow could lead to allocations
failing on the client rather than being caught earlier. This also make
security and code quality scanners happy.

* http: fix integer downcast for per_page parameter

The parser for the `per_page` query parameter downcasts to int32
without bounds checking. This could result in underflow and
nonsensical paging, but there's no server-side consequences for
this. Fixing this will silence some security and code quality scanners
though.
  • Loading branch information
tgross authored Jan 25, 2022
1 parent 3423118 commit 358a468
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 4 deletions.
2 changes: 1 addition & 1 deletion command/agent/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ func parsePagination(req *http.Request, b *structs.QueryOptions) {
query := req.URL.Query()
rawPerPage := query.Get("per_page")
if rawPerPage != "" {
perPage, err := strconv.Atoi(rawPerPage)
perPage, err := strconv.ParseInt(rawPerPage, 10, 32)
if err == nil {
b.PerPage = int32(perPage)
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/shared/executor/executor_universal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ func setCmdUser(cmd *exec.Cmd, userid string) error {

gids := make([]uint32, len(gidStrings))
for _, gidString := range gidStrings {
u, err := strconv.Atoi(gidString)
u, err := strconv.ParseUint(gidString, 10, 32)
if err != nil {
return fmt.Errorf("Unable to convert user's group to int %s: %v", gidString, err)
return fmt.Errorf("Unable to convert user's group to uint32 %s: %v", gidString, err)
}

gids = append(gids, uint32(u))
Expand Down
4 changes: 3 additions & 1 deletion helper/flags/autopilot_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package flags

import (
"fmt"
"math/bits"
"strconv"
"time"
)
Expand Down Expand Up @@ -88,7 +89,8 @@ func (u *UintValue) Set(v string) error {
if u.v == nil {
u.v = new(uint)
}
parsed, err := strconv.ParseUint(v, 0, 64)

parsed, err := strconv.ParseUint(v, 0, bits.UintSize)
*(u.v) = (uint)(parsed)
return err
}
Expand Down
8 changes: 8 additions & 0 deletions lib/cpuset/cpuset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cpuset

import (
"fmt"
"math"
"reflect"
"sort"
"strconv"
Expand Down Expand Up @@ -153,6 +154,9 @@ func Parse(s string) (CPUSet, error) {
return New(), err
}

if v > math.MaxUint16 {
return New(), fmt.Errorf("failed to parse element %s, more than max allowed cores", set)
}
cpuset.cpus[uint16(v)] = struct{}{}
continue
}
Expand All @@ -168,7 +172,11 @@ func Parse(s string) (CPUSet, error) {
if err != nil {
return New(), err
}

for v := lower; v <= upper; v++ {
if v > math.MaxUint16 {
return New(), fmt.Errorf("failed to parse element %s, more than max allowed cores", set)
}
cpuset.cpus[uint16(v)] = struct{}{}
}
}
Expand Down
4 changes: 4 additions & 0 deletions plugins/drivers/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package drivers
import (
"fmt"
"io"
"math"

"github.com/golang/protobuf/ptypes"
plugin "github.com/hashicorp/go-plugin"
Expand Down Expand Up @@ -125,6 +126,9 @@ func (b *driverPluginServer) StartTask(ctx context.Context, req *proto.StartTask
AutoAdvertise: net.AutoAdvertise,
}
for k, v := range net.PortMap {
if v > math.MaxInt32 {
return nil, fmt.Errorf("port map out of bounds")
}
pbNet.PortMap[k] = int32(v)
}
}
Expand Down

0 comments on commit 358a468

Please sign in to comment.