Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial fuzzing code #372

Merged
merged 27 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fb674e1
run clang-format on lib/
alexgeana Jun 6, 2023
5dbe6d3
Fuzzing: cmake updates
alexgeana Jul 4, 2023
334e8f0
Fuzzing: decrease size of some buffers in fuzzing builds
alexgeana Jul 4, 2023
87234f3
Fuzzing: enable ASAN or MSAN fuzzing in cmake
alexgeana Jul 26, 2023
54bb450
Fuzzing: enable fuzzing for the lib component
alexgeana Jul 26, 2023
f9127f5
Fuzzing: pkcs11 harness for C_GetAttributeValue
alexgeana Jul 27, 2023
ec277fc
Fuzzing: only enable fuzzing backend in fuzzing builds
alexgeana Oct 6, 2023
08ece8d
Fuzzing: cmake changes
alexgeana Oct 6, 2023
e73e4fe
Fuzzing: remove FuzzedDataProvider
alexgeana Oct 6, 2023
5a4e53e
Fuzzing: fix pkcs11 CMakeLists.txt
alexgeana Oct 10, 2023
96a3cee
Fuzzing: fix compiler errors/warnings
alexgeana Oct 10, 2023
e8c0822
Fuzing: move yubihsm_fuzz.h
alexgeana Oct 10, 2023
2936515
add missing source for wrap binary
alexgeana Oct 10, 2023
d0c1303
Fuzzing: add Dockerfile for MSAN
alexgeana Oct 10, 2023
577930d
Fuzzing: initial harness for yh_send_secure_msg
alexgeana Oct 10, 2023
1dcc563
Fuzzing: workflow to build MSAN container
alexgeana Oct 27, 2023
65164bb
Fuzzing: remove Dockerfile comments
alexgeana Oct 27, 2023
5135762
Fuzzing: add packages permission to github token
alexgeana Oct 30, 2023
69bab37
Fuzzing: initial build and fuzz workflow
alexgeana Oct 31, 2023
318a174
Fuzzing: MSAN docker container builds llvm for host
alexgeana Oct 31, 2023
deb8e79
Fuzzing: build with ASAN as well
alexgeana Nov 6, 2023
00f10cf
Fix error message
alexgeana Nov 13, 2023
9779733
Fuzzing: harnessing improvements
alexgeana Nov 30, 2023
b5678a8
Additional buffer length checks
alexgeana Nov 30, 2023
28bdf45
Fuzzing: add back FuzzedDataProvider
alexgeana Nov 30, 2023
85dfd6e
Fuzzing: run harness as part of workflow
alexgeana Nov 30, 2023
5bb639b
Fuzzer: Fix rebase discrepancy
aveenismail Sep 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading