-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/master'
- Loading branch information
Showing
44 changed files
with
658 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# fuzz-harness | ||
|
||
The fuzz harness for Vanetza is a testing tool designed to identify bugs, vulnerabilities, and unexpected behaviors within Vanetza's codebase. Fuzz testing, also known as fuzzing, involves providing invalid, unexpected, or random data as input to a program to uncover errors or security issues. | ||
|
||
## Requirements | ||
|
||
You will need AFL++ installed on your system. | ||
Please refer to the [AFL++ documentation](https://aflplus.plus/docs/install/) for installation instructions. | ||
Alternatively, you can use the scripts located at *tools/fuzz-harness* for running fuzz tests in a Docker container. | ||
|
||
## Usage | ||
|
||
Running the script *fuzz-harness/docker.sh* will build a suitable Docker container based on the official *aflplusplus/aflplusplus* image. | ||
As soon as the container is ready, the script launches the built container and maps your local user and some Vanetza directories into it. | ||
|
||
Within the container, you can compile the *fuzz-harness* using the AFL++ toolchain by invoking the *compile.sh* script. | ||
The *fuzz.sh* script is a convenient way to run the built harness with *afl-fuzz*. | ||
If it crashes immediately, try again a few times. | ||
|
||
### Analyse | ||
|
||
Fuzzing is executing the *fuzzing-persistent* executable. | ||
You can use its sibling *fuzzing-run* to investigate a particular crash and get more information about the possible problems. | ||
The address sanitizer is enabled by default. If you're not interested in memory leaks, make sure to disable the leak sanatizer by setting the environment variable `ASAN_OPTIONS=detect_leaks=0`. | ||
|
||
You may also want to classify the found issues using *casr-afl*: `casr-afl -i output -o output/casr` | ||
The classification process also eliminates duplicate issues. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
output/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
add_executable(fuzzing-persistent router_fuzzing_context.cpp persistent.cpp) | ||
target_link_libraries(fuzzing-persistent PUBLIC vanetza) | ||
|
||
add_executable(fuzzing-run router_fuzzing_context.cpp run.cpp) | ||
target_link_libraries(fuzzing-run PUBLIC vanetza) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ARG VERSION=latest | ||
FROM aflplusplus/aflplusplus:${VERSION} | ||
|
||
# install build dependencies for Vanetza | ||
RUN apt-get update && apt-get install --no-install-recommends -y \ | ||
libboost-all-dev libcrypto++-dev libgeographic-dev libssl-dev | ||
|
||
# install casr-afl tool | ||
RUN cargo install --root /usr/local casr | ||
|
||
# set up "fuzz" user and mapping of host user | ||
RUN useradd -m -s /bin/bash fuzz | ||
RUN cp /root/.bashrc /home/fuzz/.bashrc && chown fuzz:fuzz /home/fuzz/.bashrc | ||
COPY docker-entrypoint.sh /docker-entrypoint.sh | ||
ENTRYPOINT ["/docker-entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/bash -eu | ||
|
||
if [[ ! -d "/AFLplusplus" ]] ; then | ||
echo "This script shall be run inside the AFL++ container" | ||
exit 1 | ||
fi | ||
|
||
cd /home/fuzz | ||
|
||
export CC=${CC:=afl-clang-lto} | ||
export CXX=${CXX:=afl-clang-lto++} | ||
|
||
export AFL_LLVM_CMPLOG=1 | ||
mkdir -p build/cmplog | ||
cmake -S source -B build/cmplog -G Ninja -DBUILD_FUZZ=ON | ||
cmake --build build/cmplog | ||
unset AFL_LLVM_CMPLOG | ||
|
||
# see https://aflplus.plus/docs/env_variables/ for supported environment variables | ||
export AFL_USE_ASAN=1 | ||
export AFL_USE_UBSAN=1 | ||
mkdir -p build/asan | ||
cmake -S source -B build/asan -G Ninja -DBUILD_FUZZ=ON | ||
cmake --build build/asan |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/bash -eu | ||
afl-system-config | ||
|
||
usermod -u ${HOST_USER_ID} -g ${HOST_GROUP_ID} fuzz | ||
ln -sf /source /home/fuzz/source | ||
ln -sf /input /home/fuzz/input | ||
ln -sf /output /home/fuzz/output | ||
ln -sf /source/tools/fuzz-harness/compile.sh /home/fuzz/compile.sh | ||
ln -sf /source/tools/fuzz-harness/fuzz.sh /home/fuzz/fuzz.sh | ||
cd /home/fuzz | ||
su fuzz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/bin/bash -eu | ||
HARNESS_DIR=$(realpath $(dirname $0)) | ||
SOURCE_DIR=$HARNESS_DIR/../.. | ||
|
||
docker build $HARNESS_DIR | ||
IMAGE=$(docker build -q $HARNESS_DIR) | ||
|
||
mkdir -p $HARNESS_DIR/output | ||
docker run --rm -it \ | ||
--security-opt seccomp=unconfined \ | ||
-v$SOURCE_DIR:/source:ro \ | ||
-v$HARNESS_DIR/input:/input:ro \ | ||
-v$HARNESS_DIR/output:/output \ | ||
-e HOST_USER_ID=$(id -u) -e HOST_GROUP_ID=$(id -g) \ | ||
$IMAGE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash -eu | ||
: ${FUZZ_INPUT:="$HOME/input"} | ||
: ${FUZZ_OUTPUT:="$HOME/output"} | ||
: ${FUZZ_BUILD:="$HOME/build"} | ||
afl-fuzz -i $FUZZ_INPUT -o $FUZZ_OUTPUT -c $FUZZ_BUILD/cmplog/bin/fuzzing-persistent -m none -- $FUZZ_BUILD/asan/bin/fuzzing-persistent |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include "router_fuzzing_context.hpp" | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
|
||
#ifndef __AFL_FUZZ_TESTCASE_LEN | ||
ssize_t fuzz_len; | ||
#define __AFL_FUZZ_TESTCASE_LEN fuzz_len | ||
unsigned char fuzz_buf[1024000]; | ||
#define __AFL_FUZZ_TESTCASE_BUF fuzz_buf | ||
#define __AFL_FUZZ_INIT() void sync(void); | ||
#define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) | ||
#define __AFL_INIT() sync() | ||
#endif | ||
|
||
__AFL_FUZZ_INIT(); | ||
|
||
int main() | ||
{ | ||
#ifdef __AFL_HAVE_MANUAL_CONTROL | ||
__AFL_INIT(); | ||
#endif | ||
|
||
vanetza::RouterFuzzingContext context; | ||
|
||
unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; | ||
while (__AFL_LOOP(10000)) { | ||
int len = __AFL_FUZZ_TESTCASE_LEN; | ||
vanetza::ByteBuffer buffer { buf, buf + len }; | ||
context.initialize(); | ||
context.indicate(std::move(buffer)); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include "router_fuzzing_context.hpp" | ||
|
||
namespace vanetza | ||
{ | ||
|
||
class FuzzingRequestInterface : public dcc::RequestInterface | ||
{ | ||
void request(const dcc::DataRequest&, std::unique_ptr<ChunkPacket>) override {} | ||
}; | ||
|
||
class FuzzingTransportInterface : public geonet::TransportInterface | ||
{ | ||
void indicate(const geonet::DataIndication&, std::unique_ptr<geonet::UpPacket>) override {} | ||
}; | ||
|
||
RouterFuzzingContext::RouterFuzzingContext() : | ||
runtime(vanetza::Clock::at("2010-12-23 18:29")), security(runtime), | ||
req_ifc(std::make_unique<FuzzingRequestInterface>()), | ||
ind_ifc(std::make_unique<FuzzingTransportInterface>()) | ||
{ | ||
initialize(); | ||
} | ||
|
||
void RouterFuzzingContext::initialize() | ||
{ | ||
router = std::make_unique<geonet::Router>(runtime, mib); | ||
router->set_security_entity(&security.entity()); | ||
router->set_access_interface(req_ifc.get()); | ||
router->set_transport_handler(geonet::UpperProtocol::BTP_B, ind_ifc.get()); | ||
|
||
geonet::Address gn_addr; | ||
gn_addr.mid(MacAddress{0, 0, 0, 0, 0, 1}); | ||
router->set_address(gn_addr); | ||
} | ||
|
||
void RouterFuzzingContext::indicate(ByteBuffer&& buffer) | ||
{ | ||
MacAddress source { 0, 0, 0, 0, 0, 2 }; | ||
MacAddress destination { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
auto packet = std::make_unique<geonet::UpPacket>(CohesivePacket { std::move(buffer), OsiLayer::Network }); | ||
router->indicate(std::move(packet), source, destination); | ||
} | ||
|
||
} // namespace vanetza |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef VANETZA_ROUTER_FUZZING_CONTEXT_HPP | ||
#define VANETZA_ROUTER_FUZZING_CONTEXT_HPP | ||
|
||
#include <vanetza/common/manual_runtime.hpp> | ||
#include <vanetza/dcc/interface.hpp> | ||
#include <vanetza/geonet/router.hpp> | ||
#include <vanetza/geonet/transport_interface.hpp> | ||
#include <vanetza/geonet/tests/security_context.hpp> | ||
|
||
namespace vanetza | ||
{ | ||
|
||
class RouterFuzzingContext { | ||
public: | ||
RouterFuzzingContext(); | ||
void initialize(); | ||
void indicate(ByteBuffer&& buffer); | ||
|
||
private: | ||
ManualRuntime runtime; | ||
geonet::ManagementInformationBase mib; | ||
std::unique_ptr<geonet::Router> router; | ||
std::unique_ptr<dcc::RequestInterface> req_ifc; | ||
std::unique_ptr<geonet::TransportInterface> ind_ifc; | ||
SecurityContext security; | ||
}; | ||
|
||
} // namespace vanetza | ||
|
||
#endif //VANETZA_ROUTER_FUZZING_CONTEXT_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "router_fuzzing_context.hpp" | ||
#include <iostream> | ||
#include <fstream> | ||
|
||
vanetza::ByteBuffer readFileIntoBuffer(const std::string &filename) | ||
{ | ||
std::ifstream file(filename, std::ios::binary | std::ios::ate); | ||
if (!file.is_open()) { | ||
std::cerr << "Error opening file: " << filename << std::endl; | ||
return {}; | ||
} | ||
|
||
const std::streamsize size = file.tellg(); | ||
file.seekg(0, std::ios::beg); | ||
|
||
vanetza::ByteBuffer buffer(size); | ||
if (!file.read(reinterpret_cast<char *>(buffer.data()), size)) { | ||
std::cerr << "Error reading file: " << filename << std::endl; | ||
return {}; | ||
} | ||
|
||
return buffer; | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
if (argc != 2) { | ||
std::cerr << "Usage: " << argv[0] << " <filepath>" << std::endl; | ||
return 1; | ||
} | ||
|
||
const std::string filename = argv[1]; | ||
vanetza::ByteBuffer buffer = readFileIntoBuffer(filename); | ||
|
||
if (buffer.empty()) { | ||
return 1; | ||
} | ||
|
||
vanetza::RouterFuzzingContext context; | ||
context.indicate(std::move(buffer)); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <stdlib.h> | ||
|
||
static size_t max_size = 4096; | ||
|
||
void* vanetza_asn1c_malloc(size_t size) | ||
{ | ||
if (size <= max_size) | ||
return malloc(size); | ||
else | ||
return NULL; | ||
} | ||
|
||
void* vanetza_asn1c_calloc(size_t nmemb, size_t size) | ||
{ | ||
if (nmemb * size <= max_size) | ||
return calloc(nmemb, size); | ||
else | ||
return NULL; | ||
} | ||
|
||
void* vanetza_asn1c_realloc(void* ptr, size_t size) | ||
{ | ||
if (size <= max_size) | ||
return realloc(ptr, size); | ||
else | ||
return NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef VANETZA_ASN1C_MEMORY | ||
#define VANETZA_ASN1C_MEMORY | ||
|
||
#include <stddef.h> | ||
|
||
void* vanetza_asn1c_malloc(size_t size); | ||
void* vanetza_asn1c_calloc(size_t nmemb, size_t size); | ||
void* vanetza_asn1c_realloc(void* ptr, size_t size); | ||
|
||
#endif /* VANETZA_ASN1C_MEMORY */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.