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

feat: add initial fuzzing harnesses #87

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@

# Visual Studio Code files
.vscode
.vscode

# Fuzzing
tags
build
.cache
install
log
125 changes: 77 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ if(NOT CMAKE_CXX_STANDARD)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic
)
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

set(opencv_version 4)
Expand Down Expand Up @@ -86,34 +85,68 @@ if(NOT OpenCV_FOUND)
find_package(OpenCV 3 REQUIRED COMPONENTS imgproc highgui)
endif()


if (BUILD_GSTREAMER)
pkg_check_modules(GST REQUIRED IMPORTED_TARGET gstreamer-1.0)
include_directories(SYSTEM ${GST_INCLUDE_DIRS})
link_directories(${GST_LIBRARY_DIRS})
pkg_check_modules(GST REQUIRED IMPORTED_TARGET gstreamer-1.0)
include_directories(SYSTEM ${GST_INCLUDE_DIRS})
link_directories(${GST_LIBRARY_DIRS})
endif()

include_directories(include)

set(camera_dependencies
rclcpp
sensor_msgs
stereo_msgs
geometry_msgs
std_msgs
vision_msgs
rclcpp_components
camera_info_manager
cv_bridge
image_transport
rclcpp
sensor_msgs
stereo_msgs
geometry_msgs
std_msgs
vision_msgs
rclcpp_components
camera_info_manager
cv_bridge
image_transport
)

FILE(GLOB LIB_SRC
"src/ImageConverter.cpp"
"src/ImgDetectionConverter.cpp"
"src/ImuConverter.cpp"
"src/ImageConverter.cpp"
"src/ImgDetectionConverter.cpp"
"src/ImuConverter.cpp"
"src/DisparityConverter.cpp"
)

option(FUZZING "Enable fuzzing mode" OFF)


#find_library(ICU_LIBRARIES NAMES icuuc icudata icui18n PATHS /usr/lib/x86_64-linux-gnu)

if(FUZZING)
# Enable fuzzing and sanitizers
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,address,undefined -ggdb -O2")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=fuzzer,address,undefined -ggdb -O2")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=fuzzer,address,undefined -ggdb -O2")

# Add the depthai_bridge library
add_library(depthai_bridge SHARED ${LIB_SRC})
ament_target_dependencies(depthai_bridge PUBLIC ${camera_dependencies})
target_link_libraries(depthai_bridge PUBLIC depthai::core opencv_imgproc opencv_highgui)

# NOTE: This is copied from below as it enables correct compilation for
# the `ImgDetectionConverter.cpp`
target_compile_definitions(depthai_bridge PRIVATE IS_HUMBLE)

add_executable(img_conv_fuzz fuzz/img_conv_fuzz.cc)
target_link_libraries(img_conv_fuzz PRIVATE depthai_bridge)
add_executable(imu_conv_fuzz fuzz/imu_conv_fuzz.cc)
target_link_libraries(imu_conv_fuzz PRIVATE depthai_bridge)
add_executable(img_det_conv_fuzz fuzz/img_det_conv_fuzz.cc)
target_link_libraries(img_det_conv_fuzz PRIVATE depthai_bridge)
add_executable(disp_conv_fuzz fuzz/disp_fuzz.cc)
target_link_libraries(disp_conv_fuzz PRIVATE depthai_bridge)

# Stop after building the fuzz target
return()
endif()

# Regular build process continues here
add_library(depthai_bridge SHARED ${LIB_SRC})
ament_target_dependencies(depthai_bridge PUBLIC ${camera_dependencies})
target_link_libraries(depthai_bridge PUBLIC depthai-core opencv_imgproc opencv_highgui)
Expand All @@ -134,7 +167,6 @@ add_library(depthai_camera SHARED src/depthai_camera.cpp)
ament_target_dependencies(depthai_camera PUBLIC ${camera_dependencies})
target_link_libraries(depthai_camera PUBLIC depthai-core opencv_imgproc opencv_highgui depthai_bridge)


# DepthAI Camera as separate node
add_executable(camera_node src/camera_node.cpp)
ament_target_dependencies(camera_node PUBLIC rclcpp rclcpp_components)
Expand All @@ -145,32 +177,31 @@ add_dependencies(camera_node depthai_camera)
rclcpp_components_register_nodes(depthai_camera PLUGIN "${PROJECT_NAME}::DepthAICamera" EXECUTABLE depthai_camera)

if (BUILD_GSTREAMER)
# DepthAI GStreamer as Component library
add_library(gstreamer_interface SHARED src/gstreamer_interface.cpp)
ament_target_dependencies(gstreamer_interface PUBLIC rclcpp std_msgs sensor_msgs)
target_link_libraries(gstreamer_interface PUBLIC ${GST_LIBRARIES} gstapp-1.0)

