mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
2529c9486a
Fully scripted conversion, see script in initial SPDX license commit message. tests/xfs/044 was hand massaged to remove duplicate copyright and divider lines before running the script. Signed-off-by: Dave Chinner <dchinner@redhat.com>
95 lines
2.5 KiB
Bash
Executable File
95 lines
2.5 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved.
|
|
#
|
|
# FS QA Test 445
|
|
#
|
|
# Test the XFS filestreams allocator for use-after-free inode access. The
|
|
# filestreams allocator uses the MRU and historically kept around unreferenced
|
|
# inode pointers in each element. These pointers could outlive the inodes they
|
|
# referred to and thus lead to access of freed or reused memory when the MRU
|
|
# element was reaped. Test for this problem by performing filestream allocations
|
|
# against short-lived parent directory inodes.
|
|
#
|
|
# Note that some form of kernel debug mechanism for use-after-free detection
|
|
# (i.e., KASAN) is required for this test to reproduce the original problem.
|
|
# This is because XFS uses a kmem cache for xfs_inode objects which means that
|
|
# the backing pages for freed inodes may still reside in the cache with the
|
|
# freed inodes in a partially initialized state.
|
|
#
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
_cleanup()
|
|
{
|
|
cd /
|
|
rm -f $tmp.*
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/filestreams
|
|
|
|
# remove previous $seqres.full before test
|
|
rm -f $seqres.full
|
|
|
|
# real QA test starts here
|
|
drop_caches()
|
|
{
|
|
while [ true ]; do
|
|
echo 2 > /proc/sys/vm/drop_caches
|
|
sleep 1
|
|
done
|
|
}
|
|
|
|
# Modify as appropriate.
|
|
_supported_fs generic
|
|
_supported_os Linux
|
|
_require_scratch_size $((2*1024*1024)) # kb
|
|
|
|
# check for filestreams
|
|
_check_filestreams_support || _notrun "filestreams not available"
|
|
|
|
# use small AGs for frequent stream switching
|
|
_scratch_mkfs_xfs -d agsize=20m,size=2g >> $seqres.full 2>&1 ||
|
|
_fail "mkfs failed"
|
|
_scratch_mount "-o filestreams"
|
|
|
|
# start background inode reclaim
|
|
drop_caches &
|
|
pid=$!
|
|
|
|
# Stress the filestreams allocator via continuous allocation to a file under
|
|
# different parent dirs. Remove the old dirs as the file is moved so the MRU
|
|
# references point to an unlinked inode by the time they are removed. If the
|
|
# old dir inodes are reclaimed and associated memory reused, MRU cleanup can
|
|
# access the inode after it's been freed.
|
|
dir=$SCRATCH_MNT
|
|
for i in $(seq 0 90); do
|
|
mkdir -p $dir/$i
|
|
$XFS_IO_PROG -fc "falloc $(($i * 20))m 20m" $dir/$i/file
|
|
|
|
mkdir -p $dir/$((i + 1))
|
|
mv $dir/$i/file $dir/$((i + 1))/file
|
|
rmdir $dir/$i
|
|
|
|
# throttle to ensure this loop sees several cache reclaims
|
|
sleep 0.1
|
|
done
|
|
|
|
kill $pid 2> /dev/null
|
|
wait $pid 2> /dev/null
|
|
|
|
echo Silence is golden
|
|
|
|
# success, all done
|
|
status=0
|
|
exit
|