Skip to content

Commit 459e2d3

Browse files
rungccojocar
authored andcommitted
Modify rule for integer overflow to have more acurate results (#434)
Signed-off-by: Hiroki Suezawa <[email protected]>
1 parent a4d7b36 commit 459e2d3

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

rules/integer_overflow.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,37 @@ func (i *integerOverflowCheck) ID() string {
3030
}
3131

3232
func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
33-
var atoiVarName map[string]ast.Node
33+
var atoiVarObj map[*ast.Object]ast.Node
3434

3535
// To check multiple lines, ctx.PassedValues is used to store temporary data.
3636
if _, ok := ctx.PassedValues[i.ID()]; !ok {
37-
atoiVarName = make(map[string]ast.Node)
38-
ctx.PassedValues[i.ID()] = atoiVarName
39-
} else if pv, ok := ctx.PassedValues[i.ID()].(map[string]ast.Node); ok {
40-
atoiVarName = pv
37+
atoiVarObj = make(map[*ast.Object]ast.Node)
38+
ctx.PassedValues[i.ID()] = atoiVarObj
39+
} else if pv, ok := ctx.PassedValues[i.ID()].(map[*ast.Object]ast.Node); ok {
40+
atoiVarObj = pv
4141
} else {
42-
return nil, fmt.Errorf("PassedValues[%s] of Context is not map[string]ast.Node, but %T", i.ID(), ctx.PassedValues[i.ID()])
42+
return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*ast.Object]ast.Node, but %T", i.ID(), ctx.PassedValues[i.ID()])
4343
}
4444

4545
// strconv.Atoi is a common function.
4646
// To reduce false positives, This rule detects code which is converted to int32/int16 only.
4747
switch n := node.(type) {
48-
case *ast.FuncDecl:
49-
// Clear atoiVarName by function
50-
ctx.PassedValues[i.ID()] = make(map[string]ast.Node)
5148
case *ast.AssignStmt:
5249
for _, expr := range n.Rhs {
5350
if callExpr, ok := expr.(*ast.CallExpr); ok && i.calls.ContainsCallExpr(callExpr, ctx, false) != nil {
5451
if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" {
5552
// Example:
5653
// v, _ := strconv.Atoi("1111")
57-
// Add "v" to atoiVarName map
58-
atoiVarName[idt.Name] = n
54+
// Add v's Obj to atoiVarObj map
55+
atoiVarObj[idt.Obj] = n
5956
}
6057
}
6158
}
6259
case *ast.CallExpr:
6360
if fun, ok := n.Fun.(*ast.Ident); ok {
6461
if fun.Name == "int32" || fun.Name == "int16" {
6562
if idt, ok := n.Args[0].(*ast.Ident); ok {
66-
if n, ok := atoiVarName[idt.Name]; ok {
63+
if n, ok := atoiVarObj[idt.Obj]; ok {
6764
// Detect int32(v) and int16(v)
6865
return gosec.NewIssue(ctx, n, i.ID(), i.What, i.Severity, i.Confidence), nil
6966
}

testutils/source.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,6 @@ func main() {
525525

526526
// SampleCodeG109 - Potential Integer OverFlow
527527
SampleCodeG109 = []CodeSample{
528-
// Bind to all networks explicitly
529528
{[]string{`
530529
package main
531530
@@ -592,6 +591,22 @@ func test() {
592591
bigValue := 30
593592
value := int32(bigValue)
594593
fmt.Println(value)
594+
}`}, 0, gosec.NewConfig()}, {[]string{`
595+
package main
596+
597+
import (
598+
"fmt"
599+
"strconv"
600+
)
601+
602+
func main() {
603+
value := 10
604+
if value == 10 {
605+
value, _ := strconv.Atoi("2147483648")
606+
fmt.Println(value)
607+
}
608+
v := int32(value)
609+
fmt.Println(v)
595610
}`}, 0, gosec.NewConfig()}}
596611

597612
// SampleCodeG110 - potential DoS vulnerability via decompression bomb

0 commit comments

Comments
 (0)