mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-10 00:14:38 +00:00
Harden Proxmox integer parsing bounds
This commit is contained in:
parent
cabd224987
commit
030fc20cd6
2 changed files with 65 additions and 9 deletions
|
|
@ -88,9 +88,23 @@ func parseFlexibleIntString(raw string) (int, error) {
|
|||
}
|
||||
|
||||
func int64ToInt(v int64) (int, error) {
|
||||
maxInt := int64(^uint(0) >> 1)
|
||||
minInt := -maxInt - 1
|
||||
if v > maxInt || v < minInt {
|
||||
if strconv.IntSize == 32 {
|
||||
if v > math.MaxInt32 || v < math.MinInt32 {
|
||||
return 0, fmt.Errorf("integer %d exceeds int range", v)
|
||||
}
|
||||
return int(int32(v)), nil
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func uint64ToInt(v uint64) (int, error) {
|
||||
if strconv.IntSize == 32 {
|
||||
if v > math.MaxInt32 {
|
||||
return 0, fmt.Errorf("integer %d exceeds int range", v)
|
||||
}
|
||||
return int(int32(v)), nil
|
||||
}
|
||||
if v > math.MaxInt64 {
|
||||
return 0, fmt.Errorf("integer %d exceeds int range", v)
|
||||
}
|
||||
return int(v), nil
|
||||
|
|
@ -100,8 +114,13 @@ func floatToIntTrunc(v float64) (int, error) {
|
|||
if math.IsNaN(v) || math.IsInf(v, 0) {
|
||||
return 0, fmt.Errorf("non-finite float %v cannot be converted to int", v)
|
||||
}
|
||||
limit := math.Exp2(float64(strconv.IntSize - 1))
|
||||
if v >= limit || v < -limit {
|
||||
var maxAbs float64
|
||||
if strconv.IntSize == 32 {
|
||||
maxAbs = float64(math.MaxInt32) + 1
|
||||
} else {
|
||||
maxAbs = float64(math.MaxInt64) + 1
|
||||
}
|
||||
if v >= maxAbs || v < -maxAbs {
|
||||
return 0, fmt.Errorf("float %v exceeds int range", v)
|
||||
}
|
||||
return int(v), nil
|
||||
|
|
@ -1681,15 +1700,16 @@ func (a *VMIPAddress) UnmarshalJSON(data []byte) error {
|
|||
|
||||
a.Address = coerceString(raw["ip-address"])
|
||||
|
||||
maxInt := uint64(^uint(0) >> 1)
|
||||
prefix, err := coerceUint64("prefix", raw["prefix"])
|
||||
if err != nil {
|
||||
prefix = 0
|
||||
}
|
||||
if prefix > maxInt {
|
||||
prefix = maxInt
|
||||
if prefix > 128 {
|
||||
prefix = 128
|
||||
}
|
||||
if prefixInt, err := uint64ToInt(prefix); err == nil {
|
||||
a.Prefix = prefixInt
|
||||
}
|
||||
a.Prefix = int(prefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -587,6 +587,42 @@ func TestFlexIntUnmarshalJSONRejectsNonFiniteAndOverflow(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestVMIPAddressUnmarshalJSONCapsPrefixToCIDRRange(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
payload string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "keeps valid prefix",
|
||||
payload: `{"ip-address":"10.0.0.10","prefix":24}`,
|
||||
want: 24,
|
||||
},
|
||||
{
|
||||
name: "caps overlong ipv6 prefix",
|
||||
payload: `{"ip-address":"2001:db8::10","prefix":129}`,
|
||||
want: 128,
|
||||
},
|
||||
{
|
||||
name: "caps huge prefix before int conversion",
|
||||
payload: `{"ip-address":"2001:db8::10","prefix":"18446744073709551615"}`,
|
||||
want: 128,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var got VMIPAddress
|
||||
if err := json.Unmarshal([]byte(tc.payload), &got); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got.Prefix != tc.want {
|
||||
t.Fatalf("prefix = %d, want %d", got.Prefix, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseUint64Flexible(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue