xfs/007: fix regressions on V4 filesystems
[xfstests-dev.git] / tests / xfs / 445
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2018 Red Hat, Inc.  All Rights Reserved.
4 #
5 # FS QA Test 445
6 #
7 # Test the XFS filestreams allocator for use-after-free inode access. The
8 # filestreams allocator uses the MRU and historically kept around unreferenced
9 # inode pointers in each element. These pointers could outlive the inodes they
10 # referred to and thus lead to access of freed or reused memory when the MRU
11 # element was reaped. Test for this problem by performing filestream allocations
12 # against short-lived parent directory inodes.
13 #
14 # Note that some form of kernel debug mechanism for use-after-free detection
15 # (i.e., KASAN) is required for this test to reproduce the original problem.
16 # This is because XFS uses a kmem cache for xfs_inode objects which means that
17 # the backing pages for freed inodes may still reside in the cache with the
18 # freed inodes in a partially initialized state.
19 #
20 . ./common/preamble
21 _begin_fstest auto quick filestreams
22
23 # Import common functions.
24 . ./common/filter
25 . ./common/filestreams
26
27 # real QA test starts here
28 drop_caches()
29 {
30         while [ true ]; do
31                 echo 2 > /proc/sys/vm/drop_caches
32                 sleep 1
33         done
34 }
35
36 # Modify as appropriate.
37 _supported_fs generic
38 _require_scratch_size $((2*1024*1024)) # kb
39 _require_xfs_io_command "falloc"
40
41 # check for filestreams
42 _check_filestreams_support || _notrun "filestreams not available"
43
44 # Disable the scratch rt device to avoid test failures relating to the rt
45 # bitmap consuming free space in our small data device and throwing off the
46 # filestreams allocator.
47 unset SCRATCH_RTDEV
48
49 # use small AGs for frequent stream switching
50 _scratch_mkfs_xfs -d agsize=20m,size=2g >> $seqres.full 2>&1 ||
51         _fail "mkfs failed"
52 _scratch_mount "-o filestreams"
53
54 # start background inode reclaim
55 drop_caches &
56 pid=$!
57
58 # Stress the filestreams allocator via continuous allocation to a file under
59 # different parent dirs. Remove the old dirs as the file is moved so the MRU
60 # references point to an unlinked inode by the time they are removed. If the
61 # old dir inodes are reclaimed and associated memory reused, MRU cleanup can
62 # access the inode after it's been freed.
63 dir=$SCRATCH_MNT
64 for i in $(seq 0 90); do
65         mkdir -p $dir/$i
66         $XFS_IO_PROG -fc "falloc $(($i * 20))m 20m" $dir/$i/file
67
68         mkdir -p $dir/$((i + 1))
69         mv $dir/$i/file $dir/$((i + 1))/file
70         rmdir $dir/$i
71
72         # throttle to ensure this loop sees several cache reclaims
73         sleep 0.1
74 done
75
76 kill $pid 2> /dev/null
77 wait $pid 2> /dev/null
78
79 echo Silence is golden
80
81 # success, all done
82 status=0
83 exit