aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorHrutvik Kanabar <hrutvik@google.com>2022-10-27 14:27:38 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2022-11-21 11:06:14 +0100
commit8cc0c5c595cd14fb40a0052bbedd7ff3e96f64c8 (patch)
tree15cb9691fec7ea1daf15ec6baddb02bb3a0ea7b4 /tools
parent285c8cf9f727a6c7566b6079552c5705e61f621a (diff)
sys/linux, tools/syz-imagegen: update `syz_mount_image` to use `compressed_image`
Rather than accepting "segments", `syz_mount_image` now accepts a compressed image. Since this is already a corpus-breaking change, also rearrange the arguments so that the image is at the end. This makes it easier to inspect what the other arguments are set to. We need to increase the timeout associated with `syz_mount_image`, as decompression and execution take a little longer. 5000ms should be very generous. This commit updates the descriptions and the `syz-imagegen` tool. The executor, seed images, and asset saving will be updated in future commits.
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-imagegen/imagegen.go91
1 files changed, 17 insertions, 74 deletions
diff --git a/tools/syz-imagegen/imagegen.go b/tools/syz-imagegen/imagegen.go
index 5f120b29d..367e7d8b0 100644
--- a/tools/syz-imagegen/imagegen.go
+++ b/tools/syz-imagegen/imagegen.go
@@ -14,7 +14,6 @@ package main
import (
"bytes"
- "encoding/hex"
"errors"
"flag"
"fmt"
@@ -692,10 +691,11 @@ func (image *Image) generateSize() error {
}
image.hash = crc32.ChecksumIEEE(data)
- segments := calculateSegments(data)
-
// Write out image *with* change of directory.
- out := writeImage(image, len(data), segments, true)
+ out, err := writeImage(image, data, true)
+ if err != nil {
+ return fmt.Errorf("failed to write image: %v", err)
+ }
p, err := image.target.Deserialize(out, prog.Strict)
if err != nil {
@@ -767,85 +767,28 @@ func runCmd(cmd string, args ...string) ([]byte, error) {
return osutil.RunCmd(10*time.Minute, "", cmd, args...)
}
-func writeImage(image *Image, length int, segments []Segment, chdir bool) []byte {
+func writeImage(image *Image, data []byte, chdir bool) ([]byte, error) {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "# Code generated by tools/syz-imagegen. DO NOT EDIT.\n")
fmt.Fprintf(buf, "# requires: manual\n\n")
fmt.Fprintf(buf, "# %v\n\n", image)
- fmt.Fprintf(buf, `syz_mount_image$%v(&(0x7f0000000000)='%v\x00', &(0x7f0000000100)='./file0\x00',`+
- ` 0x%x, 0x%x, &(0x7f0000000200)=[`,
- image.fs.Name, image.fs.Name, length, len(segments))
- addr := 0x7f0000010000
- for i, seg := range segments {
- if i != 0 {
- fmt.Fprintf(buf, ", ")
- }
- fmt.Fprintf(buf, `{&(0x%x)="%v", 0x%x, 0x%x}`,
- addr, hex.EncodeToString(seg.data), len(seg.data), seg.offset)
- addr += len(seg.data)
- }
+ compressedData := prog.Compress(data)
+ b64Data := prog.EncodeB64(compressedData)
chdirAsInt := 0
if chdir {
chdirAsInt = 1
}
- fmt.Fprintf(buf, "], 0x0, &(0x%x), 0x%x)\n", addr, chdirAsInt)
- return buf.Bytes()
-}
-
-type Segment struct {
- offset int
- data []byte
-}
+ fmt.Fprintf(buf, `syz_mount_image$%v(&AUTO='%v\x00', &AUTO='./file0\x00',`+
+ ` 0x%x, AUTO, 0x0, &AUTO, 0x%x, &AUTO="$`,
+ image.fs.Name, image.fs.Name, len(data), chdirAsInt)
+ buf.Write(b64Data)
+ fmt.Fprintf(buf, "\")\n")
-func calculateSegments(data []byte) []Segment {
- const (
- skip = 32 // min zero bytes to skip
- align = 32 // non-zero block alignment
- )
- data0 := data
- zeros := make([]byte, skip+align)
- var segs []Segment
- offset := 0
- for len(data) != 0 {
- pos := bytes.Index(data, zeros)
- if pos == -1 {
- segs = append(segs, Segment{offset, data})
- break
- }
- pos = (pos + align - 1) & ^(align - 1)
- if pos != 0 {
- segs = append(segs, Segment{offset, data[:pos]})
- }
- for pos < len(data) && data[pos] == 0 {
- pos++
- }
- pos = pos & ^(align - 1)
- offset += pos
- data = data[pos:]
- }
- if false {
- // self-test.
- restored := make([]byte, len(data0))
- for _, seg := range segs {
- copy(restored[seg.offset:], seg.data)
- }
- if !bytes.Equal(data0, restored) {
- panic("restored data differs!")
- }
- }
- return segs
+ return buf.Bytes(), nil
}
// TODO: also generate syz_read_part_table tests:
-// fmt.Printf(`syz_read_part_table(0x%x, 0x%x, &(0x7f0000000200)=[`,
-// len(data0), len(segs))
-// addr := 0x7f0000010000
-// for i, seg := range segs {
-// if i != 0 {
-// fmt.Printf(", ")
-// }
-// fmt.Printf(`{&(0x%x)="%v", 0x%x, 0x%x}`,
-// addr, hex.EncodeToString(seg.data), len(seg.data), seg.offset)
-// addr = (addr + len(seg.data) + 0xff) & ^0xff
-// }
-// fmt.Printf("])\n")
+// fmt.Fprintf(buf, `syz_read_part_table(0x%x, 0x%x, &AUTO="$`,
+// len(data), len(compressedData))
+// buf.Write(b64Data)
+// fmt.Fprintf(buf, "\")\n")