github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-usbgen/usbgen.go (about) 1 // Copyright 2019 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package main 5 6 import ( 7 "encoding/hex" 8 "flag" 9 "fmt" 10 "os" 11 "regexp" 12 "sort" 13 14 "github.com/google/syzkaller/pkg/osutil" 15 "github.com/google/syzkaller/pkg/tool" 16 ) 17 18 func main() { 19 flag.Parse() 20 args := flag.Args() 21 if len(args) != 2 { 22 usage() 23 } 24 25 syslog, err := os.ReadFile(args[0]) 26 if err != nil { 27 tool.Failf("failed to read file %v: %v", args[0], err) 28 } 29 30 usbIds := extractIds(syslog, "USBID", 34) 31 hidIds := extractIds(syslog, "HIDID", 24) 32 33 output := []byte(`// Code generated by tools/syz-usbgen. DO NOT EDIT. 34 // See docs/linux/external_fuzzing_usb.md 35 36 package linux 37 38 `) 39 output = append(output, generateIdsVar(usbIds, "usbIds")...) 40 output = append(output, []byte("\n")...) 41 output = append(output, generateIdsVar(hidIds, "hidIds")...) 42 43 if err := osutil.WriteFile(args[1], output); err != nil { 44 tool.Failf("failed to output file %v: %v", args[1], err) 45 } 46 } 47 48 func extractIds(syslog []byte, prefix string, size int) []string { 49 re := fmt.Sprintf("%s: [0-9a-f]{%d}", prefix, size) 50 r := regexp.MustCompile(re) 51 matches := r.FindAll(syslog, -1) 52 uniqueMatches := make(map[string]bool) 53 for _, match := range matches { 54 uniqueMatches[string(match)] = true 55 } 56 sortedMatches := make([]string, 0) 57 for match := range uniqueMatches { 58 match = match[len(prefix+": "):] 59 match = match[:size] 60 sortedMatches = append(sortedMatches, match) 61 } 62 sort.Strings(sortedMatches) 63 return sortedMatches 64 } 65 66 func generateIdsVar(ids []string, name string) []byte { 67 output := []byte(fmt.Sprintf("var %s = ", name)) 68 for i, id := range ids { 69 decodedID, err := hex.DecodeString(id) 70 if err != nil { 71 tool.Failf("failed to decode hex string %v: %v", id, err) 72 } 73 prefix := "\t" 74 suffix := " +" 75 if i == 0 { 76 prefix = "" 77 } 78 if i == len(ids)-1 { 79 suffix = "" 80 } 81 outputID := fmt.Sprintf("%v%#v%v\n", prefix, string(decodedID), suffix) 82 output = append(output, []byte(outputID)...) 83 } 84 85 if len(ids) == 0 { 86 output = append(output, []byte("\"\"")...) 87 } 88 89 fmt.Printf("%v %s ids written\n", len(ids), name) 90 91 return output 92 } 93 94 func usage() { 95 fmt.Fprintf(os.Stderr, "usage:\n") 96 fmt.Fprintf(os.Stderr, " syz-usbgen syslog.txt sys/linux/init_vusb_ids.go\n") 97 os.Exit(1) 98 }