github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/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 "tmpfs": {"syz_mount_image$tmpfs"}, 240 }, 241 extraSubsystems: map[string][]string{ 242 "udf": {"UDF FILESYSTEM"}, 243 }, 244 } 245 testMaintainers = ` 246 Maintainers List 247 ---------------- 248 249 .. note:: When reading this list, please look for the most precise areas 250 first. When adding to this list, please keep the entries in 251 alphabetical order. 252 253 FILESYSTEMS (VFS and infrastructure) 254 M: Developer <email_vfs@email.com> 255 L: linux-fsdevel@vger.kernel.org 256 S: Maintained 257 F: fs/* 258 F: include/linux/fs.h 259 F: include/linux/fs_types.h 260 F: include/uapi/linux/fs.h 261 F: include/uapi/linux/openat2.h 262 263 EXT4 FILE SYSTEM 264 M: Developer <email_ext4@email.com> 265 M: Developer <email_ext4_2@email.com> 266 L: linux-ext4@vger.kernel.org 267 S: Maintained 268 W: http://ext4.wiki.kernel.org 269 Q: http://patchwork.ozlabs.org/project/linux-ext4/list/ 270 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git 271 F: Documentation/filesystems/ext4/ 272 F: fs/ext4/ 273 F: include/trace/events/ext4.h 274 275 FREEVXFS FILESYSTEM 276 M: Developer <email_vxfs@email.com> 277 S: Maintained 278 W: ftp://ftp.openlinux.org/pub/people/hch/vxfs 279 F: fs/freevxfs/ 280 281 MEMORY MANAGEMENT 282 M: Developer <email_mm@email.com> 283 L: linux-mm@kvack.org 284 S: Maintained 285 W: http://www.linux-mm.org 286 T: git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 287 T: quilt git://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new 288 F: include/linux/gfp.h 289 F: include/linux/gfp_types.h 290 F: include/linux/memory_hotplug.h 291 F: include/linux/mm.h 292 F: include/linux/mmzone.h 293 F: include/linux/pagewalk.h 294 F: include/linux/vmalloc.h 295 F: mm/ 296 F: tools/testing/selftests/vm/ 297 298 TMPFS (SHMEM FILESYSTEM) 299 M: Developer <email_shmem@email.com> 300 L: tmpfs@kvack.org 301 S: Maintained 302 F: include/linux/shmem_fs.h 303 F: mm/shmem* 304 305 UDF FILESYSTEM 306 M: email_udf <email_udf@email.com> 307 L: linux-fsdevel@vger.kernel.org 308 S: Maintained 309 F: Documentation/filesystems/udf.rst 310 F: fs/udf/ 311 312 THE REST 313 M: Developer <email_rest@email.com> 314 L: linux-kernel@vger.kernel.org 315 S: Buried alive in reporters 316 T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 317 F: * 318 F: */ 319 320 ` 321 )