github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/subsystem/lists/linux_test.go (about) 1 // Copyright 2023 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 lists 5 6 import ( 7 "testing" 8 9 "github.com/google/syzkaller/pkg/subsystem" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 // nolint: lll 14 func TestLinuxUpstreamSubsystems(t *testing.T) { 15 list := subsystem.GetList("linux") 16 if list == nil { 17 t.Fatalf("the list is not registered") 18 } 19 group := subsystem.MakeExtractor(list) 20 21 // For now let's keep all the regression tests in this .go file, but if later 22 // it turns out there are just too many of them, we will need to store it in 23 // separate files. 24 tests := []struct { 25 name string 26 crashes []*subsystem.Crash 27 expect []string 28 }{ 29 { 30 name: `a pure xfs bug`, 31 crashes: []*subsystem.Crash{ 32 { 33 GuiltyPath: `fs/xfs/libxfs/xfs_btree.c`, 34 SyzRepro: []byte(`# https://syzkaller.appspot.com/bug?id=e2907149c69cbccae0842eb502b8af4f6fac52a0 35 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 36 #{"procs":1,"slowdown":1,"sandbox":"","sandbox_arg":0,"close_fds":false} 37 syz_mount_image$xfs(&(0x7f0000000100), &(0x7f0000009640)='./file2\x00', 0x200800, &(0x7f0000000240)=ANY=[], 0x1, 0x9712, &(0x7f0000009680)="$eJzs3Qm4pnPhuPH=") 38 `), 39 }, 40 }, 41 expect: []string{"xfs"}, 42 }, 43 { 44 name: `a seemingly vfs bug`, 45 crashes: []*subsystem.Crash{ 46 { 47 GuiltyPath: `fs/namei.c`, 48 }, 49 { 50 GuiltyPath: `fs/namei.c`, 51 SyzRepro: []byte(`# https://syzkaller.appspot.com/bug?id=cdaf5ed409125df023889aefe50b4cc4a41c0973 52 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 53 #{"threaded":true,"repeat":true,"procs":6,"slowdown":1,"sandbox":"","sandbox_arg":0,"close_fds":false,"ieee802154":true,"sysctl":true,"tmpdir":true,"segv":true} 54 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 55 mkdirat(0xffffffffffffff9c, &(0x7f0000000600)='./file0aaaaaaaaaaaaaaaaa\x00', 0x0) 56 symlinkat(&(0x7f00000004c0)='./file0aaaaaaaaaa/file0\x00', 0xffffffffffffff9c, &(0x7f0000000280)='./file0aaaaaa/file0\x00') 57 `), 58 }, 59 }, 60 expect: []string{"ntfs3"}, 61 }, 62 { 63 name: `a bug with page cache in guilty path`, 64 crashes: []*subsystem.Crash{ 65 { 66 GuiltyPath: `mm/filemap.c`, 67 }, 68 { 69 GuiltyPath: `mm/filemap.c`, 70 SyzRepro: []byte(`# https://syzkaller.appspot.com/bug?id=cdaf5ed409125df023889aefe50b4cc4a41c0973 71 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 72 #{"threaded":true,"repeat":true,"procs":6,"slowdown":1,"sandbox":"","sandbox_arg":0,"close_fds":false,"ieee802154":true,"sysctl":true,"tmpdir":true,"segv":true} 73 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 74 mkdirat(0xffffffffffffff9c, &(0x7f0000000600)='./file0aaaaaaaaaaaaaaaaa\x00', 0x0) 75 symlinkat(&(0x7f00000004c0)='./file0aaaaaaaaaa/file0\x00', 0xffffffffffffff9c, &(0x7f0000000280)='./file0aaaaaa/file0\x00') 76 `), 77 }, 78 }, 79 // There should be no mm in the subsystems. 80 expect: []string{"ntfs3"}, 81 }, 82 { 83 name: "dri bug with usb call", 84 crashes: []*subsystem.Crash{ 85 { 86 GuiltyPath: `drivers/gpu/drm/udl/udl_drv.c`, 87 }, 88 { 89 GuiltyPath: `drivers/gpu/drm/udl/udl_drv.c`, 90 SyzRepro: []byte(` 91 # https://syzkaller.appspot.com/bug?id=56e9aec9bc3b5378c9b231a3f4b3329cf9f80990 92 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 93 #{"procs":1,"slowdown":1,"sandbox":"none","sandbox_arg":0,"tun":true,"netdev":true,"close_fds":true} 94 syz_usb_connect(0x0, 0x24, &(0x7f0000000140)=ANY=[@ANYBLOB="12010000abbe6740e9174e8b089c000000010902120001000000000904000800ff"], 0x0) 95 `), 96 }, 97 }, 98 expect: []string{"dri", "usb"}, 99 }, 100 { 101 name: "ntfs bug with one ntfs guilty path", 102 crashes: []*subsystem.Crash{ 103 { 104 GuiltyPath: `mm/folio-compat.c`, 105 }, 106 { 107 GuiltyPath: `mm/folio-compat.c`, 108 }, 109 { 110 GuiltyPath: `mm/folio-compat.c`, 111 }, 112 { 113 // By chance just one was correct. 114 GuiltyPath: `fs/ntfs3/frecord.c`, 115 SyzRepro: []byte(` 116 # https://syzkaller.appspot.com/bug?id=9a239048a7fff1d8d9b276b240522a2293468dba 117 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 118 #{"procs":1,"slowdown":1,"sandbox":"","sandbox_arg":0,"close_fds":false} 119 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 120 `), 121 }, 122 { 123 GuiltyPath: `mm/folio-compat.c`, 124 SyzRepro: []byte(` 125 # https://syzkaller.appspot.com/bug?id=56e9aec9bc3b5378c9b231a3f4b3329cf9f80990 126 # See https://goo.gl/kgGztJ for information about syzkaller reproducers. 127 #{"procs":1,"slowdown":1,"sandbox":"none","sandbox_arg":0,"tun":true,"netdev":true,"close_fds":true} 128 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 129 `), 130 }, 131 }, 132 expect: []string{"ntfs3"}, 133 }, 134 { 135 name: "many repros point to ntfs, all guilty files are wrong", 136 crashes: []*subsystem.Crash{ 137 { 138 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 139 }, 140 { 141 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 142 }, 143 { 144 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 145 }, 146 { 147 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 148 SyzRepro: []byte(` 149 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 150 `), 151 }, 152 { 153 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 154 SyzRepro: []byte(` 155 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 156 `), 157 }, 158 { 159 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 160 SyzRepro: []byte(` 161 syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==") 162 `), 163 }, 164 }, 165 // "arm" is just too omnipresent, we have to mention it. 166 expect: []string{"ntfs3", "arm"}, 167 }, 168 { 169 name: "guilty files point to media, many repros to usb", 170 crashes: []*subsystem.Crash{ 171 { 172 // Suppose, in one case report parsing failed. 173 GuiltyPath: `arch/arm64/kernel/stacktrace.c`, 174 }, 175 { 176 GuiltyPath: `drivers/media/mc/mc-entity.c`, 177 }, 178 { 179 GuiltyPath: `drivers/media/mc/mc-entity.c`, 180 }, 181 { 182 GuiltyPath: `drivers/media/mc/mc-entity.c`, 183 }, 184 { 185 GuiltyPath: `drivers/media/mc/mc-entity.c`, 186 SyzRepro: []byte(` 187 syz_usb_connect(0x0, 0x58, &(0x7f0000000100)=ANY=[@ANYBLOB="1201000036ee3808d30b55056"]) 188 `), 189 }, 190 { 191 GuiltyPath: `drivers/media/mc/mc-entity.c`, 192 SyzRepro: []byte(` 193 syz_usb_connect(0x0, 0x58, &(0x7f0000000100)=ANY=[@ANYBLOB="1201000036ee3808d30b55056"]) 194 `), 195 }, 196 { 197 GuiltyPath: `drivers/media/mc/mc-entity.c`, 198 SyzRepro: []byte(` 199 syz_usb_connect(0x0, 0x58, &(0x7f0000000100)=ANY=[@ANYBLOB="1201000036ee3808d30b55056"]) 200 `), 201 }, 202 }, 203 // "media" is picked because it's in >= 2/3 guilty paths. 204 expect: []string{"media", "usb"}, 205 }, 206 { 207 name: "wireless bug that should not be net", 208 crashes: []*subsystem.Crash{ 209 { 210 GuiltyPath: `net/mac80211/rate.c`, 211 }, 212 }, 213 expect: []string{"wireless"}, 214 }, 215 { 216 name: "old ntfs bug", 217 crashes: []*subsystem.Crash{ 218 { 219 GuiltyPath: `fs/ntfs/super.c`, 220 SyzRepro: []byte(` 221 syz_mount_image$ntfs(&AUTO, &AUTO, AUTO, &AUTO, AUTO, AUTO, &AUTO)`), 222 }, 223 }, 224 expect: []string{"ntfs3"}, 225 }, 226 { 227 // "p9" is no longer in "net". 228 name: "vf9fs bug", 229 crashes: []*subsystem.Crash{ 230 { 231 GuiltyPath: `net/9p/client.c`, 232 }, 233 }, 234 expect: []string{"v9fs"}, 235 }, 236 } 237 for _, test := range tests { 238 t.Run(test.name, func(t *testing.T) { 239 names := []string{} 240 for _, e := range group.Extract(test.crashes) { 241 names = append(names, e.Name) 242 } 243 assert.ElementsMatch(t, names, test.expect, test.name) 244 }) 245 } 246 }