xref: /aosp_15_r20/tools/security/fuzzing/fuzzer_parser/fuzzparser.go (revision d9ecfb0f4d734c9ce41cde8ac4d585b094fd4222)
1*d9ecfb0fSAndroid Build Coastguard Workerpackage main
2*d9ecfb0fSAndroid Build Coastguard Worker
3*d9ecfb0fSAndroid Build Coastguard Workerimport (
4*d9ecfb0fSAndroid Build Coastguard Worker	"bytes"
5*d9ecfb0fSAndroid Build Coastguard Worker	"flag"
6*d9ecfb0fSAndroid Build Coastguard Worker	"fmt"
7*d9ecfb0fSAndroid Build Coastguard Worker	"io"
8*d9ecfb0fSAndroid Build Coastguard Worker	"io/ioutil"
9*d9ecfb0fSAndroid Build Coastguard Worker	"os"
10*d9ecfb0fSAndroid Build Coastguard Worker	"path/filepath"
11*d9ecfb0fSAndroid Build Coastguard Worker	"strings"
12*d9ecfb0fSAndroid Build Coastguard Worker
13*d9ecfb0fSAndroid Build Coastguard Worker	"github.com/google/blueprint/parser"
14*d9ecfb0fSAndroid Build Coastguard Worker)
15*d9ecfb0fSAndroid Build Coastguard Worker
16*d9ecfb0fSAndroid Build Coastguard Workervar (
17*d9ecfb0fSAndroid Build Coastguard Worker	result	= make(map[string]string)
18*d9ecfb0fSAndroid Build Coastguard Worker	defaults = make(map[string]string)
19*d9ecfb0fSAndroid Build Coastguard Worker	Root = ""
20*d9ecfb0fSAndroid Build Coastguard Worker)
21*d9ecfb0fSAndroid Build Coastguard Worker
22*d9ecfb0fSAndroid Build Coastguard Workervar (
23*d9ecfb0fSAndroid Build Coastguard Worker	exitCode = 0
24*d9ecfb0fSAndroid Build Coastguard Worker)
25*d9ecfb0fSAndroid Build Coastguard Worker
26*d9ecfb0fSAndroid Build Coastguard Workerfunc report(err error) {
27*d9ecfb0fSAndroid Build Coastguard Worker	fmt.Fprintln(os.Stderr, err)
28*d9ecfb0fSAndroid Build Coastguard Worker	exitCode = 2
29*d9ecfb0fSAndroid Build Coastguard Worker}
30*d9ecfb0fSAndroid Build Coastguard Worker
31*d9ecfb0fSAndroid Build Coastguard Workerfunc usage() {
32*d9ecfb0fSAndroid Build Coastguard Worker	usageViolation("")
33*d9ecfb0fSAndroid Build Coastguard Worker}
34*d9ecfb0fSAndroid Build Coastguard Worker
35*d9ecfb0fSAndroid Build Coastguard Workerfunc usageViolation(violation string) {
36*d9ecfb0fSAndroid Build Coastguard Worker	fmt.Fprintln(os.Stderr, violation)
37*d9ecfb0fSAndroid Build Coastguard Worker	fmt.Fprintln(os.Stderr, "usage: fuzzparser [flags] [path ...]")
38*d9ecfb0fSAndroid Build Coastguard Worker	flag.PrintDefaults()
39*d9ecfb0fSAndroid Build Coastguard Worker	os.Exit(2)
40*d9ecfb0fSAndroid Build Coastguard Worker}
41*d9ecfb0fSAndroid Build Coastguard Worker
42*d9ecfb0fSAndroid Build Coastguard Workerfunc processFile(filename string, out io.Writer) error {
43*d9ecfb0fSAndroid Build Coastguard Worker	f, err := os.Open(filename)
44*d9ecfb0fSAndroid Build Coastguard Worker	if err != nil {
45*d9ecfb0fSAndroid Build Coastguard Worker		return err
46*d9ecfb0fSAndroid Build Coastguard Worker	}
47*d9ecfb0fSAndroid Build Coastguard Worker	defer f.Close()
48*d9ecfb0fSAndroid Build Coastguard Worker
49*d9ecfb0fSAndroid Build Coastguard Worker	return processReader(filename, f, out)
50*d9ecfb0fSAndroid Build Coastguard Worker}
51*d9ecfb0fSAndroid Build Coastguard Worker
52*d9ecfb0fSAndroid Build Coastguard Workerfunc processReader(filename string, in io.Reader, out io.Writer) error {
53*d9ecfb0fSAndroid Build Coastguard Worker	src, err := ioutil.ReadAll(in)
54*d9ecfb0fSAndroid Build Coastguard Worker	if err != nil {
55*d9ecfb0fSAndroid Build Coastguard Worker		return err
56*d9ecfb0fSAndroid Build Coastguard Worker	}
57*d9ecfb0fSAndroid Build Coastguard Worker
58*d9ecfb0fSAndroid Build Coastguard Worker	r := bytes.NewBuffer(src)
59*d9ecfb0fSAndroid Build Coastguard Worker	file, errs := parser.ParseAndEval(filename, r, parser.NewScope(nil))
60*d9ecfb0fSAndroid Build Coastguard Worker
61*d9ecfb0fSAndroid Build Coastguard Worker	modules := findModules(file)
62*d9ecfb0fSAndroid Build Coastguard Worker	// First collect all the defaults into a dictionary
63*d9ecfb0fSAndroid Build Coastguard Worker	for _, mod := range modules {
64*d9ecfb0fSAndroid Build Coastguard Worker	    if mod.Type == "cc_defaults" {
65*d9ecfb0fSAndroid Build Coastguard Worker	    	default_name := ""
66*d9ecfb0fSAndroid Build Coastguard Worker	    	for _, prop := range mod.Map.Properties {
67*d9ecfb0fSAndroid Build Coastguard Worker				if prop.Name == "name" {
68*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
69*d9ecfb0fSAndroid Build Coastguard Worker					default_name = value[1:strings.Index(value, "@")-1]
70*d9ecfb0fSAndroid Build Coastguard Worker				} else if prop.Name == "static_libs" || prop.Name == "shared_libs" {
71*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
72*d9ecfb0fSAndroid Build Coastguard Worker					for strings.Index(value, "\"") > -1 {
73*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
74*d9ecfb0fSAndroid Build Coastguard Worker						lib_name := value[:strings.Index(value, "\"")]
75*d9ecfb0fSAndroid Build Coastguard Worker						if _ , ok := defaults[default_name]; ok {
76*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += "," + lib_name
77*d9ecfb0fSAndroid Build Coastguard Worker						} else {
78*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += lib_name
79*d9ecfb0fSAndroid Build Coastguard Worker						}
80*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
81*d9ecfb0fSAndroid Build Coastguard Worker					}
82*d9ecfb0fSAndroid Build Coastguard Worker				} else if prop.Name == "defaults" {
83*d9ecfb0fSAndroid Build Coastguard Worker					// Get the defaults of the default
84*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
85*d9ecfb0fSAndroid Build Coastguard Worker					for strings.Index(value, "\"") > -1 {
86*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
87*d9ecfb0fSAndroid Build Coastguard Worker						sub_default_name := value[:strings.Index(value, "\"")]
88*d9ecfb0fSAndroid Build Coastguard Worker						if _ , ok := defaults[default_name]; ok {
89*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += "," + defaults[sub_default_name]
90*d9ecfb0fSAndroid Build Coastguard Worker						} else {
91*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += defaults[sub_default_name]
92*d9ecfb0fSAndroid Build Coastguard Worker						}
93*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
94*d9ecfb0fSAndroid Build Coastguard Worker					}
95*d9ecfb0fSAndroid Build Coastguard Worker				} else if prop.Name == "target" {
96*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
97*d9ecfb0fSAndroid Build Coastguard Worker					if default_name == "binder_fuzz_defaults" {
98*d9ecfb0fSAndroid Build Coastguard Worker						fmt.Printf("---> target value for %s: %s\n", default_name ,value)
99*d9ecfb0fSAndroid Build Coastguard Worker					}
100*d9ecfb0fSAndroid Build Coastguard Worker					for strings.Index(value, "\"") > -1 {
101*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
102*d9ecfb0fSAndroid Build Coastguard Worker						lib := value[:strings.Index(value, "\"")]
103*d9ecfb0fSAndroid Build Coastguard Worker						if _ , ok := defaults[default_name]; ok {
104*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += "," + lib
105*d9ecfb0fSAndroid Build Coastguard Worker						} else {
106*d9ecfb0fSAndroid Build Coastguard Worker							defaults[default_name] += lib
107*d9ecfb0fSAndroid Build Coastguard Worker						}
108*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
109*d9ecfb0fSAndroid Build Coastguard Worker					}
110*d9ecfb0fSAndroid Build Coastguard Worker				}
111*d9ecfb0fSAndroid Build Coastguard Worker			}
112*d9ecfb0fSAndroid Build Coastguard Worker		}
113*d9ecfb0fSAndroid Build Coastguard Worker    }
114*d9ecfb0fSAndroid Build Coastguard Worker
115*d9ecfb0fSAndroid Build Coastguard Worker	for _, mod := range modules {
116*d9ecfb0fSAndroid Build Coastguard Worker		if mod.Type == "cc_fuzz" {
117*d9ecfb0fSAndroid Build Coastguard Worker			fuzzer_name := ""
118*d9ecfb0fSAndroid Build Coastguard Worker			for _, prop := range mod.Map.Properties {
119*d9ecfb0fSAndroid Build Coastguard Worker				// First get the name of the fuzzer
120*d9ecfb0fSAndroid Build Coastguard Worker				if prop.Name == "name" {
121*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
122*d9ecfb0fSAndroid Build Coastguard Worker					fuzzer_name = value[1:strings.Index(value, "@")-1]
123*d9ecfb0fSAndroid Build Coastguard Worker				} else if prop.Name == "defaults" {
124*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
125*d9ecfb0fSAndroid Build Coastguard Worker					if strings.Index(value, "@") == 0 {
126*d9ecfb0fSAndroid Build Coastguard Worker						value = value[1:]
127*d9ecfb0fSAndroid Build Coastguard Worker					}
128*d9ecfb0fSAndroid Build Coastguard Worker					default_name := value[strings.Index(value, "[")+2: strings.Index(value, "@")-1]
129*d9ecfb0fSAndroid Build Coastguard Worker					if _, ok := result[fuzzer_name]; ok {
130*d9ecfb0fSAndroid Build Coastguard Worker						result[fuzzer_name] += "," + defaults[default_name]
131*d9ecfb0fSAndroid Build Coastguard Worker					} else {
132*d9ecfb0fSAndroid Build Coastguard Worker						result[fuzzer_name] += defaults[default_name]
133*d9ecfb0fSAndroid Build Coastguard Worker					}
134*d9ecfb0fSAndroid Build Coastguard Worker				} else if prop.Name == "static_libs" || prop.Name == "shared_libs" {
135*d9ecfb0fSAndroid Build Coastguard Worker					value := prop.Value.String()
136*d9ecfb0fSAndroid Build Coastguard Worker					for strings.Index(value, "\"") > -1 {
137*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
138*d9ecfb0fSAndroid Build Coastguard Worker						lib_name := value[:strings.Index(value, "\"")]
139*d9ecfb0fSAndroid Build Coastguard Worker						if _ , ok := result[fuzzer_name]; ok {
140*d9ecfb0fSAndroid Build Coastguard Worker							result[fuzzer_name] += "," + lib_name
141*d9ecfb0fSAndroid Build Coastguard Worker						} else {
142*d9ecfb0fSAndroid Build Coastguard Worker							result[fuzzer_name] += lib_name
143*d9ecfb0fSAndroid Build Coastguard Worker						}
144*d9ecfb0fSAndroid Build Coastguard Worker						value = value[strings.Index(value, "\"")+1:]
145*d9ecfb0fSAndroid Build Coastguard Worker					}
146*d9ecfb0fSAndroid Build Coastguard Worker				}
147*d9ecfb0fSAndroid Build Coastguard Worker			}
148*d9ecfb0fSAndroid Build Coastguard Worker	    }
149*d9ecfb0fSAndroid Build Coastguard Worker	}
150*d9ecfb0fSAndroid Build Coastguard Worker
151*d9ecfb0fSAndroid Build Coastguard Worker	if len(errs) > 0 {
152*d9ecfb0fSAndroid Build Coastguard Worker		for _, err := range errs {
153*d9ecfb0fSAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, err)
154*d9ecfb0fSAndroid Build Coastguard Worker		}
155*d9ecfb0fSAndroid Build Coastguard Worker		return fmt.Errorf("%d parsing errors", len(errs))
156*d9ecfb0fSAndroid Build Coastguard Worker	}
157*d9ecfb0fSAndroid Build Coastguard Worker
158*d9ecfb0fSAndroid Build Coastguard Worker    return err
159*d9ecfb0fSAndroid Build Coastguard Worker}
160*d9ecfb0fSAndroid Build Coastguard Worker
161*d9ecfb0fSAndroid Build Coastguard Workerfunc findModules(file *parser.File) (modules []*parser.Module) {
162*d9ecfb0fSAndroid Build Coastguard Worker    if file != nil {
163*d9ecfb0fSAndroid Build Coastguard Worker		for _, def := range file.Defs {
164*d9ecfb0fSAndroid Build Coastguard Worker			if module, ok := def.(*parser.Module); ok {
165*d9ecfb0fSAndroid Build Coastguard Worker				modules = append(modules, module)
166*d9ecfb0fSAndroid Build Coastguard Worker			}
167*d9ecfb0fSAndroid Build Coastguard Worker		}
168*d9ecfb0fSAndroid Build Coastguard Worker	}
169*d9ecfb0fSAndroid Build Coastguard Worker	return modules
170*d9ecfb0fSAndroid Build Coastguard Worker}
171*d9ecfb0fSAndroid Build Coastguard Worker
172*d9ecfb0fSAndroid Build Coastguard Workerfunc walkDir(path string) {
173*d9ecfb0fSAndroid Build Coastguard Worker	visitFile := func(path string, f os.FileInfo, err error) error {
174*d9ecfb0fSAndroid Build Coastguard Worker		if err == nil && f.Name() == "Android.bp" {
175*d9ecfb0fSAndroid Build Coastguard Worker			err = processFile(path, os.Stdout)
176*d9ecfb0fSAndroid Build Coastguard Worker		}
177*d9ecfb0fSAndroid Build Coastguard Worker		if err != nil {
178*d9ecfb0fSAndroid Build Coastguard Worker			fmt.Printf("ERROR")
179*d9ecfb0fSAndroid Build Coastguard Worker			report(err)
180*d9ecfb0fSAndroid Build Coastguard Worker		}
181*d9ecfb0fSAndroid Build Coastguard Worker		return nil
182*d9ecfb0fSAndroid Build Coastguard Worker	}
183*d9ecfb0fSAndroid Build Coastguard Worker    fmt.Printf("Parsing %s recursively...\n", path)
184*d9ecfb0fSAndroid Build Coastguard Worker	filepath.Walk(path, visitFile)
185*d9ecfb0fSAndroid Build Coastguard Worker}
186*d9ecfb0fSAndroid Build Coastguard Worker
187*d9ecfb0fSAndroid Build Coastguard Workerfunc main() {
188*d9ecfb0fSAndroid Build Coastguard Worker	flag.Usage = usage
189*d9ecfb0fSAndroid Build Coastguard Worker	flag.Parse()
190*d9ecfb0fSAndroid Build Coastguard Worker
191*d9ecfb0fSAndroid Build Coastguard Worker	for i := 0; i < flag.NArg(); i++ {
192*d9ecfb0fSAndroid Build Coastguard Worker		Root := flag.Arg(i)
193*d9ecfb0fSAndroid Build Coastguard Worker		fmt.Printf("Root %s\n", Root)
194*d9ecfb0fSAndroid Build Coastguard Worker		switch dir, err := os.Stat(Root); {
195*d9ecfb0fSAndroid Build Coastguard Worker		case err != nil:
196*d9ecfb0fSAndroid Build Coastguard Worker			report(err)
197*d9ecfb0fSAndroid Build Coastguard Worker		case dir.IsDir():
198*d9ecfb0fSAndroid Build Coastguard Worker			walkDir(Root)
199*d9ecfb0fSAndroid Build Coastguard Worker		default:
200*d9ecfb0fSAndroid Build Coastguard Worker			if err := processFile(Root, os.Stdout); err != nil {
201*d9ecfb0fSAndroid Build Coastguard Worker				report(err)
202*d9ecfb0fSAndroid Build Coastguard Worker			}
203*d9ecfb0fSAndroid Build Coastguard Worker		}
204*d9ecfb0fSAndroid Build Coastguard Worker	}
205*d9ecfb0fSAndroid Build Coastguard Worker
206*d9ecfb0fSAndroid Build Coastguard Worker	fmt.Printf("-------------------------------------\n")
207*d9ecfb0fSAndroid Build Coastguard Worker	fmt.Printf("Fuzzer name -------Library name------\n")
208*d9ecfb0fSAndroid Build Coastguard Worker	if len(result) > 0 {
209*d9ecfb0fSAndroid Build Coastguard Worker		for k, v := range result {
210*d9ecfb0fSAndroid Build Coastguard Worker			if len(v) == 0 {
211*d9ecfb0fSAndroid Build Coastguard Worker				v = "NOT FOUND"
212*d9ecfb0fSAndroid Build Coastguard Worker			}
213*d9ecfb0fSAndroid Build Coastguard Worker			fmt.Printf("%s:%s\n", k, v)
214*d9ecfb0fSAndroid Build Coastguard Worker		}
215*d9ecfb0fSAndroid Build Coastguard Worker	}
216*d9ecfb0fSAndroid Build Coastguard Worker
217*d9ecfb0fSAndroid Build Coastguard Worker	os.Exit(exitCode)
218*d9ecfb0fSAndroid Build Coastguard Worker}
219