mirror of
https://github.com/radareorg/r2fuse.git
synced 2026-11-07 06:26:00 -10:00
Reject unexpected filesystem errors in the test suite
This commit is contained in:
1 parent
da793a230c
commit
2e8868fc63
7 files changed
+79
-16
No files matched your search
@@ -62,8 +62,9 @@ Status legend: **[api]** core r_fs API, **[plugin]** a specific plugin,
|
||||
"symlinked" variants (`R`, `D`, ...). In practice:
|
||||
- grub plugins use `'f'` for regular files, which is not a defined constant.
|
||||
- ubifs uses `'l'` for symlinks, also undefined.
|
||||
- reiserfs and xfs report symlinks as `'f'`, and opening them fails
|
||||
(`reiserfs-link-root.img`, `xfs-symlink-size.img`).
|
||||
- reiserfs and xfs now preserve symlinks as `'l'` through the grub wrapper
|
||||
(`reiserfs-link-root.img`, `xfs-symlink-size.img`); reading their targets
|
||||
still needs the readlink API below.
|
||||
- no plugin uses the upper-case variants.
|
||||
- **Proposal:**
|
||||
- define `R_FS_FILE_TYPE_SYMLINK 'l'`, `R_FS_FILE_TYPE_FIFO 'p'` and `R_FS_FILE_TYPE_SOCKET 'S'`;
|
||||
@@ -157,14 +158,14 @@ Status legend: **[api]** core r_fs API, **[plugin]** a specific plugin,
|
||||
|
||||
| Plugin | Image | Symptom | Notes |
|
||||
|---|---|---|---|
|
||||
| bfs | `haiku.bfs` | `/radare2_test/gvpr`: reads stop at 2048 of 5736 bytes, and later reads return 0 | `fs_bfs_read` only looks at the block run that contains `addr` ("read from direct blocks only"). Indirect and double-indirect runs are needed |
|
||||
| ext2 (grub) | `ext4_advanced.img` | mount fails | incompat flags 0x22c2: extents, 64bit, flex_bg and **metadata_csum_seed** (0x2000). grub rejects unknown incompat bits. Allow it read-only |
|
||||
| ntfs | `ntfs.img` | `$Extend/$ObjId`, `$Quota` and `$Reparse` are listed but cannot be opened | these metafiles have no unnamed `$DATA` stream. Report them as special, or expose their named streams |
|
||||
| ntfs | `ntfs-resident-oob.img` | `/file` cannot be opened | crafted image. Make sure the failure is a clean error |
|
||||
| reiserfs | `reiserfs-link-root.img`, `reiserfs-corrupt.img` | `link` is reported as `'f'` and cannot be opened | symlink type missing (see 1.5, 1.6) |
|
||||
| xfs | `xfs-symlink-size.img` | `link` is reported as `'f'` | same as above |
|
||||
| bfs | `haiku.bfs` | fixed: multi-block and cross-run reads return the full file | direct runs use the same reader as directories; indirect and double-indirect runs remain unsupported |
|
||||
| ext2 (grub) | `ext4_advanced.img` | fixed: the image mounts and passes read stress | 64-bit group descriptor stride and inode table addresses are supported; metadata checksum seeds are allowed for read-only access |
|
||||
| ntfs | `ntfs.img` | fixed: index-view metadata is reported as special entries | named stream access remains a separate feature |
|
||||
| ntfs | `ntfs-resident-oob.img` | `/file` is correctly refused | passing negative test checks the exact open failure; a crash or unrelated error fails |
|
||||
| reiserfs | `reiserfs-link-root.img`, `reiserfs-corrupt.img` | fixed: `link` is reported as `'l'` | readlink support is still missing (see 1.6) |
|
||||
| xfs | `xfs-symlink-size.img` | fixed: `link` is reported as `'l'` | readlink support is still missing |
|
||||
| ubifs | `ubifs.img` | 174 symlinks reported as `'l'` | readlink support (1.6) |
|
||||
| ubifs | `ubifs-oversize.img` | `File size (11) exceeds filesystem size (0)`, then 0 bytes are read | `leb_cnt` is 0 here. The size clamp should not use the volume size when that size is unknown |
|
||||
| ubifs | `ubifs-oversize.img` | fixed: the 11-byte file reads correctly | the volume-size clamp applies only when the volume size is known |
|
||||
| iso9660 | `iso.img` | level-1 names without an extension keep the dot: `LS.`, `SERVICES.` | strip the trailing `.` together with the `;1` version |
|
||||
| hfs | `hfs-oobread.img` | refuses to mount | crafted image, the expected result |
|
||||
| bfs | `bfs-sibling-cycle.img` | refuses to mount | crafted image, the expected result |
|
||||
|
||||
@@ -61,6 +61,7 @@ static:
|
||||
./dist/static.sh
|
||||
|
||||
check test: $(BIN)
|
||||
sh ./test/harness.sh
|
||||
./test/run.sh $(TESTBINS)
|
||||
|
||||
install: $(BIN)
|
||||
|
||||
@@ -170,8 +170,11 @@ f 19605 c960f1896b3e8434 /etc/services
|
||||
from the [radare2-testbins](https://github.com/radareorg/radare2-testbins)
|
||||
`fs/` directory (default `../radare2/test/bins/fs`, override with
|
||||
`make check TESTBINS=...`). Each image has an expected result. Plugin bugs show
|
||||
up as `XFAIL`, and when one gets fixed it shows up as `XPASS` so the table can be
|
||||
updated. Set `R2FUSE_MOUNT=1` to also mount every image and compare file sizes
|
||||
up as `XFAIL`, and when one gets fixed it shows up as `XPASS` and fails the run
|
||||
until its expectation is updated. Malformed images pass only when they are
|
||||
rejected with the expected error; crashes and timeouts always fail.
|
||||
The check/stress commands return 0 on success, 1 on a failed check, and 2 if
|
||||
the image cannot be opened or mounted. Set `R2FUSE_MOUNT=1` to also mount every image and compare file sizes
|
||||
as seen through the kernel.
|
||||
|
||||
## How it works
|
||||
|
||||
@@ -57,6 +57,8 @@ executable('r2fuse',
|
||||
link_args: link_args,
|
||||
install: true)
|
||||
|
||||
test('harness', find_program('sh'), args: [meson.current_source_dir() / 'test/harness.sh'])
|
||||
|
||||
test('check', find_program('test/run.sh'),
|
||||
args: [get_option('testbins')],
|
||||
depends: [],
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
# Exercise the runner's exit-status handling without real filesystem plugins.
|
||||
set -eu
|
||||
|
||||
HERE=$(cd "$(dirname "$0")" && pwd)
|
||||
TMP=$(mktemp -d "${TMPDIR:-/tmp}/r2fuse-harness.XXXXXX")
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
mkdir "$TMP/images"
|
||||
cat > "$TMP/mock" <<'EOF'
|
||||
#!/bin/sh
|
||||
case "$R2FUSE_TEST_STATUS" in
|
||||
timeout) exec sleep 2 ;;
|
||||
esac
|
||||
printf '%s\n' "$R2FUSE_TEST_OUTPUT"
|
||||
exit "$R2FUSE_TEST_STATUS"
|
||||
EOF
|
||||
chmod +x "$TMP/mock"
|
||||
|
||||
check() {
|
||||
image=$1 status=$2 output=$3 expected=$4
|
||||
: > "$TMP/images/$image"
|
||||
result=0
|
||||
R2FUSE="$TMP/mock" R2FUSE_MOUNT= TIMEOUT=1 \
|
||||
R2FUSE_TEST_STATUS="$status" R2FUSE_TEST_OUTPUT="$output" \
|
||||
sh "$HERE/run.sh" "$TMP/images" > "$TMP/output" 2>&1 || result=$?
|
||||
rm -f "$TMP/images/$image"
|
||||
if [ "$result" -ne "$expected" ]; then
|
||||
echo "Runner regression: $image, status $status: exit $result, expected $expected"
|
||||
cat "$TMP/output"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check ext2.img 0 'valid image' 0
|
||||
check ext2.img 1 'unexpected read failure' 1
|
||||
check ext2.img 2 'unexpected mount rejection' 1
|
||||
check ext2.img 139 'crash' 1
|
||||
check ext2.img timeout '' 1
|
||||
check bfs-sibling-cycle.img 2 'malformed image rejected' 0
|
||||
check bfs-sibling-cycle.img 0 'unexpected acceptance' 1
|
||||
check bfs-sibling-cycle.img 1 'wrong kind of failure' 1
|
||||
check bfs-sibling-cycle.img 139 'crash' 1
|
||||
check ntfs-resident-oob.img 1 'FAIL /file: open failed' 0
|
||||
check ntfs-resident-oob.img 1 'FAIL /other: open failed' 1
|
||||
check ntfs-resident-oob.img 1 'FAIL /file: read failed' 1
|
||||
check ntfs-resident-oob.img 139 'crash' 1
|
||||
check ntfs-resident-oob.img 0 'unexpected acceptance' 1
|
||||
echo 'OK runner rejects unexpected errors, crashes, timeouts and unexpected passes'
|
||||
+2
-2
@@ -12,8 +12,8 @@ iso3.img - ok
|
||||
iso-joliet-rockridge.iso - ok
|
||||
udf.img udf ok autodetected as iso9660
|
||||
haiku.bfs - ok
|
||||
ntfs.img - fail $Extend metafiles cannot be opened
|
||||
ntfs-resident-oob.img - fail crafted image
|
||||
ntfs.img - ok index-view metadata is reported as special files
|
||||
ntfs-resident-oob.img - reject-file:/file resident value outside the MFT record
|
||||
reiserfs-link-root.img - ok symlinks are reported as special files
|
||||
reiserfs-corrupt.img - ok crafted image
|
||||
reiserfs-name-oob.img - ok crafted image
|
||||
|
||||
+11
-3
@@ -70,12 +70,20 @@ while read -r img fstype expect notes; do
|
||||
2) res=reject ;;
|
||||
*) res=crash ;;
|
||||
esac
|
||||
case "$expect" in
|
||||
reject-file:*)
|
||||
if [ "$rc" -eq 1 ] && [ "$(grep -c '^FAIL ' "$TMP/out")" -eq 1 ] \
|
||||
&& grep -Fxq "FAIL ${expect#reject-file:}: open failed" "$TMP/out"; then
|
||||
res=$expect
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
summary=$(tail -n 1 "$TMP/out")
|
||||
if [ "$res" = "$expect" ]; then
|
||||
if [ "$res" != crash ] && [ "$res" = "$expect" ]; then
|
||||
if [ "$res" = ok ]; then
|
||||
echo "OK $img: $summary"; pass=$((pass + 1))
|
||||
elif [ "$res" = reject ]; then
|
||||
echo "OK $img: rejected malformed image"; pass=$((pass + 1))
|
||||
elif [ "$res" != fail ]; then
|
||||
echo "OK $img: rejected malformed image or file"; pass=$((pass + 1))
|
||||
else
|
||||
echo "XFAIL $img: $notes"; xfail=$((xfail + 1))
|
||||
fi
|
||||
|
||||
Reference in new issue
Block a user