Skip to content

Commit a5a8f2f

Browse files
mkozlowskimeecash
authored andcommitted
Add test cases for memory dump corruption and signal handling
1 parent f46af40 commit a5a8f2f

File tree

5 files changed

+392
-122
lines changed

5 files changed

+392
-122
lines changed

memcr.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,7 +2261,7 @@ static int execute_parasite_checkpoint(pid_t pid)
22612261
/* mmap space for parasite */
22622262
ret = execute_blob(&ctx, mmap_blob, mmap_blob_size, sizeof(parasite_blob), 0);
22632263
if (ret >= -4096LU) {
2264-
fprintf(stdout, "[-] mmap failed: %lx\n", ret);
2264+
fprintf(stdout, "[-] mmap blob failed: %lx\n", ret);
22652265
signals_unblock(pid);
22662266
ctx_restore(pid);
22672267
return -1;
@@ -2309,10 +2309,16 @@ static int execute_parasite_restore(pid_t pid)
23092309

23102310
/* parasite is done, munmap parasite_blob area */
23112311
ret = execute_blob(&ctx, munmap_blob, munmap_blob_size, (unsigned long)ctx.blob, sizeof(parasite_blob));
2312-
if (ret)
2313-
fprintf(stderr, "[-] munmap failed: %ld\n", ret);
2312+
if (ret) {
2313+
fprintf(stderr, "[-] munmap blob failed: %ld\n", ret);
2314+
return ret;
2315+
}
23142316

2315-
signals_unblock(pid);
2317+
ret = signals_unblock(pid);
2318+
if (ret) {
2319+
fprintf(stderr, "[-] signals_unblock() failed: %ld\n", ret);
2320+
return ret;
2321+
}
23162322

23172323
ctx_restore(pid);
23182324

tests/run.sh

Lines changed: 8 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#set -x
44

5+
set -eu
6+
57
# $1 should point to memcr executable
68
[ -n "$1" ] || exit 1
79
[ -x "$1" ] || exit 2
@@ -19,130 +21,18 @@ fi
1921
WHITE='\033[37m'
2022
RED='\033[0;31m'
2123
GREEN='\033[0;32m'
24+
YELLOW='\033[0;33m'
2225
BOLD='\033[1m'
2326
NOFMT='\033[0m'
2427

25-
TEST_CNT=0
26-
TEST_PIPE=./test-pipe
27-
28-
# remove stale test pipe (if any)
29-
rm $TEST_PIPE
30-
31-
do_memcr_test()
32-
{
33-
MEMCR_CMD=$1
34-
TEST=$2
35-
36-
TEST_CNT=$((TEST_CNT + 1))
37-
echo "${WHITE}[test $TEST_CNT] $MEMCR_CMD for $TEST${NOFMT}"
38-
39-
mkfifo $TEST_PIPE
40-
41-
# start the test
42-
./$TEST $TEST_PIPE &
43-
TPID=$!
44-
45-
# wait for test to be ready
46-
cat $TEST_PIPE
47-
rm $TEST_PIPE
48-
49-
# memcr
50-
$MEMCR_CMD -p $TPID
51-
if [ $? -ne 0 ]; then
52-
kill $TPID
53-
echo "${RED}[test $TEST_CNT] failed${NOFMT}"
54-
return 1
55-
fi
56-
57-
# stop the test
58-
kill -USR1 $TPID
59-
wait $TPID
60-
if [ $? -ne 0 ]; then
61-
echo "${RED}[test $TEST_CNT] failed${NOFMT}"
62-
return 1
63-
fi
64-
65-
echo "${GREEN}[test $TEST_CNT] passed${NOFMT}"
66-
return 0
67-
}
68-
69-
TESTS="test-malloc"
70-
28+
TESTS_DONE=0
7129
TIME_START=$(date +%s%N)
7230

73-
# basic tests
74-
for OPT in "" "--proc-mem" "--rss-file" "--proc-mem --rss-file"; do
75-
MEMCR_CMD="${DO}$MEMCR -n $OPT"
76-
77-
for TEST in $TESTS; do
78-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
79-
done
80-
done
81-
82-
# compression tests: lz4
83-
if [ "$COMPRESS_LZ4" = 1 ]; then
84-
MEMCR_CMD="${DO}$MEMCR -n -f --compress lz4"
85-
86-
for TEST in $TESTS; do
87-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
88-
done
89-
fi
90-
91-
# compression tests: zstd
92-
if [ "$COMPRESS_ZSTD" = 1 ]; then
93-
MEMCR_CMD="${DO}$MEMCR -n -f -z zstd"
94-
95-
for TEST in $TESTS; do
96-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
97-
done
98-
fi
99-
100-
# checksumming tests
101-
if [ "$CHECKSUM_MD5" = 1 ]; then
102-
MEMCR_CMD="${DO}$MEMCR -n -f --checksum"
103-
104-
for TEST in $TESTS; do
105-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
106-
done
107-
fi
108-
109-
# encryption tests
110-
if [ "$ENCRYPT" = "1" ]; then
111-
if [ ! -f ../libencrypt.so ]; then
112-
echo "${RED}libencrypt.so not found${NOFMT}"
113-
exit 1
114-
fi
115-
116-
for OPT in "--rss-file" "--proc-mem --rss-file"; do
117-
for ENC in "" "aes-128-cbc" "aes-192-cbc" "aes-256-cbc"; do
118-
MEMCR_CMD="${DO}env LD_PRELOAD=../libencrypt.so $MEMCR -n $OPT --encrypt $ENC"
119-
120-
for TEST in $TESTS; do
121-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
122-
done
123-
done
124-
done
125-
fi
126-
127-
# combined tests: lz4 + md5 + enc
128-
if [ "$COMPRESS_LZ4" = 1 ] && [ "$CHECKSUM_MD5" = 1 ] && [ "$ENCRYPT" = "1" ]; then
129-
MEMCR_CMD="${DO}env LD_PRELOAD=../libencrypt.so $MEMCR -n -f -z -c -e"
130-
131-
for TEST in $TESTS; do
132-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
133-
done
134-
fi
135-
136-
# combined tests: zstd + md5 + enc
137-
if [ "$COMPRESS_ZSTD" = 1 ] && [ "$CHECKSUM_MD5" = 1 ] && [ "$ENCRYPT" = "1" ]; then
138-
MEMCR_CMD="${DO}env LD_PRELOAD=../libencrypt.so $MEMCR -n -f -z ZSTD -c -e"
139-
140-
for TEST in $TESTS; do
141-
do_memcr_test "$MEMCR_CMD" "$TEST" || exit 1
142-
done
143-
fi
31+
. ./run_ok_test.sh
32+
. ./run_corrupt_test.sh
33+
. ./run_signal_test.sh
14434

14535
TIME_END=$(date +%s%N)
14636
TIME_ELAPSED_MS=$(((TIME_END - TIME_START) / 1000000))
14737

148-
echo "${BOLD}[+] all $TEST_CNT tests passed, took $TIME_ELAPSED_MS ms${NOFMT}"
38+
echo "${WHITE}[+] all $TESTS_DONE tests passed, took $TIME_ELAPSED_MS ms${NOFMT}"

tests/run_corrupt_test.sh

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/bin/sh
2+
3+
if [ "$0" = "$_" ]; then
4+
echo "this script should not be called directly"
5+
exit 1;
6+
fi
7+
8+
NAME=./run_corrupt_test.sh
9+
10+
TEST_CNT=0
11+
TEST_PIPE=./test-pipe
12+
MEMCR_PIPE_0=./memcr-pipe-0
13+
MEMCR_PIPE_1=./memcr-pipe-1
14+
15+
do_memcr_corrupt_test()
16+
{
17+
if [ -z "$1" ]; then
18+
MEMCR_ENV=""
19+
else
20+
MEMCR_ENV="$1 "
21+
fi
22+
23+
MEMCR_CMD="$DO$MEMCR_ENV$MEMCR -d /tmp $2"
24+
TEST=$3
25+
26+
TEST_CNT=$((TEST_CNT + 1))
27+
echo "${WHITE}[test $TEST_CNT] $MEMCR_CMD -p .. for $TEST${NOFMT}"
28+
29+
mkfifo $TEST_PIPE
30+
31+
# start the test
32+
./"$TEST" $TEST_PIPE &
33+
TPID=$!
34+
35+
# wait for test to be ready
36+
cat $TEST_PIPE
37+
rm $TEST_PIPE
38+
39+
mkfifo $MEMCR_PIPE_0
40+
exec 3<>$MEMCR_PIPE_0
41+
mkfifo $MEMCR_PIPE_1
42+
43+
# memcr checkpoint and wait
44+
$MEMCR_CMD -p $TPID < $MEMCR_PIPE_0 > $MEMCR_PIPE_1 2>&1 &
45+
MPID=$!
46+
47+
# wait until checkpoint is complete
48+
while IFS=$'\n' read -r LINE; do
49+
echo "$LINE"
50+
51+
case "$LINE" in
52+
*"press enter to restore"*)
53+
break
54+
;;
55+
esac
56+
done < $MEMCR_PIPE_1
57+
58+
# corrupt TPID memory dump
59+
echo "${YELLOW}[test $TEST_CNT] corrupt /tmp/pages-$TPID.img and restore${NOFMT}"
60+
$DO dd if=/dev/urandom of=/tmp/pages-$TPID.img bs=1 count=1 seek=64 conv=notrunc status=none
61+
62+
# memcr restore
63+
echo "" > $MEMCR_PIPE_0
64+
65+
# show remaining output
66+
cat $MEMCR_PIPE_1
67+
68+
rm $MEMCR_PIPE_1
69+
exec 3>&-
70+
rm $MEMCR_PIPE_0
71+
72+
# memcr is expected to exit with error
73+
74+
wait $MPID
75+
RET=$?
76+
if [ $RET -eq 0 ]; then
77+
echo "${RED}[test $TEST_CNT] failed, memcr exit code is $RET${NOFMT}"
78+
return 1
79+
else
80+
echo "[test $TEST_CNT] MPID exit code is $RET"
81+
fi
82+
83+
# TPID should be killed at this point as a result of restore error
84+
85+
wait $TPID
86+
RET=$?
87+
if [ $RET -eq 0 ]; then
88+
echo "${RED}[test $TEST_CNT] failed, ${TEST} exit code is $RET${NOFMT}"
89+
return 1
90+
else
91+
echo "[test $TEST_CNT] TPID exit code is $RET"
92+
fi
93+
94+
echo "${GREEN}[test $TEST_CNT] passed${NOFMT}"
95+
return 0
96+
}
97+
98+
# remove stale test pipe (if any)
99+
rm -f $TEST_PIPE
100+
rm -f $MEMCR_PIPE_0
101+
rm -f $MEMCR_PIPE_1
102+
103+
echo "${BOLD}[+] $NAME start${NOFMT}"
104+
105+
# error test: checksum
106+
if [ "$CHECKSUM_MD5" = 1 ]; then
107+
do_memcr_corrupt_test "" "-f -m -c" "test-malloc" || exit 1
108+
fi
109+
110+
# error test: checksum + lz4
111+
if [ "$CHECKSUM_MD5" = 1 ] && [ "$COMPRESS_LZ4" = 1 ]; then
112+
do_memcr_corrupt_test "" "-f -m -c -z lz4" "test-malloc" || exit 1
113+
fi
114+
115+
# error test: checksum + zstd
116+
if [ "$CHECKSUM_MD5" = 1 ] && [ "$COMPRESS_ZSTD" = 1 ]; then
117+
do_memcr_corrupt_test "" "-f -m -c -z zstd" "test-malloc" || exit 1
118+
fi
119+
120+
# error test: checksum + zstd + enc
121+
if [ "$CHECKSUM_MD5" = 1 ] && [ "$COMPRESS_ZSTD" = 1 ] && [ "$ENCRYPT" = 1 ]; then
122+
if [ ! -f ../libencrypt.so ]; then
123+
echo "${RED}libencrypt.so not found${NOFMT}"
124+
exit 1
125+
fi
126+
127+
do_memcr_corrupt_test "env LD_PRELOAD=../libencrypt.so" "-f -m -c -z zstd -e" "test-malloc" || exit 1
128+
fi
129+
130+
if [ $TEST_CNT -ne 0 ]; then
131+
echo "${BOLD}[+] $NAME $TEST_CNT tests passed${NOFMT}"
132+
else
133+
echo "${BOLD}[+] $NAME 0 tests executed (check config opts)${NOFMT}"
134+
fi
135+
136+
TESTS_DONE=$((TESTS_DONE + TEST_CNT))

0 commit comments

Comments
 (0)