overlay: run unionmount testsuite test cases
[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 _require_xfs_io_command "falloc"
57
58 # check for filestreams
59 _check_filestreams_support || _notrun "filestreams not available"
60
61 # use small AGs for frequent stream switching
62 _scratch_mkfs_xfs -d agsize=20m,size=2g >> $seqres.full 2>&1 ||
63         _fail "mkfs failed"
64 _scratch_mount "-o filestreams"
65
66 # start background inode reclaim
67 drop_caches &
68 pid=$!
69
70 # Stress the filestreams allocator via continuous allocation to a file under
71 # different parent dirs. Remove the old dirs as the file is moved so the MRU
72 # references point to an unlinked inode by the time they are removed. If the
73 # old dir inodes are reclaimed and associated memory reused, MRU cleanup can
74 # access the inode after it's been freed.
75 dir=$SCRATCH_MNT
76 for i in $(seq 0 90); do
77         mkdir -p $dir/$i
78         $XFS_IO_PROG -fc "falloc $(($i * 20))m 20m" $dir/$i/file
79
80         mkdir -p $dir/$((i + 1))
81         mv $dir/$i/file $dir/$((i + 1))/file
82         rmdir $dir/$i
83
84         # throttle to ensure this loop sees several cache reclaims
85         sleep 0.1
86 done
87
88 kill $pid 2> /dev/null
89 wait $pid 2> /dev/null
90
91 echo Silence is golden
92
93 # success, all done
94 status=0
95 exit