mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 08:40:55 +00:00 
			
		
		
		
	cmd/compile: intercept string compares in libFuzzer mode
IR string compares as well as calls to string comparison functions such
as `strings.EqualFold` are intercepted and the corresponding libFuzzer
callbacks are invoked with the corresponding arguments. As a result, the
compared strings will be added to libFuzzer’s table of recent compares,
which feeds future mutations performed by the fuzzer and thus allow it
to reach into branches guarded by string comparisons.
The list of methods to intercept is maintained in
`cmd/compile/internal/walk/expr.go` and can easily be extended to cover
more standard library functions in the future.
Change-Id: I5c8b89499c4e19459406795dea923bf777779c51
GitHub-Last-Rev: 6b8529b555
GitHub-Pull-Request: golang/go#51319
Reviewed-on: https://go-review.googlesource.com/c/go/+/387335
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
			
			
This commit is contained in:
		
							parent
							
								
									b58067013e
								
							
						
					
					
						commit
						2b0e457b42
					
				
					 9 changed files with 157 additions and 4 deletions
				
			
		|  | @ -496,6 +496,16 @@ func walkAddString(n *ir.AddStringExpr, init *ir.Nodes) ir.Node { | |||
| 	return r1 | ||||
| } | ||||
| 
 | ||||
| type hookInfo struct { | ||||
| 	paramType   types.Kind | ||||
| 	argsNum     int | ||||
| 	runtimeFunc string | ||||
| } | ||||
| 
 | ||||
| var hooks = map[string]hookInfo{ | ||||
| 	"strings.EqualFold": {paramType: types.TSTRING, argsNum: 2, runtimeFunc: "libfuzzerHookEqualFold"}, | ||||
| } | ||||
| 
 | ||||
| // walkCall walks an OCALLFUNC or OCALLINTER node. | ||||
| func walkCall(n *ir.CallExpr, init *ir.Nodes) ir.Node { | ||||
| 	if n.Op() == ir.OCALLMETH { | ||||
|  | @ -591,6 +601,20 @@ func walkCall1(n *ir.CallExpr, init *ir.Nodes) { | |||
| 	} | ||||
| 
 | ||||
| 	n.Args = args | ||||
| 	funSym := n.X.Sym() | ||||
| 	if base.Debug.Libfuzzer != 0 && funSym != nil { | ||||
| 		if hook, found := hooks[funSym.Pkg.Path+"."+funSym.Name]; found { | ||||
| 			if len(args) != hook.argsNum { | ||||
| 				panic(fmt.Sprintf("%s.%s expects %d arguments, but received %d", funSym.Pkg.Path, funSym.Name, hook.argsNum, len(args))) | ||||
| 			} | ||||
| 			var hookArgs []ir.Node | ||||
| 			for _, arg := range args { | ||||
| 				hookArgs = append(hookArgs, tracecmpArg(arg, types.Types[hook.paramType], init)) | ||||
| 			} | ||||
| 			hookArgs = append(hookArgs, fakePC(n)) | ||||
| 			init.Append(mkcall(hook.runtimeFunc, nil, init, hookArgs...)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // walkDivMod walks an ODIV or OMOD node. | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Khaled Yakdan
						Khaled Yakdan