Skip to content

Commit 7d5925b

Browse files
committed
tools/syz-imagegen: accept filesystem descriptions as input
Don't generate just the hard-coded list of filesystems, but also generate seeds for the externally supplied json description of a filesystem. Add a special syscall attribute to help syz-imagegen guess the actual filesystem name from the syz_mount_image variant name.
1 parent e12e5ba commit 7d5925b

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

prog/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type SyscallAttrs struct {
4848
Automatic bool
4949
AutomaticHelper bool
5050
Fsck string
51+
// Filesystem is used in tools/syz-imagegen when fs name cannot be deduced from
52+
// the part after $.
53+
Filesystem string
5154
}
5255

5356
// MaxArgs is maximum number of syscall arguments.

tools/syz-imagegen/imagegen.go

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"bufio"
1717
"bytes"
1818
"encoding/binary"
19+
"encoding/json"
1920
"errors"
2021
"flag"
2122
"fmt"
@@ -40,16 +41,18 @@ import (
4041
// FileSystem represents one file system.
4142
// Each FileSystem produces multiple images, see MkfsFlagCombinations and Image type.
4243
type FileSystem struct {
43-
// Name of the file system. Needs to match syz_mount_image$NAME name.
44-
Name string
44+
// Name of the file system. Needs to match the name passed to mount().
45+
Name string `json:"name"`
46+
// By default, syz_mount_image$NAME are generated. SyscallSuffix overrides the part after $.
47+
SyscallSuffix string `json:"syscall_suffix"`
4548
// Imagegen autodetects size for images starting from MinSize and then repeatedly doubling it if mkfs fails.
46-
MinSize int
49+
MinSize int `json:"min_size"`
4750
// Don't populate this image with files (can't mount read-write).
48-
ReadOnly bool
51+
ReadOnly bool `json:"read_only"`
4952
// These flags are always appended to mkfs as is.
50-
MkfsFlags []string
53+
MkfsFlags []string `json:"mkfs_flags"`
5154
// Generate images for all possible permutations of these flag combinations.
52-
MkfsFlagCombinations [][]string
55+
MkfsFlagCombinations [][]string `json:"mkfs_flag_combinations"`
5356
// Custom mkfs invocation, if nil then mkfs.name is invoked in a standard way.
5457
Mkfs func(img *Image) error
5558
}
@@ -552,7 +555,14 @@ func (fs FileSystem) filePrefix() string {
552555
if fs.Name == parttable {
553556
return syzReadPartTable
554557
}
555-
return syzMountImage + "_" + fs.Name
558+
return syzMountImage + "_" + fs.suffix()
559+
}
560+
561+
func (fs FileSystem) suffix() string {
562+
if fs.SyscallSuffix != "" {
563+
return fs.SyscallSuffix
564+
}
565+
return fs.Name
556566
}
557567

558568
// Image represents one image we generate for a file system.
@@ -586,6 +596,7 @@ func main() {
586596
flagPopulate = flag.String("populate", "", "populate the specified image with files (for internal use)")
587597
flagKeepImage = flag.Bool("keep", false, "save disk images as .img files")
588598
flagFS = flag.String("fs", "", "comma-separated list of filesystems to generate, all if empty")
599+
flagFromJSON = flag.String("from_json", "", "load the fs config from the file and generate seeds for it")
589600
)
590601
flag.Parse()
591602
if *flagDebug {
@@ -601,6 +612,12 @@ func main() {
601612
if err != nil {
602613
tool.Fail(err)
603614
}
615+
if *flagFromJSON != "" {
616+
fs := loadFilesystem(*flagFromJSON)
617+
fileSystems = append(fileSystems, fs)
618+
// Generate seeds only for the specific filesystem.
619+
*flagFS = fs.suffix()
620+
}
604621
addEmptyImages(target)
605622
images, err := generateImages(target, *flagFS, *flagList)
606623
if err != nil {
@@ -655,7 +672,10 @@ func addEmptyImages(target *prog.Target) {
655672
if call.CallName != syzMountImage {
656673
continue
657674
}
658-
name := strings.TrimPrefix(call.Name, syzMountImage+"$")
675+
name := call.Attrs.Filesystem
676+
if name == "" {
677+
name = strings.TrimPrefix(call.Name, syzMountImage+"$")
678+
}
659679
if have[name] {
660680
continue
661681
}
@@ -735,7 +755,7 @@ func printResults(images []*Image, shutdown chan struct{}, keepImage, verbose bo
735755
func generateImages(target *prog.Target, flagFS string, list bool) ([]*Image, error) {
736756
var images []*Image
737757
for _, fs := range fileSystems {
738-
if flagFS != "" && !strings.Contains(","+flagFS+",", ","+fs.Name+",") {
758+
if flagFS != "" && !strings.Contains(","+flagFS+",", ","+fs.suffix()+",") {
739759
continue
740760
}
741761
index := 0
@@ -910,10 +930,24 @@ func writeImage(img *Image, data []byte) ([]byte, error) {
910930
fmt.Fprintf(buf, `%s(AUTO, &AUTO="$`, syzReadPartTable)
911931
} else {
912932
fmt.Fprintf(buf, `%s$%v(&AUTO='%v\x00', &AUTO='./file0\x00', 0x0, &AUTO, 0x1, AUTO, &AUTO="$`,
913-
syzMountImage, img.fs.Name, img.fs.Name)
933+
syzMountImage, img.fs.suffix(), img.fs.Name)
914934
}
915935
buf.Write(b64Data)
916936
fmt.Fprintf(buf, "\")\n")
917937

918938
return buf.Bytes(), nil
919939
}
940+
941+
func loadFilesystem(fileName string) FileSystem {
942+
file, err := os.Open(fileName)
943+
if err != nil {
944+
tool.Fail(err)
945+
}
946+
defer file.Close()
947+
var fs FileSystem
948+
err = json.NewDecoder(file).Decode(&fs)
949+
if err != nil {
950+
tool.Failf("failed to parse JSON: %v", err)
951+
}
952+
return fs
953+
}

0 commit comments

Comments
 (0)