Skip to content

Commit

Permalink
Updated Makefiles and added docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hazimeh committed Nov 1, 2019
1 parent 6a0974a commit 1a46965
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 11 deletions.
14 changes: 9 additions & 5 deletions Makefile
Expand Up @@ -12,30 +12,34 @@ TARGETS := $(shell find $(CBDIR) -maxdepth 1 -type d -printf %P\\n)
BUG_COUNT := $(shell echo $(lastword $(sort $(patsubst bugs/%.patch,%,$(BUG_PATCHES)))) | sed 's/^0*//')
export BUG_COUNT

.PHONY: all clean patch copy $(PATCHES) $(TARGETS)
.PHONY: all all_targets all_patches clean copy setup $(PATCHES) $(TARGETS)

.NOTPARALLEL:

all: $(PATCHES) $(TARGETS)
all: all_patches all_targets
@rm -r $(TMPDIR)

all_targets: $(TARGETS)

all_patches: $(PATCHES)

clean:
rm -rf tmp build/*

patch: $(PATCHES)

copy:
@echo "Copying codebase to tmp directory"
@if [ -d "$(TMPDIR)" ]; then \
rm -r "$(TMPDIR)"; \
fi;
@cp -r "$(CBDIR)" "$(TMPDIR)"

setup: copy $(SETUP_PATCHES)

$(PATCHES): copy
@echo "Applying patch $(basename $@)"
@sed -- 's/$(notdir $(CBDIR))/$(notdir $(TMPDIR))/g' $(PATCHDIR)/$@ | git apply

$(TARGETS): copy patch
$(TARGETS): setup
@mkdir -p $(BINDIR)
@echo "Building $@"
@cd $(TMPDIR); $(MAKE) $@;
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -43,6 +43,8 @@ applications. To that end, the near-future list of TODOs is the following:
1. Add more bugs and libraries.
1. Allow poppler to use the buggy versions of libpng and libtiff.
1. Add processor affinity support to the `benchd` toolset.
1. Replace the use of `git apply` with the GNU `patch` utility so that Magma can
be distributed without a git dependency.

The long-term milestones of this project are:

Expand Down Expand Up @@ -140,6 +142,8 @@ behavior. The following environment variables control these configurations:
* `MAGMA_STORAGE`: the name of the shared memory object where canary statistics
will be stored. It is recommended to use a unique name for every launched
campaign, to avoid data races on the same shmem object.
* `MAGMA_SUFFIX`: a string suffix to add to the programs' names in the build dir
to use as an identifier if needed.
* `MAGMA_ISAN`: if defined, the Ideal Sanitization mode will be used for the
canaries. Whenever a bug is triggered, the canary will send a SIGSEGV signal
to the target, causing it to crash.
Expand Down
78 changes: 78 additions & 0 deletions docs/BUILD.md
@@ -0,0 +1,78 @@
# Building Magma

Magma's build system relies on the individual build systems of each of the
included repositories by launching their automake, make, or cmake scripts. As
such, and to reduce the complexity of Magma's build scripts, its build system
does not support incremental building, but rather performs a complete re-build
of the libraries whenever Magma's Makefile is invoked.

Additionally, Magma applies setup and bug patches to the codebase, to add Magma
support to the libraries' build systems, and to forward-port bugs. For that
reason, the `codebase` is copied into a `tmp` directory first, then patches are
applied, and finally, the codebase and supporting files are built in `tmp`, and
the Magma-relevant binaries are copied to `build`.

Build configurations are specified as environment variables and propagated to
the included libraries' build systems. The relevant build configuration
parameters are `CC`, `CXX`, `CFLAGS`, `CXXFLAGS`, `LDFLAGS`, and `LIBS`.

Additionally, Magma-specific build parameters are also read from the environment
as follows:

* `MAGMA_STORAGE`: the name of the shared memory object where canary statistics
will be stored. It is recommended to use a unique name for every launched
campaign, to avoid data races on the same shmem object.
* `MAGMA_SUFFIX`: a string suffix to add to the programs' names in the build dir
to use as an identifier if needed.
* `MAGMA_ISAN`: if defined, the Ideal Sanitization mode will be used for the
canaries. Whenever a bug is triggered, the canary will send a SIGSEGV signal
to the target, causing it to crash.
* `MAGMA_HARDEN`: if defined, canaries will be hardened. In hardened mode, the
access to shared memory is surrounded by a couple calls to `mprotect`, which
first set the shmem object's page's permissions to `RW`, allowing the canary
to report, and then set the permissions back to `R`. This way, an OOB memory
write during the program execution would not overwrite campaign results.

Magma is built using the Makefile in its root directory. The default build
recipe, `make all`, applies all patches and builds all targets.

To build some targets with specific patches:
```bash
make <xxx.patch <xxy.patch <xxz.patch ...>>> <target <target <target ...>>>
```

The available patches are all the files under the `patches` directory, in
addition to `all_patches`, which applies all the included patches. The available
targets are the names of the directories in the `codebase`, in addition to
`all_targets`, which builds everything.

Thus, the following bash script template covers all the configurable Magma build
system parameters:

```bash
#!/bin/bash
export CC="<path/to/cc>"
export CXX="<path/to/cxx>"
export CFLAGS="<additional C compiler flags>"
export CXXFLAGS="<additional CXX compiler flags>"
export LDFLAGS="<additional LD flags>"
export LIBS="<additional libs to link, e.g.: -lm or -l:path/to/lib>"
export MAGMA_STORAGE="<name of shmem object, e.g., MAGMA_TMP>"
export MAGMA_SUFFIX="<suffix to append, if any>"

# The value of the following env variables is not relevant, as long as they're
# exported.
export MAGMA_ISAN=1
export MAGMA_HARDEN=1

make <xxx.patch <xxy.patch <xxz.patch ...>>> <target <target <target ...>>>
```

To add a new library to the build system, it suffices to modify the `Makefile`
in `codebase` to add a new build recipe named as the library's directory name in
`codebase`. The recipe must configure and invoke the build system of the target
library, and copy the relevant binaries to `$(BINDIR)/programs/`, with the
`MAGMA_SUFFIX` appended to the programs' names.

The binaries eventually copied to `build` contain the required Magma
instrumentation and can be fed into the fuzzers under test.
35 changes: 35 additions & 0 deletions docs/USAGE.md
@@ -0,0 +1,35 @@
# Using Magma

After building the Magma binaries, and in order to collect information about
fuzzer progress, a monitoring utility must be first launched before executing
the instrumented binaries.

In its current implementation, Magma uses POSIX shared memory objects to store
persistent information. To read it, a monitoring utility must open the shmem
object, whose name was specified during build in `MAGMA_STORAGE`. The size of
the shmem object and the format of data in it is specified in the `magma`
library in the `codebase`, specifically, in `canary.h` and `canary.c`.

Magma ships with two utilities that function as monitoring utilities. For every
build, Magma's build system generates a `monitor` binary in `build` which sets
up the shmem object and prints its contents. To delete the shmem object, launch
monitor as `./monitor --rm`. The `monitor` utility is convenient for quickly
checking if the canaries are working as expected or if some manual program input
reaches/triggers some bug.

The other monitor is included in the `benchd` toolset which is designed for
launching long-running campaigns and collecting and processing fuzzer progress
information.

The `benchd` toolset manages fuzzing campaigns, runs multiple campaigns
concurrently for a specified time duration, and collects and saves canary
information. The provided scripts, `logparse.py` and `postproc.py` also help in
parsing and processing monitor logs and fuzzer findings. Look at the `--help`
output of these scripts to determine usage.

Don't forget to set up the environment for the fuzzers under test. AFL, for instance, requires the following:

```bash
echo core | sudo tee /proc/sys/kernel/core_pattern
sudo bash -c 'cd /sys/devices/system/cpu; echo performance | tee cpu*/cpufreq/scaling_governor'
```
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/afl.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]
env["CC"] = self.cc
Expand Down
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/aflfast.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]
env["CC"] = self.cc
Expand Down
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/angora.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]

Expand Down
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/fairfuzz.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]
env["CC"] = self.cc
Expand Down
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/honggfuzz.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]
env["CC"] = self.cc
Expand Down
2 changes: 1 addition & 1 deletion tools/benchd/fuzzers/moptafl.py
Expand Up @@ -29,7 +29,7 @@ def compile(self, target_name, output_dir, config=None, **env):
self.magma_dir,
# "-f %s" % os.path.join(self.magma_dir, "Makefile")
"clean",
"patch",
"all_patches",
target_name
]
env["CC"] = self.cc
Expand Down

0 comments on commit 1a46965

Please sign in to comment.