diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-09-15 13:36:15 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-09-27 13:07:37 +0200 |
| commit | 2b420c9686b7c95216d491a97fcd5158acb810f2 (patch) | |
| tree | 091b25ff54bf7f41a7fcf3a027a714fb2e7255b8 | |
| parent | 1856cdc9b3652a082c5bfa0e08a9f883baece8ec (diff) | |
sys/linux: extract raw images from syz_mount_image
To simplify the extraction code, let's make segments non-overlapping
even before execution.
| -rw-r--r-- | dashboard/dashapi/dashapi.go | 1 | ||||
| -rw-r--r-- | prog/analysis.go | 38 | ||||
| -rw-r--r-- | prog/target.go | 6 | ||||
| -rw-r--r-- | sys/linux/init.go | 1 | ||||
| -rw-r--r-- | sys/linux/init_images.go | 95 | ||||
| -rw-r--r-- | sys/linux/init_images_test.go | 126 | ||||
| -rw-r--r-- | sys/linux/testdata/fs_images/0.in | 1 | ||||
| -rw-r--r-- | sys/linux/testdata/fs_images/0.out0 | bin | 0 -> 8736 bytes | |||
| -rw-r--r-- | sys/linux/testdata/fs_images/1.in | 1 | ||||
| -rw-r--r-- | sys/linux/testdata/fs_images/1.out0 | bin | 0 -> 262144 bytes |
10 files changed, 251 insertions, 18 deletions
diff --git a/dashboard/dashapi/dashapi.go b/dashboard/dashapi/dashapi.go index 2a6c8df22..cbc89cce2 100644 --- a/dashboard/dashapi/dashapi.go +++ b/dashboard/dashapi/dashapi.go @@ -417,6 +417,7 @@ const ( KernelObject AssetType = "kernel_object" KernelImage AssetType = "kernel_image" HTMLCoverageReport AssetType = "html_coverage_report" + MountInRepro AssetType = "mount_in_repro" ) type BisectResult struct { diff --git a/prog/analysis.go b/prog/analysis.go index 1b572f0c0..04f0b270a 100644 --- a/prog/analysis.go +++ b/prog/analysis.go @@ -10,6 +10,7 @@ package prog import ( "fmt" + "io" ) type state struct { @@ -337,3 +338,40 @@ func checkMaxCallID(id int) { panic(fmt.Sprintf("too many syscalls, have %v, max supported %v", id, fallbackCallMask+1)) } } + +type ExtractedAssetType int + +const ( + MountInRepro ExtractedAssetType = iota +) + +type ExtractedAsset struct { + Call int + Type ExtractedAssetType + Reader io.Reader + Error error +} + +func (p *Prog) ExtractAssets() []*ExtractedAsset { + handler := p.Target.ExtractMountedImage + if handler == nil { + // Such an operation is not supported by the target. + return nil + } + ret := []*ExtractedAsset{} + for id, c := range p.Calls { + // So far we only support the MountInRepro asset. + reader, err := handler(c) + if reader == nil && err == nil { + // This is not the call that contains the mount image. + continue + } + ret = append(ret, &ExtractedAsset{ + Type: MountInRepro, + Call: id, + Reader: reader, + Error: err, + }) + } + return ret +} diff --git a/prog/target.go b/prog/target.go index 56c2a94ca..bc619d5b6 100644 --- a/prog/target.go +++ b/prog/target.go @@ -5,6 +5,7 @@ package prog import ( "fmt" + "io" "math/rand" "sort" "sync" @@ -61,6 +62,11 @@ type Target struct { SyscallMap map[string]*Syscall ConstMap map[string]uint64 + // The extracted images will be then saved to the disk or uploaded to the asset storage. + // Returns nil if the call does not mount any image. + // We have to use io.Reader since such blobs can get pretty large. + ExtractMountedImage func(c *Call) (io.Reader, error) + init sync.Once initArch func(target *Target) types []Type diff --git a/sys/linux/init.go b/sys/linux/init.go index 9080cbd7c..09b70f092 100644 --- a/sys/linux/init.go +++ b/sys/linux/init.go @@ -54,6 +54,7 @@ func InitTarget(target *prog.Target) { target.MakeDataMmap = targets.MakePosixMmap(target, true, true) target.Neutralize = arch.neutralize + target.ExtractMountedImage = arch.extractSyzMountImage target.SpecialTypes = map[string]func(g *prog.Gen, typ prog.Type, dir prog.Dir, old prog.Arg) ( prog.Arg, []*prog.Call){ "timespec": arch.generateTimespec, diff --git a/sys/linux/init_images.go b/sys/linux/init_images.go index e914b8b4d..eb1d7c7ad 100644 --- a/sys/linux/init_images.go +++ b/sys/linux/init_images.go @@ -4,12 +4,45 @@ package linux import ( + "bytes" "fmt" "io" + "sort" "github.com/google/syzkaller/prog" ) +func (arch *arch) extractSyzMountImage(c *prog.Call) (io.Reader, error) { + // In order to reduce the size of syzlang programs, disk imags are de facto compressed. + // Here we do the uncompression. + if c.Meta.CallName != "syz_mount_image" { + return nil, nil + } + ret, err := parseSyzMountImage(c) + if err != nil { + // Parsing failed --> do not try to recover, just ignore. + return nil, err + } else if len(ret.segments) == 0 { + return nil, fmt.Errorf("an empty image") + } + readers := []io.Reader{} + nextPos := 0 + // Add fake zero readers between segments, so that we can combine them to read the whole image. + for _, segment := range ret.segments { + offset := int(segment.offset.Val) + if offset > nextPos { + readers = append(readers, &zeroReader{left: offset - nextPos}) + } + size := int(segment.size.Val) + readers = append(readers, bytes.NewReader(segment.data.Data()[0:size])) + nextPos = offset + size + } + if int(ret.size.Val) > nextPos { + readers = append(readers, &zeroReader{left: int(ret.size.Val) - nextPos}) + } + return io.MultiReader(readers...), nil +} + type zeroReader struct { left int } @@ -25,39 +58,67 @@ func (zr *zeroReader) Read(p []byte) (n int, err error) { for i := 0; i < toRead; i++ { p[i] = 0 } + zr.left -= toRead return toRead, nil } -func newZeroReader(size int) io.Reader { - return &zeroReader{left: size} -} - const imageMaxSize = 129 << 20 func fixUpImageSegments(parsed *mountImageArgs) { + const maxImageSegments = 4096 parsed.filterSegments(func(i int, segment *mountImageSegment) bool { + if i >= maxImageSegments { + // We don't want more than maxImageSegments segments. + return false + } if segment.parseError != nil { + // Delete mangled segment structures. return false } return segment.offset.Val < imageMaxSize && segment.size.Val < imageMaxSize }) + // Overwriting of the image multiple times is not efficient and complicates image extraction in Go. + // So let's make segments non-overlapping. + sort.Stable(parsed) + resizeSegment := func(s *mountImageSegment, size uint64) { + s.size.Val = size + s.data.SetData(s.data.Data()[0:size]) + } + newSize := parsed.size.Val - for _, segment := range parsed.segments { + if newSize > imageMaxSize { + newSize = imageMaxSize + } + + for idx, segment := range parsed.segments { actualSize := uint64(len(segment.data.Data())) - if segment.size.Val > actualSize { + if segment.size.Val != actualSize { segment.size.Val = actualSize } + if idx > 0 { + // Adjust the end of the previous segment. + prevSegment := parsed.segments[idx-1] + if prevSegment.offset.Val+prevSegment.size.Val > segment.offset.Val { + resizeSegment(prevSegment, segment.offset.Val-prevSegment.offset.Val) + } + } if segment.offset.Val+segment.size.Val > imageMaxSize { - segment.offset.Val = imageMaxSize - segment.size.Val + resizeSegment(segment, imageMaxSize-segment.offset.Val) } if segment.offset.Val+segment.size.Val > newSize { newSize = segment.offset.Val + segment.size.Val } } if newSize > imageMaxSize { - newSize = imageMaxSize + // Assert that the logic above is not broken. + panic("newSize > imageMaxSize") } parsed.size.Val = newSize + + // Drop 0-size segments. + parsed.filterSegments(func(i int, segment *mountImageSegment) bool { + return segment.size.Val > 0 + }) } func (arch *arch) fixUpSyzMountImage(c *prog.Call) { @@ -71,10 +132,6 @@ func (arch *arch) fixUpSyzMountImage(c *prog.Call) { deactivateSyzMountImage(c) return } - const maxImageSegments = 4096 - ret.filterSegments(func(i int, _ *mountImageSegment) bool { - return i < maxImageSegments - }) fixUpImageSegments(ret) } @@ -99,6 +156,20 @@ func (m *mountImageArgs) filterSegments(filter func(int, *mountImageSegment) boo m.segmentsCount.Val = uint64(len(newArgs)) } +// Methods for segment sorting. +func (m *mountImageArgs) Len() int { return len(m.segments) } +func (m *mountImageArgs) Swap(i, j int) { + inner := m.segmentsGroup.Inner + inner[i], inner[j] = inner[j], inner[i] + m.segments[i], m.segments[j] = m.segments[j], m.segments[i] +} +func (m *mountImageArgs) Less(i, j int) bool { + if m.segments[i].offset.Val != m.segments[j].offset.Val { + return m.segments[i].offset.Val < m.segments[j].offset.Val + } + return m.segments[i].size.Val < m.segments[j].size.Val +} + type mountImageSegment struct { data *prog.DataArg offset *prog.ConstArg diff --git a/sys/linux/init_images_test.go b/sys/linux/init_images_test.go index 816d59902..0bfb68cc4 100644 --- a/sys/linux/init_images_test.go +++ b/sys/linux/init_images_test.go @@ -4,12 +4,24 @@ package linux import ( + "flag" + "fmt" + "io" + "math/rand" + "os" + "path/filepath" + "reflect" + "sort" + "strings" "testing" + "time" + "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" "github.com/google/syzkaller/sys/targets" ) +// nolint: lll func TestSyzMountImageNeutralize(t *testing.T) { prog.TestDeserializeHelper(t, targets.Linux, targets.AMD64, nil, []prog.DeserializeTest{ { @@ -23,16 +35,118 @@ func TestSyzMountImageNeutralize(t *testing.T) { Out: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file1\x00', 0x240, 0x2, &(0x7f0000000200)=[{&(0x7f0000010000)="cefaad1bc0210000ff0f0000ffffffffffffffffffffffffffffffff73797a6b616c73797a6b616c00"/64, 0x40, 0x0}, {&(0x7f0000010040)="0200000011000000140000001f22000002000000ed4100000000000001000000020000005ffb19635ffb19635ffb196300"/64, 0x40, 0x200}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, }, { - // Overflow over the max image size. - In: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file2\x00', 0x8200000, 0x2, &(0x7f0000000200)=[{&(0x7f0000010000)="cefaad1bc0210000ff0f0000ffffffffffffffffffffffffffffffff73797a6b616c73797a6b616c00"/64, 0x40, 0x0}, {&(0x7f0000010040)="0200000011000000140000001f22000002000000ed4100000000000001000000020000005ffb19635ffb19635ffb196300"/64, 0x400, 0x80fffff}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, - // It should shift the overflowing segment and adjust the total size. - Out: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file2\x00', 0x8100000, 0x2, &(0x7f0000000200)=[{&(0x7f0000010000)="cefaad1bc0210000ff0f0000ffffffffffffffffffffffffffffffff73797a6b616c73797a6b616c00"/64, 0x40, 0x0}, {&(0x7f0000010040)="0200000011000000140000001f22000002000000ed4100000000000001000000020000005ffb19635ffb19635ffb196300"/64, 0x40, 0x80fffc0}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, - }, - { // Invalid offset. In: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file1\x00', 0x20, 0x2, &(0x7f0000000200)=[{&(0x7f0000010000)="cefaad1bc0210000ff0f0000ffffffffffffffffffffffffffffffff73797a6b616c73797a6b616c00"/64, 0x40, 0x0}, {&(0x7f0000010040)="0200000011000000140000001f22000002000000ed4100000000000001000000020000005ffb19635ffb19635ffb196300"/64, 0x40, 0x9100000}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, // The segment is deleted. Out: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file1\x00', 0x40, 0x1, &(0x7f0000000200)=[{&(0x7f0000010000)="cefaad1bc0210000ff0f0000ffffffffffffffffffffffffffffffff73797a6b616c73797a6b616c00"/64, 0x40, 0x0}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, }, + { + // Overlapping and unsorted segments. + In: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file0\x00', 0x2220, 0x3, &(0x7f0000000200)=[{&(0x7f0000010000)="cafef00d"/64, 0x50, 0x20}, {&(0x7f0000010040)="deadbeef"/64, 0x30, 0x10}, {&(0x7f0000010080)="abcdef"/64, 0x40, 0x20}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, + Out: `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file0\x00', 0x2220, 0x2, &(0x7f0000000200)=[{&(0x7f0000010040)="deadbeef00"/16, 0x10, 0x10}, {&(0x7f0000010000)="cafef00d00"/64, 0x40, 0x20}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)`, + }, }) } + +var flagUpdate = flag.Bool("update", false, "update test files accordingly to current results") + +func TestExtractSyzMountImage(t *testing.T) { + target, err := prog.GetTarget(targets.Linux, targets.AMD64) + if err != nil { + t.Fatal(err) + } + files, err := filepath.Glob(filepath.Join("testdata", "fs_images", "*.in")) + if err != nil { + t.Fatalf("directory read failed: %v", err) + } + allOutFiles, err := filepath.Glob(filepath.Join("testdata", "fs_images", "*.out*")) + if err != nil { + t.Fatalf("directory read failed: %v", err) + } + testedOutFiles := []string{} + for _, file := range files { + if !strings.HasSuffix(file, ".in") { + continue + } + sourceProg, err := os.ReadFile(file) + if err != nil { + t.Fatal(err) + } + p, err := target.Deserialize(sourceProg, prog.NonStrict) + if err != nil { + t.Fatalf("failed to deserialize %s: %s", file, err) + } + base := strings.TrimSuffix(file, ".in") + for _, asset := range p.ExtractAssets() { + if asset.Type != prog.MountInRepro { + continue + } + outFilePath := fmt.Sprintf("%s.out%d", base, asset.Call) + var testResult []byte + if asset.Reader != nil { + var err error + testResult, err = io.ReadAll(asset.Reader) + if err != nil { + t.Fatal(err) + } + } + if *flagUpdate && asset.Reader != nil { + err := osutil.WriteFile(outFilePath, testResult) + if err != nil { + t.Fatal(err) + } + } + outExists := osutil.IsExist(outFilePath) + if !outExists && asset.Reader != nil { + t.Fatalf("#%d: mount found, but does not exist in the answer", asset.Call) + } + if testResult != nil { + testedOutFiles = append(testedOutFiles, outFilePath) + outFile, err := os.ReadFile(outFilePath) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(testResult, outFile) { + t.Fatalf("output not equal:\nWant: %x\nGot: %x", outFile, testResult) + } + } + } + } + sort.Strings(testedOutFiles) + sort.Strings(allOutFiles) + if !reflect.DeepEqual(testedOutFiles, allOutFiles) { + t.Fatalf("all out files: %v\ntested files: %v", allOutFiles, testedOutFiles) + } +} + +// nolint: lll +func TestSyzMountImageMutation(t *testing.T) { + // We cannot unfortunately just import InitTest from prog. + rs := rand.NewSource(time.Now().UnixNano()) + iters := 100 + target, err := prog.GetTarget("linux", "amd64") + if err != nil { + t.Fatal(err) + } + + var p *prog.Prog + var ct *prog.ChoiceTable + + const mutateCount = 1000 + const baseProg = `syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file0\x00', 0x2220, 0x2, &(0x7f0000000200)=[{&(0x7f0000010040)="deadbeef00"/16, 0x10, 0x10}, {&(0x7f0000010000)="cafef00d00"/64, 0x40, 0x20}], 0x0, &(0x7f00000100a0)={[], [], 0x0}, 0x0)` + + for i := 0; i < iters; i++ { + if i%mutateCount == 0 { + var err error + p, err = target.Deserialize([]byte(baseProg), prog.NonStrict) + if err != nil { + t.Fatal(err) + } + ct = target.DefaultChoiceTable() + } + p.Mutate(rs, 1, ct, nil, nil) + // We only call the extraction code and do mutations to catch possible panics. + // It is absolutely normal for syzkaller to mutate the call to the level when the image can no longer be extracted. + p.Target.ExtractMountedImage(p.Calls[0]) + } +} diff --git a/sys/linux/testdata/fs_images/0.in b/sys/linux/testdata/fs_images/0.in new file mode 100644 index 000000000..3eed397dd --- /dev/null +++ b/sys/linux/testdata/fs_images/0.in @@ -0,0 +1 @@ +syz_mount_image$bfs(&(0x7f0000000000)='bfs\x00', &(0x7f0000000100)='./file0\x00', 0x2220, 0x3, &(0x7f0000000200)=[{&(0x7f0000010040)="deadbeef00"/64, 0x10, 0x10}, {&(0x7f0000010000)="cafef00d00"/64, 0x0, 0x20}, {&(0x7f0000010080)="abcdef00"/64, 0x40, 0x20}], 0x0, &(0x7f00000100a0)={[], [], 0x0})
\ No newline at end of file diff --git a/sys/linux/testdata/fs_images/0.out0 b/sys/linux/testdata/fs_images/0.out0 Binary files differnew file mode 100644 index 000000000..424d24bd8 --- /dev/null +++ b/sys/linux/testdata/fs_images/0.out0 diff --git a/sys/linux/testdata/fs_images/1.in b/sys/linux/testdata/fs_images/1.in new file mode 100644 index 000000000..3d9d3e222 --- /dev/null +++ b/sys/linux/testdata/fs_images/1.in @@ -0,0 +1 @@ +syz_mount_image$ext4(&(0x7f0000000000)='ext4\x00', &(0x7f0000000100)='./file0\x00', 0x40000, 0x2a, &(0x7f0000000200)=[{&(0x7f0000010000)="20000000000100000c000000ce0000000f00000001000000000000000000000000200000002000002000000067fb196367fb19630100ffff53ef01000100000067fb1963000000000000000001000000000000000b000000800000000800000052470000620100000000000000000000000000000000000073797a6b616c6c6572000000000000002f746d702f73797a2d696d61676567656e333234303537373133330000000000000000000000000000000000000000000000000000000000", 0xc0, 0x400}, {&(0x7f00000100c0)="0000000000000000000000009bbd22de26804913867de6e04e8059bc010000000c0000000000000067fb19630000000000000000000000000000000000000000", 0x40, 0x4e0}, {&(0x7f0000010100)="0100000000000500110000000000000000000000040000003c00000000000000", 0x20, 0x560}, {&(0x7f0000010120)="0300000004000000090000000000000000000000000000000000000000000000", 0x20, 0x640}, {&(0x7f0000010140)="030000001300000023000000ce000f0003000400000000000000000000000000", 0x20, 0x800}, {&(0x7f0000010160)="fffffffffcff0700000000000000000000000000000000000000000000000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff020000000c0001022e000000020000000c0002022e2e00000b00000014000a026c6f73742b666f756e6400000c0000001000050266696c65300000000f0000001000050166696c6531000000100000001000050166696c6532000000100000001000050166696c6533000000110000009403090166696c652e636f6c64000000", 0x480, 0xc00}, {&(0x7f00000105e0)="0b0000000c0001022e00000002000000f40302022e2e00000000000000000000", 0x20, 0x1400}, {&(0x7f0000010600)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x1800}, {&(0x7f0000010620)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x1c00}, {&(0x7f0000010640)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x2000}, {&(0x7f0000010660)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x2400}, {&(0x7f0000010680)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x2800}, {&(0x7f00000106a0)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x2c00}, {&(0x7f00000106c0)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x3000}, {&(0x7f00000106e0)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x3400}, {&(0x7f0000010700)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x3800}, {&(0x7f0000010720)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x3c00}, {&(0x7f0000010740)="0000000000040000000000000000000000000000000000000000000000000000", 0x20, 0x4000}, {&(0x7f0000010760)="504d4d00504d4dff67fb1963000000006872757476696b2e632e676f6f676c6572732e636f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000006c6f6f7032310075782f746573742f73797a5f6d6f756e745f696d6167655f6505000000000000000000000000000000", 0x80, 0x4400}, {&(0x7f00000107e0)="111fc0d901000000803a0900803a090000000000060000000000000005000000", 0x20, 0x4800}, {&(0x7f0000010800)="ffff0100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300000000000000000000000000000000000000000000000000000000000000", 0x420, 0x4c00}, {&(0x7f0000010c20)="0400000000000000000000000000000000000000000000000000000000000000", 0x20, 0x5400}, {&(0x7f0000010c40)="0500000000000000000000000000000000000000000000000000000000000000", 0x20, 0x5800}, {&(0x7f0000010c60)="000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000", 0x60, 0x5c00}, {&(0x7f0000010cc0)="0200000000000000000000000000000000000000000000000000000000000000", 0x20, 0x6000}, {&(0x7f0000010ce0)="2719c0d901000000803a0900803a090000000000060000000000000005000000", 0x20, 0x6400}, {&(0x7f0000010d00)="0300000000000000000000000000000000000000000000000000000000000000", 0x20, 0x6800}, {&(0x7f0000010d20)="0400000000000000000000000000000000000000000000000000000000000000", 0x20, 0x6c00}, {&(0x7f0000010d40)="0500000000000000000000000000000000000000000000000000000000000000", 0x20, 0x7000}, {&(0x7f0000010d60)="000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000", 0x60, 0x7400}, {&(0x7f0000010dc0)="0200000000000000000000000000000000000000000000000000000000000000", 0x20, 0x7800}, {&(0x7f0000010de0)="0c0000000c0001022e000000020000000c0002022e2e00000d0000001000050166696c65300000000e000000d803050766696c65310000000000000000000000", 0x40, 0x7c00}, {&(0x7f0000010e20)="000002ea0100000001000000270f240c000000000000000000000000000000000601f8030000000006000000779b539778617474723100000601f003000000000600000074985397786174747232000000000000000000000000000000000000", 0x60, 0x8000}, {&(0x7f0000010e80)="0000000000000000000000000000000078617474723200007861747472310000", 0x20, 0x83e0}, {&(0x7f0000010ea0)="000000000000000067fb196367fb196367fb1963000000000000000000000000", 0x20, 0x8c00}, {&(0x7f0000010ec0)="ed4100000004000067fb196367fb196367fb196300000000000004000200000000000800050000000af301000400000000000000000000000100000004000000", 0x40, 0x8c80}, {&(0x7f0000010f00)="808100000018000067fb196367fb196367fb196300000000000001000c00000010000800000000000af30300040000000000000000000000010000001200000001000000010000001800000002000000040000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000808100000018000067fb196367fb196367fb196300000000000001000c00000010000800000000000af30300040000000000000000000000010000001900000001000000010000001e00000002000000040000001a0000000000000000000000", 0xe0, 0x8d00}, {&(0x7f0000010fe0)="c04100000030000067fb196367fb196367fb196300000000000002001800000000000800000000000af301000400000000000000000000000c00000005000000", 0x40, 0x9100}, {&(0x7f0000011020)="ed4100000004000067fb196367fb196367fb196300000000000002000200000000000800030000000af30100040000000000000000000000010000001f000000000000000000000000000000000000000000000000000000000000000000000000000000a6b0039d000000000000000000000000000000000000000000000000ed8100001a04000067fb196367fb196367fb196300000000000001000400000000000800010000000af3010004000000000000000000000002000000270000000000000000000000000000000000000000000000000000000000000000000000000000005109c476000000000000000000000000000000000000000000000000ffa100002700000067fb196367fb196367fb196300000000000001000000000000000000010000002f746d702f73797a2d696d61676567656e333234303537373133332f66696c65302f66696c653000000000000000000000000000000000000000000047fa2223000000000000000000000000000000000000000000000000ed8100000a00000067fb196367fb196367fb196300000000000001000400000000000800010000000af301000400000000000000000000000100000029000000000000000000000000000000000000000000000000000000000000000000000000000000d10ea931200000000000000000000000000000000000000000000000ed8100002823000067fb196367fb196367fb196300000000000002001200000000000800010000000af30100040000000000000000000000090000002a0000000000000000000000000000000000000000000000000000000000000000000000000000006077b616000000000000000000000000000000000000000000000000ed8100006400000067fb196367fb196367fb196300000000000001000200000000000800010000000af3010004000000000000000000000001000000330000000000000000000000000000000000000000000000000000000000000000000000000000003ffd7303000000000000000000000000000000000000000000000000", 0x300, 0x9180}, {&(0x7f0000011320)="73797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c000000000000", 0x420, 0x9c00}, {&(0x7f0000011740)="73797a6b616c6c65727300000000000000000000000000000000000000000000", 0x20, 0xa400}, {&(0x7f0000011760)="73797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c657273797a6b616c6c65727300000000000000000000000000000000000000000000000000000000", 0x80, 0xcc00}], 0x0, &(0x7f00000117e0))
\ No newline at end of file diff --git a/sys/linux/testdata/fs_images/1.out0 b/sys/linux/testdata/fs_images/1.out0 Binary files differnew file mode 100644 index 000000000..c498f4d53 --- /dev/null +++ b/sys/linux/testdata/fs_images/1.out0 |
