Skip to content

Commit 1fb4346

Browse files
authored
Add a prototype of security benchmark
Inspired by https://github.com/GrapheneOS/hardened_malloc/tree/main/test
1 parent 9eed684 commit 1fb4346

27 files changed

+361
-20
lines changed

bench.sh

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
#!/bin/bash
22
# Copyright 2018-2022, Microsoft Research, Daan Leijen, Julien Voisin, Matthew Parkinson
33

4-
if grep -q -e 'ID=debian' -e 'ID=ubuntu' /etc/os-release 2>/dev/null; then
5-
echo "Running on Debian or Ubuntu: errors are considered fatal"
6-
set -eo pipefail
7-
elif brew --version 2> /dev/null >/dev/null; then
8-
echo "Running on OSX: errors are considered fatal"
9-
set -eo pipefail
10-
fi
11-
124

135
# --------------------------------------------------------------------
146
# Allocators and tests
@@ -23,7 +15,7 @@ alloc_libs="sys=" # mapping from allocator to its .so as "<allocator>=<sofi
2315
readonly tests_all1="cfrac espresso barnes redis lean larson-sized mstress rptest gs"
2416
readonly tests_all2="alloc-test sh6bench sh8bench xmalloc-test cscratch glibc-simple glibc-thread rocksdb"
2517
readonly tests_all3="larson lean-mathlib malloc-large mleak rbstress cthrash"
26-
readonly tests_all4="z3 spec spec-bench"
18+
readonly tests_all4="z3 spec spec-bench security"
2719

2820
readonly tests_all="$tests_all1 $tests_all2 $tests_all3 $tests_all4"
2921
readonly tests_allt="$tests_all1 $tests_all2" # run with 'allt' command option
@@ -529,6 +521,18 @@ function run_test_env_cmd { # <test name> <allocator name> <environment args> <c
529521
$redis_dir/redis-cli shutdown
530522
sleep 1s
531523
;;
524+
security)
525+
echo $2 >> $outfile
526+
for file in security/*.c
527+
do
528+
binary=${file%.*}
529+
if /usr/bin/env $3 ./$binary 2>/dev/null | grep --text -q 'NOT_CAUGHT'; then
530+
echo "[-] $binary" >> "$outfile"
531+
else
532+
echo "[+] $binary" >> "$outfile"
533+
fi
534+
done
535+
;;
532536
*)
533537
$timecmd -a -o "$benchres.line" -f "$1${benchfill:${#1}} $2${allocfill:${#2}} %E %M %U %S %F %R" /usr/bin/env $3 $4 < "$infile" > "$outfile";;
534538
esac
@@ -561,11 +565,10 @@ function run_test_env_cmd { # <test name> <allocator name> <environment args> <c
561565
spec-*)
562566
popd;;
563567
esac
564-
cat "$benchres.line" | tee -a $benchres
568+
test -f "$benchres.line" && cat "$benchres.line" | tee -a $benchres
565569
}
566570

567571
function run_test_cmd { # <test name> <command>
568-
echo " " >> $benchres
569572
echo ""
570573
echo "---- $repeat: $1"
571574
for alloc in $alloc_run; do # use order as given on the command line
@@ -685,6 +688,8 @@ function run_test { # <test>
685688
648) run_test_cmd "spec-648.exchange2_s" "./exchange2_s_base.malloc-test-m64 6";;
686689
*) echo "error: unknown spec benchmark";;
687690
esac;;
691+
security)
692+
run_test_cmd "security";;
688693
*)
689694
warning "skipping unknown test: $1";;
690695
esac
@@ -694,6 +699,7 @@ function run_test { # <test>
694699
if [ -f "$benchres" ]; then
695700
rm "$benchres"
696701
fi
702+
rm -f ./security-*-out.txt
697703

698704
for ((repeat=1; repeat<=$repeats; repeat++)); do
699705
for tst in $tests_run; do
@@ -705,13 +711,19 @@ done
705711
# --------------------------------------------------------------------
706712
# Wrap up
707713
# --------------------------------------------------------------------
714+
if test -f "$benchres"; then
715+
sed -i.bak "s/ 0:/ /" $benchres
716+
echo ""
717+
echo "results written to: $benchres"
718+
echo ""
719+
echo "#------------------------------------------------------------------"
720+
echo "# test alloc time rss user sys page-faults page-reclaims"
708721

709-
sed -i.bak "s/ 0:/ /" $benchres
710-
echo ""
711-
echo "results written to: $benchres"
712-
echo ""
713-
echo "#------------------------------------------------------------------"
714-
echo "# test alloc time rss user sys page-faults page-reclaims"
715-
716-
cat $benchres
717-
echo ""
722+
cat $benchres
723+
echo ""
724+
fi
725+
for file in security-*-out.txt
726+
do
727+
cat "$file"
728+
echo ""
729+
done

bench/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,8 @@ target_link_libraries(glibc-simple pthread)
110110

111111
add_executable(glibc-thread glibc-bench/bench-malloc-thread.c)
112112
target_link_libraries(glibc-thread pthread)
113+
114+
file(GLOB MY_SECURITY_BINARIES
115+
"security/*"
116+
)
117+
file(COPY ${MY_SECURITY_BINARIES} DESTINATION security/)

bench/security/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CFLAGS := -Wno-free-nonheap-object
2+
3+
SRCS = $(wildcard *.c)
4+
PROGS = $(patsubst %.c,%,$(SRCS))
5+
6+
%: %.c
7+
$(CC) $(CFLAGS) -o $@ $<
8+
9+
all: $(PROGS)
10+
11+
clean:
12+
rm -rf $(PROGS)

bench/security/double_free_large.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(256 * 1024);
6+
free(p);
7+
free(p);
8+
9+
puts("NOT_CAUGHT");
10+
return 0;
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(256 * 1024);
6+
free(p);
7+
8+
for(int i=0; i<1024; i++)
9+
free(malloc(256 * 1024));
10+
11+
free(p);
12+
13+
puts("NOT_CAUGHT");
14+
return 0;
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(256 * 1024);
6+
void *q = malloc(256 * 1024);
7+
free(p);
8+
free(q);
9+
free(p);
10+
11+
puts("NOT_CAUGHT");
12+
return 0;
13+
}

bench/security/double_free_small.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(8);
6+
free(p);
7+
free(p);
8+
9+
puts("NOT_CAUGHT");
10+
return 0;
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(8);
6+
free(p);
7+
8+
for(int i=0; i<1024; i++)
9+
free(malloc(8));
10+
11+
free(p);
12+
13+
puts("NOT_CAUGHT");
14+
return 0;
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main() {
5+
void *p = malloc(8);
6+
void *q = malloc(8);
7+
free(p);
8+
free(q);
9+
free(p);
10+
11+
puts("NOT_CAUGHT");
12+
return 0;
13+
}

bench/security/executable_heap.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
const char* shellcode = "\x90\x90\x90\x90\xc3"; // nop, ..., ret on x86
6+
7+
int main(void) {
8+
char *p = malloc(8);
9+
memcpy(p, shellcode, sizeof(shellcode));
10+
void(*fptr)(void) = (void(*)(void))p;
11+
fptr();
12+
13+
puts("NOT_CAUGHT");
14+
return 0;
15+
}

0 commit comments

Comments
 (0)