forked from allenh1/rplidar_ros
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Christopher Krah
committed
May 20, 2024
1 parent
7f34c7c
commit c27bb54
Showing
3 changed files
with
256 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
cmake_minimum_required(VERSION 3.9.5) | ||
project(rplidar_fuzz) | ||
|
||
if (NOT CMAKE_CXX_STANDARD) | ||
set(CMAKE_CXX_STANDARD 17) | ||
endif () | ||
|
||
message(STATUS "CXX Compiler: ${CMAKE_CXX_COMPILER}") | ||
message(STATUS "CXX Flags before: ${CMAKE_CXX_FLAGS}") | ||
|
||
if (CMAKE_CXX_COMPILER) | ||
# Check if the CXX compiler is afl-clang or afl-clang++ | ||
if (CMAKE_CXX_COMPILER MATCHES "afl-clang-fast") | ||
message(STATUS "Using AFL Clang compiler") | ||
# Set flags for AFL | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,address,undefined -ggdb -O2 -fno-omit-frame-pointer") | ||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined -ggdb -O2") | ||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address,undefined -ggdb -O2") | ||
else() | ||
message(STATUS "Using regular Clang/GCC compiler") | ||
# Enable fuzzer and address sanitizers for other compilers | ||
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") | ||
endif() | ||
|
||
message(STATUS "CXX Flags after: ${CMAKE_CXX_FLAGS}") | ||
|
||
# Include directories for the SDK library | ||
include_directories( | ||
../sdk/include | ||
../sdk/src | ||
../sdk/src/arch/linux | ||
../sdk/src/hal) | ||
|
||
# Create instrumented SDK library | ||
add_library(rplidar_sdk_instr SHARED | ||
../sdk/src/rplidar_driver.cpp | ||
../sdk/src/arch/linux/net_serial.cpp | ||
../sdk/src/arch/linux/net_socket.cpp | ||
../sdk/src/arch/linux/timer.cpp | ||
../sdk/src/hal/thread.cpp) | ||
|
||
target_include_directories(rplidar_sdk_instr | ||
PUBLIC | ||
../sdk/include | ||
../sdk/src | ||
PRIVATE | ||
../sdk/src/arch/linux | ||
../sdk/src/hal) | ||
|
||
# Add the fuzz test executable | ||
add_executable(harness harness.cc) | ||
|
||
# Link against the instrumented rplidar_sdk library | ||
target_link_libraries(harness rplidar_sdk_instr) | ||
|
||
# Set the RPATH to find the SDK library | ||
set_target_properties(harness PROPERTIES INSTALL_RPATH "\$ORIGIN") | ||
|
||
# Set the output directory for the instrumented SDK library | ||
set_target_properties(rplidar_sdk_instr PROPERTIES | ||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") | ||
|
||
# Set the output directory for the fuzz test executable | ||
set_target_properties(harness PROPERTIES | ||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") | ||
else() | ||
message(FATAL_ERROR "CMAKE_CXX is not set. Please specify the CXX compiler.") | ||
endif () |
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,18 @@ | ||
BUILD_DIR := build | ||
|
||
.PHONY: all clean fuzz afl | ||
|
||
all: fuzz | ||
|
||
clean: | ||
rm -rf $(BUILD_DIR) | ||
|
||
fuzz: clean | ||
mkdir -p $(BUILD_DIR) | ||
cd $(BUILD_DIR) && CC=clang CXX=clang++ cmake .. && make | ||
mv $(BUILD_DIR)/harness harness | ||
|
||
afl: clean | ||
mkdir -p $(BUILD_DIR) | ||
cd $(BUILD_DIR) && CC=afl-clang-fast CXX=afl-clang-fast++ cmake .. && make | ||
mv $(BUILD_DIR)/harness harness_afl |
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,168 @@ | ||
#include "sdkcommon.h" | ||
|
||
#include "hal/abs_rxtx.h" | ||
#include "hal/event.h" | ||
#include "hal/locker.h" | ||
#include "hal/socket.h" | ||
#include "hal/thread.h" | ||
#include "hal/types.h" | ||
#include "rplidar_cmd.h" | ||
#include "rplidar_driver.h" | ||
#include "sdkcommon.h" | ||
|
||
// Is needed for `std::unique_ptr` | ||
#include <iostream> | ||
#include <iterator> | ||
#include <memory> | ||
#include <vector> | ||
|
||
#include <cstddef> | ||
#include <cstdint> | ||
#include <fuzzer/FuzzedDataProvider.h> | ||
#include <ostream> | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <string> | ||
|
||
#define MAX_ALLOC 1024 * 1000 | ||
|
||
// extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { return 0; } | ||
|
||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | ||
FuzzedDataProvider fdp(data, size); | ||
|
||
// Create an instance of the RPlidarDriver | ||
auto driverType = fdp.ConsumeBool() | ||
? rp::standalone::rplidar::DRIVER_TYPE_TCP | ||
: rp::standalone::rplidar::DRIVER_TYPE_SERIALPORT; | ||
auto drv = rp::standalone::rplidar::RPlidarDriver::CreateDriver(driverType); | ||
|
||
if (!drv) { | ||
return 0; | ||
} | ||
|
||
// Connect to the RPLIDAR device | ||
if (fdp.remaining_bytes() >= 2) { | ||
if (driverType == rp::standalone::rplidar::DRIVER_TYPE_SERIALPORT) { | ||
std::string portPath = fdp.ConsumeRandomLengthString(256); | ||
uint32_t baudrate = fdp.ConsumeIntegral<uint32_t>(); | ||
drv->connect(portPath.c_str(), baudrate); | ||
} else { | ||
std::string ip = fdp.ConsumeRandomLengthString(15); | ||
uint32_t port = fdp.ConsumeIntegral<uint32_t>(); | ||
|
||
// Check if _binded_socket is null before calling connect | ||
// if (static_cast<rp::standalone::rplidar::RPlidarDriver *>(drv) | ||
// ->_channel._binded_socket == nullptr) { | ||
// return -1; | ||
//} | ||
|
||
drv->connect(ip.c_str(), port); | ||
} | ||
} | ||
// Check if the device is connected | ||
drv->isConnected(); | ||
|
||
// Reset the device | ||
if (fdp.ConsumeBool()) { | ||
drv->reset(); | ||
} | ||
|
||
// Get all supported scan modes | ||
if (fdp.ConsumeBool()) { | ||
std::vector<rp::standalone::rplidar::RplidarScanMode> outModes; | ||
drv->getAllSupportedScanModes(outModes); | ||
} | ||
|
||
// Get typical scan mode | ||
if (fdp.ConsumeBool()) { | ||
uint16_t outMode; | ||
drv->getTypicalScanMode(outMode); | ||
} | ||
|
||
// Start scan | ||
if (fdp.ConsumeBool()) { | ||
bool force = fdp.ConsumeBool(); | ||
bool useTypicalScan = fdp.ConsumeBool(); | ||
rp::standalone::rplidar::RplidarScanMode outUsedScanMode; | ||
drv->startScan(force, useTypicalScan, 0, &outUsedScanMode); | ||
} | ||
|
||
// Start scan express | ||
if (fdp.ConsumeBool()) { | ||
bool force = fdp.ConsumeBool(); | ||
uint16_t scanMode = fdp.ConsumeIntegral<uint16_t>(); | ||
rp::standalone::rplidar::RplidarScanMode outUsedScanMode; | ||
drv->startScanExpress(force, scanMode, 0, &outUsedScanMode); | ||
} | ||
|
||
// Get health status | ||
if (fdp.ConsumeBool()) { | ||
rplidar_response_device_health_t health; | ||
drv->getHealth(health); | ||
} | ||
|
||
// Get device info | ||
if (fdp.ConsumeBool()) { | ||
rplidar_response_device_info_t info; | ||
drv->getDeviceInfo(info); | ||
} | ||
|
||
// Set motor PWM | ||
if (fdp.ConsumeBool()) { | ||
uint16_t pwm = fdp.ConsumeIntegral<uint16_t>(); | ||
drv->setMotorPWM(pwm); | ||
} | ||
|
||
// Start motor | ||
if (fdp.ConsumeBool()) { | ||
drv->startMotor(); | ||
} | ||
|
||
// Stop motor | ||
if (fdp.ConsumeBool()) { | ||
drv->stopMotor(); | ||
} | ||
|
||
// Check motor control support | ||
if (fdp.ConsumeBool()) { | ||
bool support; | ||
drv->checkMotorCtrlSupport(support); | ||
} | ||
|
||
// Get scan data | ||
if (fdp.ConsumeBool()) { | ||
// FIXME: Gotta wait for https://github.com/google/sanitizers/issues/1720 | ||
// size_t count = fdp.ConsumeIntegral<size_t>(); | ||
size_t count = fdp.ConsumeIntegralInRange<size_t>(0, MAX_ALLOC); | ||
|
||
auto nodebuffer = std::unique_ptr<rplidar_response_measurement_node_hq_t[]>( | ||
new rplidar_response_measurement_node_hq_t[count]); | ||
auto timeout = static_cast<uint32_t>(fdp.ConsumeIntegral<uint16_t>()); | ||
drv->grabScanDataHq(nodebuffer.get(), count, timeout); | ||
} | ||
|
||
// Ascend scan data | ||
if (fdp.ConsumeBool()) { | ||
// FIXME: same as above | ||
// size_t count = fdp.ConsumeIntegral<size_t>(); | ||
size_t count = fdp.ConsumeIntegralInRange<size_t>(0, MAX_ALLOC); | ||
auto nodebuffer = std::unique_ptr<rplidar_response_measurement_node_hq_t[]>( | ||
new rplidar_response_measurement_node_hq_t[count]); | ||
drv->ascendScanData(nodebuffer.get(), count); | ||
} | ||
|
||
// Get scan data with interval | ||
if (fdp.ConsumeBool()) { | ||
// FIXME: same as above | ||
// size_t count = fdp.ConsumeIntegral<size_t>(); | ||
size_t count = fdp.ConsumeIntegralInRange<size_t>(0, MAX_ALLOC); | ||
auto nodebuffer = std::unique_ptr<rplidar_response_measurement_node_hq_t[]>( | ||
new rplidar_response_measurement_node_hq_t[count]); | ||
drv->getScanDataWithIntervalHq(nodebuffer.get(), count); | ||
} | ||
// Dispose of the driver | ||
rp::standalone::rplidar::RPlidarDriver::DisposeDriver(drv); | ||
|
||
return 0; | ||
} |