# DepthAI GStreamer as Component library
add_library(depthai_gstreamer SHARED src/depthai_gstreamer.cpp)
ament_target_dependencies(depthai_gstreamer PUBLIC rclcpp std_msgs sensor_msgs rclcpp_components)
target_link_libraries(depthai_gstreamer PUBLIC ${GST_LIBRARIES} gstapp-1.0 gstreamer_interface)

# DepthAI GStreamer as separate node
add_executable(gstreamer_node src/gstreamer_node.cpp)
ament_target_dependencies(gstreamer_node PUBLIC rclcpp rclcpp_components)
target_link_libraries(gstreamer_node PUBLIC depthai_gstreamer)
# Combined DepthAI node
add_executable(depthai_ctrl src/depthai_ctrl.cpp)
ament_target_dependencies(depthai_ctrl PUBLIC rclcpp rclcpp_components)
target_link_libraries(depthai_ctrl PUBLIC depthai_camera depthai_gstreamer)

add_dependencies(depthai_ctrl depthai_gstreamer depthai_camera)
add_dependencies(gstreamer_node depthai_gstreamer)
rclcpp_components_register_nodes(depthai_gstreamer PLUGIN "${PROJECT_NAME}::DepthAIGStreamer" EXECUTABLE depthai_gstreamer)
# DepthAI GStreamer as Component library
add_library(gstreamer_interface SHARED src/gstreamer_interface.cpp)
ament_target_dependencies(gstreamer_interface PUBLIC rclcpp std_msgs sensor_msgs)
target_link_libraries(gstreamer_interface PUBLIC ${GST_LIBRARIES} gstapp-1.0)

# DepthAI GStreamer as Component library
add_library(depthai_gstreamer SHARED src/depthai_gstreamer.cpp)
ament_target_dependencies(depthai_gstreamer PUBLIC rclcpp std_msgs sensor_msgs rclcpp_components)
target_link_libraries(depthai_gstreamer PUBLIC ${GST_LIBRARIES} gstapp-1.0 gstreamer_interface)

# DepthAI GStreamer as separate node
add_executable(gstreamer_node src/gstreamer_node.cpp)
ament_target_dependencies(gstreamer_node PUBLIC rclcpp rclcpp_components)
target_link_libraries(gstreamer_node PUBLIC depthai_gstreamer)

# Combined DepthAI node
add_executable(depthai_ctrl src/depthai_ctrl.cpp)
ament_target_dependencies(depthai_ctrl PUBLIC rclcpp rclcpp_components)
target_link_libraries(depthai_ctrl PUBLIC depthai_camera depthai_gstreamer)

add_dependencies(depthai_ctrl depthai_gstreamer depthai_camera)
add_dependencies(gstreamer_node depthai_gstreamer)
rclcpp_components_register_nodes(depthai_gstreamer PLUGIN "${PROJECT_NAME}::DepthAIGStreamer" EXECUTABLE depthai_gstreamer)
endif()



# Disable tests as its obsolete
# if (BUILD_TESTING)
# enable_testing()
Expand Down Expand Up @@ -214,9 +245,7 @@ install(TARGETS
camera_node
DESTINATION lib/${PROJECT_NAME})


install(DIRECTORY launch params urdf
DESTINATION share/${PROJECT_NAME}
)
DESTINATION share/${PROJECT_NAME})

ament_package()
ament_package()
146 changes: 146 additions & 0 deletions fuzz/disp_fuzz.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include <cv_bridge/cv_bridge.hpp>
#include <fuzzer/FuzzedDataProvider.h>

#include "depthai-shared/common/CameraInfo.hpp"
#include <depthai/depthai.hpp>
#include <depthai_ctrl/DisparityConverter.hpp>
#include <depthai_ctrl/ImageConverter.hpp>
#include <depthai_ctrl/ImgDetectionConverter.hpp>
#include <depthai_ctrl/ImuConverter.hpp>
#include <deque>
#include <memory>
#include <ratio>
#include <tuple>

dai::RawImgFrame::Type PickFrameType(FuzzedDataProvider &fdp)
{
return fdp.PickValueInArray<dai::RawImgFrame::Type>(
{dai::RawImgFrame::Type::YUV422i, dai::RawImgFrame::Type::YUV444p,
dai::RawImgFrame::Type::YUV420p, dai::RawImgFrame::Type::YUV422p,
dai::RawImgFrame::Type::YUV400p, dai::RawImgFrame::Type::RGBA8888,
dai::RawImgFrame::Type::RGB161616, dai::RawImgFrame::Type::RGB888p,
dai::RawImgFrame::Type::BGR888p, dai::RawImgFrame::Type::RGB888i,
dai::RawImgFrame::Type::BGR888i, dai::RawImgFrame::Type::RGBF16F16F16p,
dai::RawImgFrame::Type::BGRF16F16F16p, dai::RawImgFrame::Type::RGBF16F16F16i,
dai::RawImgFrame::Type::BGRF16F16F16i, dai::RawImgFrame::Type::GRAY8,
dai::RawImgFrame::Type::GRAYF16, dai::RawImgFrame::Type::LUT2,
dai::RawImgFrame::Type::LUT4, dai::RawImgFrame::Type::LUT16,
dai::RawImgFrame::Type::RAW16, dai::RawImgFrame::Type::RAW14,
dai::RawImgFrame::Type::RAW12, dai::RawImgFrame::Type::RAW10,
dai::RawImgFrame::Type::RAW8, dai::RawImgFrame::Type::PACK10,
dai::RawImgFrame::Type::PACK12, dai::RawImgFrame::Type::YUV444i,
dai::RawImgFrame::Type::NV12, dai::RawImgFrame::Type::NV21,
dai::RawImgFrame::Type::BITSTREAM, dai::RawImgFrame::Type::HDR,
dai::RawImgFrame::Type::NONE});
}

