t5313-pack-bounds-checks.sh [plain text]
#!/bin/sh
test_description='bounds-checking of access to mmapped on-disk file formats'
. ./test-lib.sh
clear_base () {
test_when_finished 'restore_base' &&
rm -f $base
}
restore_base () {
cp base-backup/* .git/objects/pack/
}
do_pack () {
pack_objects=$1; shift
sha1=$(
for i in $pack_objects
do
echo $i
done | git pack-objects "$@" .git/objects/pack/pack
) &&
pack=.git/objects/pack/pack-$sha1.pack &&
idx=.git/objects/pack/pack-$sha1.idx &&
chmod +w $pack $idx &&
test_when_finished 'rm -f "$pack" "$idx"'
}
munge () {
printf "$3" | dd of="$1" bs=1 conv=notrunc seek=$2
}
ofs_table () {
echo $((4 + 4 + 4*256 + 20*$1 + 4*$1))
}
extended_table () {
echo $(($(ofs_table "$1") + 4*$1))
}
test_expect_success 'set up base packfile and variables' '
echo 74 >file &&
git add file &&
git commit -m base &&
git repack -ad &&
base=$(echo .git/objects/pack/*) &&
chmod +w $base &&
mkdir base-backup &&
cp $base base-backup/ &&
object=$(git rev-parse HEAD:file)
'
test_expect_success 'pack/index object count mismatch' '
do_pack $object &&
munge $pack 8 "\377\0\0\0" &&
clear_base &&
echo "$object missing" >expect &&
git cat-file --batch-all-objects --batch-check >actual &&
test_cmp expect actual &&
test_must_fail git cat-file blob $object &&
restore_base &&
git cat-file blob $object >actual &&
test_cmp file actual &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'matched bogus object count' '
do_pack $object &&
munge $pack 8 "\377\0\0\0" &&
munge $idx $((255 * 4)) "\377\0\0\0" &&
clear_base &&
git cat-file --batch-all-objects --batch-check >actual &&
test_must_be_empty actual &&
test_must_fail git cat-file blob $object &&
restore_base &&
git cat-file blob $object >actual &&
test_cmp file actual &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus object offset (v1)' '
do_pack $object --index-version=1 &&
munge $idx $((4 * 256)) "\377\0\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus object offset (v2, no msb)' '
do_pack $object --index-version=2 &&
munge $idx $(ofs_table 1) "\0\377\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus offset into v2 extended table' '
do_pack $object --index-version=2 &&
munge $idx $(ofs_table 1) "\377\0\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus offset inside v2 extended table' '
second=$(echo 1485 | git hash-object -w --stdin) &&
do_pack "$object $second" --index-version=2 &&
{
dd if=$idx bs=1 count=$(($(ofs_table 2) + 4)) &&
printf "\200\0\0\0" &&
printf "\377\0\0\0\0\0\0\0" &&
dd if=$idx bs=1 skip=$(extended_table 2)
} >tmp &&
mv tmp "$idx" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus OFS_DELTA in packfile' '
base=$(test-tool genrandom foo 3000 | git hash-object --stdin -w) &&
delta=$(test-tool genrandom foo 2000 | git hash-object --stdin -w) &&
do_pack "$base $delta" --delta-base-offset &&
rm -f .git/objects/??/* &&
echo $base >expect &&
echo $delta | git cat-file --batch-check="%(deltabase)" >actual &&
test_cmp expect actual &&
ofs=$(git show-index <$idx | grep $delta | cut -d" " -f1) &&
munge $pack $(($ofs + 1)) "\177\377" &&
test_must_fail git cat-file blob $delta >/dev/null
'
test_done