github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/subsystem/linux/subsystems_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 linux 5 6 import ( 7 "io/fs" 8 "testing" 9 "testing/fstest" 10 11 "github.com/google/syzkaller/pkg/subsystem" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestGroupLinuxSubsystems(t *testing.T) { 16 subsystems, err := listFromRepoInner( 17 prepareTestLinuxRepo(t, []byte(testMaintainers)), 18 nil) 19 if err != nil { 20 t.Fatal(err) 21 } 22 for _, s := range subsystems { 23 // The regexps used for matching rules may change later, so let's not compare them here. 24 s.PathRules = nil 25 // It complicates the test, so let's skip it here. 26 s.Parents = nil 27 } 28 expected := []*subsystem.Subsystem{ 29 { 30 Name: "fs", 31 Lists: []string{"linux-fsdevel@vger.kernel.org"}, 32 // Two different subsystems point to linux-fsdevel@vger.kernel.org, so 33 // we do not include maintainers. 34 }, 35 { 36 Name: "ext4", 37 Lists: []string{"linux-ext4@vger.kernel.org"}, 38 Maintainers: []string{"email_ext4@email.com", "email_ext4_2@email.com"}, 39 }, 40 { 41 Name: "mm", 42 Lists: []string{"linux-mm@kvack.org"}, 43 Maintainers: []string{"email_mm@email.com"}, 44 }, 45 { 46 Name: "tmpfs", 47 Lists: []string{"tmpfs@kvack.org"}, 48 Maintainers: []string{"email_shmem@email.com"}, 49 }, 50 { 51 Name: "kernel", 52 Lists: []string{"linux-kernel@vger.kernel.org"}, 53 Maintainers: []string{"email_rest@email.com"}, 54 }, 55 } 56 assert.ElementsMatch(t, subsystems, expected) 57 } 58 59 func TestCustomCallRules(t *testing.T) { 60 subsystems, err := listFromRepoInner( 61 prepareTestLinuxRepo(t, []byte(testMaintainers)), 62 testRules, 63 ) 64 if err != nil { 65 t.Fatal(err) 66 } 67 for _, s := range subsystems { 68 // The regexps used for matching rules may change later, so let's not compare them here. 69 s.PathRules = nil 70 // It complicates the test, so let's skip it here. 71 s.Parents = nil 72 } 73 // Ensure that the subsystem from the custom rule is present. 74 assert.Contains(t, subsystems, &subsystem.Subsystem{ 75 Name: "udf", 76 Maintainers: []string{"email_udf@email.com"}, 77 Lists: []string{"linux-fsdevel@vger.kernel.org"}, 78 }) 79 // Now that udf is excluded, it becomes possible to generate a maintainer list for vfs. 80 assert.Contains(t, subsystems, &subsystem.Subsystem{ 81 Name: "fs", 82 Lists: []string{"linux-fsdevel@vger.kernel.org"}, 83 Maintainers: []string{"email_vfs@email.com"}, 84 }) 85 86 expectCalls := map[string][]string{ 87 "ext4": {"syz_mount_image$ext4"}, 88 "tmpfs": {"syz_mount_image$tmpfs"}, 89 } 90 gotCalls := map[string][]string{} 91 for _, s := range subsystems { 92 if len(s.Syscalls) > 0 { 93 gotCalls[s.Name] = s.Syscalls 94 } 95 } 96 assert.Equal(t, len(expectCalls), len(gotCalls)) 97 for name, expect := range expectCalls { 98 assert.ElementsMatchf(t, expect, gotCalls[name], "syscalls of %s", name) 99 } 100 } 101 102 func TestLinuxSubsystemPaths(t *testing.T) { 103 // For the list of subsystems, see TestLinuxSubsystemsList. 104 // Here we rely on the same ones. 105 repo := prepareTestLinuxRepo(t, []byte(testMaintainers)) 106 subsystems, err := listFromRepoInner(repo, nil) 107 if err != nil { 108 t.Fatal(err) 109 } 110 matcher := subsystem.MakePathMatcher(subsystems) 111 tests := []struct { 112 path string 113 list []string 114 }{ 115 { 116 path: `fs/internal.h`, 117 list: []string{"kernel", "fs"}, 118 }, 119 { 120 path: `fs/ext4/mmp.c`, 121 list: []string{"kernel", "fs", "ext4"}, 122 }, 123 { 124 // The subsystem is not present in our test MAINTAINERS. 125 path: `fs/fat/inode.c`, 126 list: []string{"kernel", "fs"}, 127 }, 128 { 129 path: `fs/freevxfs/vxfs_olt.c`, 130 list: []string{"kernel", "fs"}, 131 }, 132 { 133 path: `mm/memory.c`, 134 list: []string{"kernel", "mm"}, 135 }, 136 { 137 path: `mm/shmem.c`, 138 list: []string{"kernel", "mm", "tmpfs"}, 139 }, 140 { 141 path: `include/net/ah.h`, 142 list: []string{"kernel"}, 143 }, 144 { 145 path: `include/linux/mm.h`, 146 list: []string{"kernel", "mm"}, 147 }, 148 { 149 path: `include/linux/fs.h`, 150 list: []string{"kernel", "fs"}, 151 }, 152 } 153 for _, test := range tests { 154 retList := []string{} 155 for _, s := range matcher.Match(test.path) { 156 retList = append(retList, s.Name) 157 } 158 assert.ElementsMatchf(t, retList, test.list, 159 "invalid subsystems for %#v", test.path) 160 } 161 } 162 163 func TestLinuxSubsystemParents(t *testing.T) { 164 // For the list of subsystems, see TestLinuxSubsystemsList. 165 // Here we rely on the same ones. 166 repo := prepareTestLinuxRepo(t, []byte(testMaintainers)) 167 subsystems, err := listFromRepoInner(repo, nil) 168 if err != nil { 169 t.Fatal(err) 170 } 171 ensureParents(t, subsystems, map[string][]string{ 172 "ext4": {"fs"}, 173 "mm": {"kernel"}, 174 "fs": {"kernel"}, 175 "tmpfs": {"mm"}, 176 "freevxfs": {"fs"}, 177 }) 178 179 // Now check that our custom parent rules work. 180 subsystems2, err := listFromRepoInner(repo, &customRules{ 181 addParents: map[string][]string{ 182 // Just for the sake of testing. 183 "fs": {"mm"}, 184 }, 185 }) 186 if err != nil { 187 t.Fatal(err) 188 } 189 ensureParents(t, subsystems2, map[string][]string{ 190 "ext4": {"fs"}, 191 "mm": {"kernel"}, 192 "fs": {"mm"}, // We test for this change. 193 "tmpfs": {"mm"}, 194 "freevxfs": {"fs"}, 195 }) 196 } 197 198 func ensureParents(t *testing.T, subsystems []*subsystem.Subsystem, 199 expectParents map[string][]string) { 200 for _, s := range subsystems { 201 names := []string{} 202 for _, p := range s.Parents { 203 names = append(names, p.Name) 204 } 205 assert.ElementsMatch(t, names, expectParents[s.Name], 206 "wrong parents for %#v", s.Name) 207 } 208 } 209 210 func prepareTestLinuxRepo(t *testing.T, maintainers []byte) fs.FS { 211 return fstest.MapFS{ 212 `fs/ext4/fsync.c`: {}, 213 `fs/ext4/fsync.h`: {}, 214 `fs/ext4/mmp.c`: {}, 215 `fs/ext4/mmp.h`: {}, 216 `fs/freevxfs/vxfs_olt.c`: {}, 217 `fs/freevxfs/vxfs_olt.h`: {}, 218 `fs/freevxfs/file.c`: {}, 219 `fs/udf/file.c`: {}, 220 `fs/udf/file2.c`: {}, 221 `fs/udf/file3.c`: {}, 222 `fs/file.c`: {}, 223 `fs/internal.h`: {}, 224 `include/linux/fs.h`: {}, 225 `include/linux/mm.h`: {}, 226 `include/linux/shmem_fs.h`: {}, 227 `include/net/ah.h`: {}, 228 `mm/memory.c`: {}, 229 `mm/shmem.c`: {}, 230 `mm/shmem2.c`: {}, 231 `MAINTAINERS`: {Data: maintainers}, 232 } 233 } 234 235 var ( 236 testRules = &customRules{ 237 subsystemCalls: map[string][]string{ 238 "ext4": {"syz_mount_image$ext4"}, 239 "vxfs": {"syz_mount_image$vxfs"}, 240 "tmpfs": {"syz_mount_image$tmpfs"}, 241 }, 242 extraSubsystems: map[string][]string{ 243 "udf": {"UDF FILESYSTEM"}, 244 }, 245 } 246 testMaintainers = ` 247 Maintainers List 248 ---------------- 249 250 .. note:: When reading this list, please look for the most precise areas 251 first. When adding to this list, please keep the entries in 252 alphabetical order. 253 254 FILESYSTEMS (VFS and infrastructure) 255 M: Developer <email_vfs@email.com> 256 L: linux-fsdevel@vger.kernel.org 257 S: Maintained 258 F: fs/* 259 F: include/linux/fs.h 260 F: include/linux/fs_types.h 261 F: include/uapi/linux/fs.h 262 F: include/uapi/linux/openat2.h 263 264 EXT4 FILE SYSTEM 265 M: Developer <email_ext4@email.com> 266 M: Developer <email_ext4_2@email.com> 267 L: linux-ext4@vger.kernel.org 268 S: Maintained 269 W: http://ext4.wiki.kernel.org 270 Q: http://patchwork.ozlabs.org/project/linux-ext4/list/ 271 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git 272 F: Documentation/filesystems/ext4/ 273 F: fs/ext4/ 274 F: include/trace/events/ext4.h 275 276 FREEVXFS FILESYSTEM 277 M: Developer <email_vxfs@email.com> 278 S: Maintained 279 W: ftp://ftp.openlinux.org/pub/people/hch/vxfs 280 F: fs/freevxfs/ 281 282 MEMORY MANAGEMENT 283 M: Developer <email_mm@email.com> 284 L: linux-mm@kvack.org 285 S: Maintained 286 W: http://www.linux-mm.org 287 T: git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 288 T: quilt git://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new 289 F: include/linux/gfp.h 290 F: include/linux/gfp_types.h 291 F: include/linux/memory_hotplug.h 292 F: include/linux/mm.h 293 F: include/linux/mmzone.h 294 F: include/linux/pagewalk.h 295 F: include/linux/vmalloc.h 296 F: mm/ 297 F: tools/testing/selftests/vm/ 298 299 TMPFS (SHMEM FILESYSTEM) 300 M: Developer <email_shmem@email.com> 301 L: tmpfs@kvack.org 302 S: Maintained 303 F: include/linux/shmem_fs.h 304 F: mm/shmem* 305 306 UDF FILESYSTEM 307 M: email_udf <email_udf@email.com> 308 L: linux-fsdevel@vger.kernel.org 309 S: Maintained 310 F: Documentation/filesystems/udf.rst 311 F: fs/udf/ 312 313 THE REST 314 M: Developer <email_rest@email.com> 315 L: linux-kernel@vger.kernel.org 316 S: Buried alive in reporters 317 T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 318 F: * 319 F: */ 320 321 ` 322 )