fstests: convert remaining tests to SPDX license tags
[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 seq=`basename $0`
21 seqres=$RESULT_DIR/$seq
22 echo "QA output created by $seq"
23
24 here=`pwd`
25 tmp=/tmp/$$
26 status=1        # failure is the default!
27 trap "_cleanup; exit \$status" 0 1 2 3 15
28
29 _cleanup()
30 {
31         cd /
32         rm -f $tmp.*
33 }
34
35 # get standard environment, filters and checks
36 . ./common/rc
37 . ./common/filter
38 . ./common/filestreams
39
40 # remove previous $seqres.full before test
41 rm -f $seqres.full
42
43 # real QA test starts here
44 drop_caches()
45 {
46         while [ true ]; do
47                 echo 2 > /proc/sys/vm/drop_caches
48                 sleep 1
49         done
50 }
51
52 # Modify as appropriate.
53 _supported_fs generic
54 _supported_os Linux
55 _require_scratch_size $((2*1024*1024)) # kb
56
57 # check for filestreams
58 _check_filestreams_support || _notrun "filestreams not available"
59
60 # use small AGs for frequent stream switching
61 _scratch_mkfs_xfs -d agsize=20m,size=2g >> $seqres.full 2>&1 ||
62         _fail "mkfs failed"
63 _scratch_mount "-o filestreams"
64
65 # start background inode reclaim
66 drop_caches &
67 pid=$!
68
69 # Stress the filestreams allocator via continuous allocation to a file under
70 # different parent dirs. Remove the old dirs as the file is moved so the MRU
71 # references point to an unlinked inode by the time they are removed. If the
72 # old dir inodes are reclaimed and associated memory reused, MRU cleanup can
73 # access the inode after it's been freed.
74 dir=$SCRATCH_MNT
75 for i in $(seq 0 90); do
76         mkdir -p $dir/$i
77         $XFS_IO_PROG -fc "falloc $(($i * 20))m 20m" $dir/$i/file
78
79         mkdir -p $dir/$((i + 1))
80         mv $dir/$i/file $dir/$((i + 1))/file
81         rmdir $dir/$i
82
83         # throttle to ensure this loop sees several cache reclaims
84         sleep 0.1
85 done
86
87 kill $pid 2> /dev/null
88 wait $pid 2> /dev/null
89
90 echo Silence is golden
91
92 # success, all done
93 status=0
94 exit