std::chrono::time_point<std::chrono::steady_clock> GenerateFuzzTimestamp(FuzzedDataProvider &fdp)
{
using namespace std::chrono;
auto now = steady_clock::now();
auto now_ts = duration_cast<nanoseconds>(now.time_since_epoch()).count();

// Range: ±1 day in nanoseconds
constexpr uint64_t ONE_DAY_NS = 86400ULL * 1000000000ULL;

uint64_t fuzz_ns = fdp.ConsumeIntegralInRange<uint64_t>(now_ts - ONE_DAY_NS, // min: now - 1 day
now_ts + ONE_DAY_NS // max: now + 1 day
);

// Convert back to time_point by creating from epoch
return steady_clock::time_point(nanoseconds(fuzz_ns));
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{

if (size < 64)
{
return -1;
}

FuzzedDataProvider fdp(data, size);

std::string frameName = fdp.ConsumeRandomLengthString();
float focalLength = fdp.ConsumeFloatingPoint<float>();
float baseline = fdp.ConsumeFloatingPoint<float>();
float minDepth = fdp.ConsumeFloatingPoint<float>();
float maxDepth = fdp.ConsumeFloatingPoint<float>();

// printf("FOO\n");

try
{
dai::ros::DisparityConverter converter(frameName, focalLength, baseline, minDepth, maxDepth);
// dai::ros::DisparityConverter converter("asdf", 1.2);
// printf("BAR\n");

auto category = fdp.ConsumeIntegral<int>();
auto height = fdp.ConsumeIntegral<int>();
auto instanceNum = fdp.ConsumeIntegral<int>();
auto seqNum = fdp.ConsumeIntegral<int>();
auto width = fdp.ConsumeIntegral<int>();
auto type = PickFrameType(fdp);
auto ts = GenerateFuzzTimestamp(fdp);

// Determine the number of elements for the vector
size_t num_elements = fdp.ConsumeIntegralInRange<size_t>(1, 100);

// Create a vector to hold the integers
std::vector<int> int_list;

// Populate the vector by consuming integers from FuzzedDataProvider
for (size_t i = 0; i < num_elements; i++)
{
int_list.push_back(fdp.ConsumeIntegral<int>());
}

// Convert the std::vector<int> to std::vector<uint8_t>
std::vector<std::uint8_t> byte_list;
for (const auto &val : int_list)
{
// Safely cast/convert each int value to uint8_t
byte_list.push_back(static_cast<std::uint8_t>(val & 0xFF)); // Mask to 8 bits
}

auto inData = std::make_shared<dai::ImgFrame>();
inData->setWidth(width); // Image width in pixels
inData->setHeight(height); // Image height in pixels
inData->setCategory(category);
inData->setType(type); // Format/type (e.g.,dai::RawImgFrame::Type::BGR888)
inData->setData(byte_list); // Raw image data buffer
// FIXME:
inData->setTimestamp(ts); // Timestamp
inData->setSequenceNum(seqNum); // Sequence number
inData->setInstanceNum(instanceNum); // Instance number

std::deque<dai::ros::DisparityMsgs::DisparityImage> outImageMsg;
converter.toRosMsg(inData, outImageMsg);
}
catch (const std::exception &e)
{
printf("[!] ERR");
return -1;
}

return 0;
}

// 1. NULL PTR into memcpy as dst
// --> DisparityConverter:75 (crash-adc...2fc)

// 2. Multiple OOM situations in toRosMsg where aaray allocation takes place.
// --> e.g. ./oom-ba3c2d81f661ecb7fffa1aef25893db89f10b297

// 3. /home/user/git/work/depthai_ctrl/src/DisparityConverter.cpp:99:65: runtime
// error: -8 is outside the range of representable values of type 'unsigned
// long' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
// /home/user/git/work/depthai_ctrl/src/DisparityConverter.cpp:99:65
// std::transform(raw16Data.begin(), raw16Data.end(),
// std::back_inserter(convertedData),
// [](int16_t disp) -> std::size_t { return
// static_cast<float>(disp) / 32.0; });

// 4. Dvi by 0
// outImageMsg.step = size / inData->getHeight();
// crash-crash-4b3043662cdde20ecb4bfc70fa0ca03001438378
Loading
Loading