-
Notifications
You must be signed in to change notification settings - Fork 136
/
Copy pathlimit_memory.sh
executable file
·157 lines (108 loc) · 3.75 KB
/
limit_memory.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
#
# american fuzzy lop - limit memory using cgroups
# -----------------------------------------------
#
# Written by Samir Khakimov <samir.hakim@nyu.edu> and
# David A. Wheeler <dwheeler@ida.org>
#
# Edits to bring the script in line with afl-cmin and other companion scripts
# by Michal Zalewski <lcamtuf@google.com>. All bugs are my fault.
#
# Copyright 2015 Institute for Defense Analyses.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# This tool allows the amount of actual memory allocated to a program
# to be limited on Linux systems using cgroups, instead of the traditional
# setrlimit() API. This helps avoid the address space problems discussed in
# docs/notes_for_asan.txt.
#
# Important: the limit covers *both* afl-fuzz and the fuzzed binary. In some
# hopefully rare circumstances, afl-fuzz could be killed before the fuzzed
# task.
#
echo "cgroup tool for afl-fuzz by <samir.hakim@nyu.edu> and <dwheeler@ida.org>"
echo
unset NEW_USER
MEM_LIMIT="50"
while getopts "+u:m:" opt; do
case "$opt" in
"u")
NEW_USER="$OPTARG"
;;
"m")
MEM_LIMIT="$[OPTARG]"
;;
"?")
exit 1
;;
esac
done
if [ "$MEM_LIMIT" -lt "5" ]; then
echo "[-] Error: malformed or dangerously low value of -m." 1>&2
exit 1
fi
shift $((OPTIND-1))
TARGET_BIN="$1"
if [ "$TARGET_BIN" = "" -o "$NEW_USER" = "" ]; then
cat 1>&2 <<_EOF_
Usage: $0 [ options ] -- /path/to/afl-fuzz [ ...afl options... ]
Required parameters:
-u user - run the fuzzer as a specific user after setting up limits
Optional parameters:
-m megs - set memory limit to a specified value ($MEM_LIMIT MB)
This tool configures cgroups-based memory limits for a fuzzing job to simplify
the task of fuzzing ASAN or MSAN binaries. You would normally want to use it in
conjunction with '-m none' passed to the afl-fuzz binary itself, say:
$0 -u joe ./afl-fuzz -i input -o output -m none /path/to/target
_EOF_
exit 1
fi
# Basic sanity checks
if [ ! "`uname -s`" = "Linux" ]; then
echo "[-] Error: this tool does not support non-Linux systems." 1>&2
exit 1
fi
if [ ! "`id -u`" = "0" ]; then
echo "[-] Error: you need to run this script as root (sorry!)." 1>&2
exit 1
fi
if ! type cgcreate 2>/dev/null 1>&2; then
echo "[-] Error: you need to install cgroup tools first." 1>&2
if type apt-get 2>/dev/null 1>&2; then
echo " (Perhaps 'apt-get install cgroup-bin' will work.)" 1>&2
elif type yum 2>/dev/null 1>&2; then
echo " (Perhaps 'yum install libcgroup-tools' will work.)" 1>&2
fi
exit 1
fi
if ! id -u "$NEW_USER" 2>/dev/null 1>&2; then
echo "[-] Error: user '$NEW_USER' does not seem to exist." 1>&2
exit 1
fi
# Create a new cgroup path if necessary... We used PID-keyed groups to keep
# parallel afl-fuzz tasks separate from each other.
CID="afl-$NEW_USER-$$"
CPATH="/sys/fs/cgroup/memory/$CID"
if [ ! -d "$CPATH" ]; then
cgcreate -a "$NEW_USER" -g memory:"$CID" || exit 1
fi
# Set the appropriate limit...
if [ -f "$CPATH/memory.memsw.limit_in_bytes" ]; then
echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" 2>/dev/null
echo "${MEM_LIMIT}M" > "$CPATH/memory.memsw.limit_in_bytes" || exit 1
echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" || exit 1
elif grep -qE 'partition|file' /proc/swaps; then
echo "[-] Error: your system requires swap to be disabled first (swapoff -a)." 1>&2
exit 1
else
echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" || exit 1
fi
# All right. At this point, we can just run the command.
cgexec -g "memory:$CID" su -c "$*" "$NEW_USER"
cgdelete -g "memory:$CID"