Skip to content

Commit

Permalink
Initial fuzzing code (#372)
Browse files Browse the repository at this point in the history
Introducing initial fuzzing functionality
  • Loading branch information
alexgeana authored Sep 24, 2024
1 parent 898f03d commit ec05084
Show file tree
Hide file tree
Showing 21 changed files with 1,165 additions and 20 deletions.
75 changes: 75 additions & 0 deletions .github/workflows/build_and_fuzz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Build and Fuzz

on:
schedule:
# Run this every wednesday at 3:50. https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
- cron: '50 3 * * 3'

jobs:
fuzz_msan:
name: fuzz with MemorySanitizer
runs-on: ubuntu-latest
container: ghcr.io/yubico/yubihsm-shell/fuzzing-msan:latest

steps:

- name: clone the Yubico/yubihsm-shell repository
uses: actions/checkout@v3
with:
path: yubihsm-shell

- name: do build
working-directory: yubihsm-shell
run: |
cmake \
-DFUZZING=ON \
-DFUZZING_MSAN=ON \
-DWITHOUT_MANPAGES=ON \
-DDISABLE_LTO=ON \
-DENABLE_STATIC=ON \
-B build-msan
cmake --build build-msan
- name: run harness for fuzz_get_attribute_value
working-directory: yubihsm-shell
run: ./build-msan/pkcs11/fuzz_get_attribute_value -max_total_time=1800

fuzz_asan:
name: fuzz with AddressSanitizer
runs-on: ubuntu-latest
container: ubuntu:23.04

steps:

- name: install dependencies from package management
env:
DEBIAN_FRONTEND: noninteractive
run: |
apt -q -y update
apt -q -y install \
llvm-16 clang-16 lld-16 \
build-essential cmake ninja-build pkg-config \
libssl-dev libedit-dev libcurl4-openssl-dev libusb-1.0-0-dev libpcsclite-dev gengetopt
- name: clone the Yubico/yubihsm-shell repository
uses: actions/checkout@v3
with:
path: yubihsm-shell

- name: do build
env:
CC: clang-16
CXX: clang++-16
working-directory: yubihsm-shell
run: |
cmake \
-DFUZZING=ON \
-DWITHOUT_MANPAGES=ON \
-DDISABLE_LTO=ON \
-DENABLE_STATIC=ON \
-B build-asan
cmake --build build-asan
- name: run harness for fuzz_get_attribute_value
working-directory: yubihsm-shell
run: ./build-asan/pkcs11/fuzz_get_attribute_value -max_total_time=1800
35 changes: 35 additions & 0 deletions .github/workflows/push_fuzzing_msan_container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Create MSAN fuzzing docker image

on:
push:
paths:
- "resources/fuzzing/Docker.fuzzing_msan"

jobs:
build_and_push:
name: Build and Push

runs-on: ubuntu-latest

permissions:
packages: write

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build image
uses: docker/build-push-action@v5
with:
pull: true
push: true
tags: ghcr.io/yubico/yubihsm-shell/fuzzing-msan:latest
context: "{{defaultContext}}:resources/fuzzing"
file: "Docker.fuzzing_msan"
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ project (yubihsm-shell)
option(BUILD_ONLY_LIB "Library only build" OFF)
option(SUPRESS_MSVC_WARNINGS "Suppresses a lot of the warnings when compiling with MSVC" ON)

include(${CMAKE_SOURCE_DIR}/cmake/Fuzzing.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/SecurityFlags.cmake)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
Expand Down
27 changes: 27 additions & 0 deletions cmake/Fuzzing.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
option(FUZZING "Compile binaries with fuzzing instrumentation" OFF)
option(LIBFUZZER_ASAN "Enable ASAN instrumentation with libfuzzer" OFF)
option(FUZZING_MSAN "Compile binaries with MemorySanitizer instrumentation" OFF)

if (FUZZING)
message(STATUS "Building with fuzzing instrumentation.")

string (APPEND CMAKE_C_FLAGS " -DFUZZING")
string (APPEND CMAKE_C_FLAGS " -fno-omit-frame-pointer -O1 -g")

string (APPEND CMAKE_CXX_FLAGS " -std=c++17")
string (APPEND CMAKE_CXX_FLAGS " -DFUZZING")
string (APPEND CMAKE_CXX_FLAGS " -fno-omit-frame-pointer -O1 -g")

string (APPEND CMAKE_EXE_LINKER_FLAGS " -g")

if (FUZZING_MSAN)
string (APPEND CMAKE_C_FLAGS " -fsanitize=memory")
string (APPEND CMAKE_CXX_FLAGS " -fsanitize=memory")
string (APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=memory")
else (FUZZING_MSAN)
string (APPEND CMAKE_C_FLAGS " -fsanitize=address -fsanitize=undefined")
string (APPEND CMAKE_CXX_FLAGS " -fsanitize=address -fsanitize=undefined")
string (APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address -fsanitize=undefined")
endif (FUZZING_MSAN)

endif ()
4 changes: 2 additions & 2 deletions cmake/SecurityFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ if (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR
CMAKE_C_COMPILER_ID STREQUAL "AppleClang" OR
CMAKE_C_COMPILER_ID STREQUAL "GNU")

add_compile_options (-Wall -Wextra -Werror)
add_compile_options (-Wformat -Wformat-nonliteral -Wformat-security)
add_compile_options (-Wshadow)
#add_compile_options (-Wcast-qual)
add_compile_options (-Wmissing-prototypes)
add_compile_options (-Wbad-function-cast)
add_compile_options (-pedantic -pedantic-errors)
add_compile_options (-fpie -fpic)
if (NOT FUZZ)
if (NOT FUZZING)
add_compile_options (-Wall -Wextra -Werror)
add_compile_options(-O2)
add_definitions (-D_FORTIFY_SOURCE=2)
endif ()
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set (
SOURCE_WRAP
wrap.c
../common/util.c
../common/hash.c
../common/openssl-compat.c
)

Expand Down
12 changes: 12 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ else(WIN32)
set(CRYPT_LIBRARY ${LIBCRYPTO_LDFLAGS})

list(APPEND STATIC_SOURCE yubihsm_libusb.c yubihsm_usb.c yubihsm_curl.c)

if(FUZZING)
add_executable(fuzz_send_plain_msg ${SOURCE} fuzz/fuzz_send_plain_msg.cc fuzz/yubihsm_fuzz.cc)
set_target_properties (fuzz_send_plain_msg PROPERTIES COMPILE_FLAGS "-DSTATIC -fsanitize=fuzzer ")
set_target_properties (fuzz_send_plain_msg PROPERTIES LINK_FLAGS "-fsanitize=fuzzer ")
target_link_libraries (fuzz_send_plain_msg ${LIBCRYPTO_LDFLAGS})

add_executable(fuzz_send_secure_msg ${SOURCE} fuzz/fuzz_send_secure_msg.cc fuzz/yubihsm_fuzz.cc)
set_target_properties (fuzz_send_secure_msg PROPERTIES COMPILE_FLAGS "-DSTATIC -fsanitize=fuzzer ")
set_target_properties (fuzz_send_secure_msg PROPERTIES LINK_FLAGS "-fsanitize=fuzzer ")
target_link_libraries (fuzz_send_secure_msg ${LIBCRYPTO_LDFLAGS})
endif(FUZZING)
endif(WIN32)

include_directories (
Expand Down
46 changes: 46 additions & 0 deletions lib/fuzz/fuzz_send_plain_msg.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <assert.h>
#include "debug_lib.h"

extern "C" {
#include "yubihsm.h"

uint8_t *backend_data;
size_t backend_data_len;
}

#include "yubihsm_fuzz.h"

yh_connector *connector;

static bool initialize() {
yh_rc rc = yh_init_connector("yhfuzz://yubihsm_fuzz", &connector);
assert(rc == YHR_SUCCESS);
rc = yh_connect(connector, 0);
assert(rc == YHR_SUCCESS);
return true;
}

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
static bool is_initialized = initialize();

if (size < 2) {
return 0;
}
size_t data_len = data[0];
size_t response_len = data[1];

backend_data = data + 2;
backend_data_len = size - 2;

uint8_t *hsm_data = new uint8_t[data_len];
uint8_t *response = new uint8_t[response_len];
yh_cmd response_cmd;

yh_send_plain_msg(connector, YHC_ECHO, hsm_data, data_len, &response_cmd,
response, &response_len);

delete[] hsm_data;
delete[] response;

return 0;
}
62 changes: 62 additions & 0 deletions lib/fuzz/fuzz_send_secure_msg.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <assert.h>
#include <string.h>
#include "debug_lib.h"

extern "C" {
#include "yubihsm.h"

uint8_t *backend_data;
size_t backend_data_len;
yh_session *fuzz_session;
}

#include "yubihsm_fuzz.h"

yh_connector *connector;

static bool initialize() {
yh_rc rc = yh_init_connector("yhfuzz://yubihsm_fuzz", &connector);
assert(rc == YHR_SUCCESS);
rc = yh_connect(connector, 0);
assert(rc == YHR_SUCCESS);
return true;
}

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
static bool is_initialized = initialize();
yh_rc yrc = YHR_GENERIC_ERROR;

if (size < 2) {
return 0;
}

yrc = yh_create_session_derived(connector, 1,
(const uint8_t *) FUZZ_BACKEND_PASSWORD,
strlen(FUZZ_BACKEND_PASSWORD), false,
&fuzz_session);
assert(yrc == YHR_SUCCESS);

size_t data_len = data[0];
size_t response_len = data[1];

backend_data = data + 2;
backend_data_len = size - 2;

uint8_t *hsm_data = new uint8_t[data_len];
uint8_t *response = new uint8_t[response_len];
yh_cmd response_cmd;

yh_send_secure_msg(fuzz_session, YHC_ECHO, hsm_data, data_len, &response_cmd,
response, &response_len);

yrc = yh_util_close_session(fuzz_session);
assert(yrc == YHR_SUCCESS);

yrc = yh_destroy_session(&fuzz_session);
assert(yrc == YHR_SUCCESS);

delete[] hsm_data;
delete[] response;

return 0;
}
Loading

0 comments on commit ec05084

Please sign in to comment.