add fuzzer and cram based unit tests
For improved QA etc. Signed-off-by: Petr Štetiar <ynezz@true.cz>
This commit is contained in:
parent
c413be9b37
commit
08f17c87a0
26 changed files with 198 additions and 0 deletions
|
@ -41,6 +41,15 @@ TARGET_LINK_LIBRARIES(ubus ${ubox_library})
|
|||
|
||||
find_library(json NAMES json-c json)
|
||||
|
||||
MACRO(ADD_UNIT_TEST_SAN name output_name)
|
||||
ADD_EXECUTABLE(${name}-san ${name}.c)
|
||||
TARGET_COMPILE_OPTIONS(${name}-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all)
|
||||
TARGET_LINK_OPTIONS(${name}-san PRIVATE -fsanitize=undefined,address,leak)
|
||||
TARGET_LINK_LIBRARIES(${name}-san ubus ubusd_library ${ubox_library} ${blob_library} ${json})
|
||||
TARGET_INCLUDE_DIRECTORIES(${name}-san PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
SET_TARGET_PROPERTIES(${name}-san PROPERTIES OUTPUT_NAME ${output_name})
|
||||
ENDMACRO(ADD_UNIT_TEST_SAN)
|
||||
|
||||
ADD_LIBRARY(ubusd_library STATIC ubusd.c ubusd_proto.c ubusd_id.c ubusd_obj.c ubusd_event.c ubusd_acl.c ubusd_monitor.c)
|
||||
ADD_EXECUTABLE(ubusd ubusd_main.c)
|
||||
TARGET_LINK_LIBRARIES(ubusd ubusd_library ${ubox_library} ${blob_library} ${json})
|
||||
|
@ -52,6 +61,13 @@ TARGET_LINK_LIBRARIES(cli ubus ${ubox_library} ${blob_library} ${json})
|
|||
ADD_SUBDIRECTORY(lua)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
|
||||
IF(UNIT_TESTING)
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ADD_UNIT_TEST_SAN(cli ubus-san)
|
||||
ADD_UNIT_TEST_SAN(ubusd_main ubusd-san)
|
||||
ENDIF()
|
||||
|
||||
INSTALL(TARGETS ubus cli
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
|
|
18
tests/CMakeLists.txt
Normal file
18
tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
ADD_SUBDIRECTORY(cram)
|
||||
|
||||
MACRO(ADD_UNIT_TEST name)
|
||||
ADD_EXECUTABLE(${name} ${name}.c)
|
||||
TARGET_LINK_LIBRARIES(${name} ubox blobmsg_json json_script ${json})
|
||||
TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
ENDMACRO(ADD_UNIT_TEST)
|
||||
|
||||
FILE(GLOB test_cases "test-*.c")
|
||||
FOREACH(test_case ${test_cases})
|
||||
GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE)
|
||||
ADD_UNIT_TEST(${test_case})
|
||||
ADD_UNIT_TEST_SAN(${test_case})
|
||||
ENDFOREACH(test_case)
|
||||
|
||||
IF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
ADD_SUBDIRECTORY(fuzz)
|
||||
ENDIF()
|
22
tests/cram/CMakeLists.txt
Normal file
22
tests/cram/CMakeLists.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
FIND_PACKAGE(PythonInterp 3 REQUIRED)
|
||||
FILE(GLOB test_cases "test_*.t")
|
||||
|
||||
SET(PYTHON_VENV_DIR "${CMAKE_CURRENT_BINARY_DIR}/.venv")
|
||||
SET(PYTHON_VENV_PIP "${PYTHON_VENV_DIR}/bin/pip")
|
||||
SET(PYTHON_VENV_CRAM "${PYTHON_VENV_DIR}/bin/cram")
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${PYTHON_VENV_CRAM}
|
||||
COMMAND ${PYTHON_EXECUTABLE} -m venv ${PYTHON_VENV_DIR}
|
||||
COMMAND ${PYTHON_VENV_PIP} install cram
|
||||
)
|
||||
ADD_CUSTOM_TARGET(prepare-cram-venv ALL DEPENDS ${PYTHON_VENV_CRAM})
|
||||
|
||||
ADD_TEST(
|
||||
NAME cram
|
||||
COMMAND ${PYTHON_VENV_CRAM} ${test_cases}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "UBUS=$<TARGET_FILE:ubus>")
|
||||
SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "TEST_BIN_DIR=$<TARGET_FILE_DIR:ubus>")
|
58
tests/cram/test_ubus.t
Normal file
58
tests/cram/test_ubus.t
Normal file
|
@ -0,0 +1,58 @@
|
|||
set environment for convenience:
|
||||
|
||||
$ [ -n "$TEST_BIN_DIR" ] && export PATH="$TEST_BIN_DIR:$PATH"
|
||||
$ alias ubus='valgrind --quiet --leak-check=full ubus'
|
||||
|
||||
check usage:
|
||||
|
||||
$ ubus
|
||||
Usage: ubus [<options>] <command> [arguments...]
|
||||
Options:
|
||||
-s <socket>:\t\tSet the unix domain socket to connect to (esc)
|
||||
-t <timeout>:\t\tSet the timeout (in seconds) for a command to complete (esc)
|
||||
-S:\t\t\tUse simplified output (for scripts) (esc)
|
||||
-v:\t\t\tMore verbose output (esc)
|
||||
-m <type>:\t\t(for monitor): include a specific message type (esc)
|
||||
\t\t\t(can be used more than once) (esc)
|
||||
-M <r|t>\t\t(for monitor): only capture received or transmitted traffic (esc)
|
||||
|
||||
Commands:
|
||||
- list [<path>]\t\t\tList objects (esc)
|
||||
- call <path> <method> [<message>]\tCall an object method (esc)
|
||||
- listen [<path>...]\t\t\tListen for events (esc)
|
||||
- send <type> [<message>]\t\tSend an event (esc)
|
||||
- wait_for <object> [<object>...]\tWait for multiple objects to appear on ubus (esc)
|
||||
- monitor\t\t\t\tMonitor ubus traffic (esc)
|
||||
|
||||
[1]
|
||||
|
||||
$ ubus-san
|
||||
Usage: ubus-san [<options>] <command> [arguments...]
|
||||
Options:
|
||||
-s <socket>:\t\tSet the unix domain socket to connect to (esc)
|
||||
-t <timeout>:\t\tSet the timeout (in seconds) for a command to complete (esc)
|
||||
-S:\t\t\tUse simplified output (for scripts) (esc)
|
||||
-v:\t\t\tMore verbose output (esc)
|
||||
-m <type>:\t\t(for monitor): include a specific message type (esc)
|
||||
\t\t\t(can be used more than once) (esc)
|
||||
-M <r|t>\t\t(for monitor): only capture received or transmitted traffic (esc)
|
||||
|
||||
Commands:
|
||||
- list [<path>]\t\t\tList objects (esc)
|
||||
- call <path> <method> [<message>]\tCall an object method (esc)
|
||||
- listen [<path>...]\t\t\tListen for events (esc)
|
||||
- send <type> [<message>]\t\tSend an event (esc)
|
||||
- wait_for <object> [<object>...]\tWait for multiple objects to appear on ubus (esc)
|
||||
- monitor\t\t\t\tMonitor ubus traffic (esc)
|
||||
|
||||
[1]
|
||||
|
||||
check monitor command:
|
||||
|
||||
$ ubus monitor
|
||||
Failed to connect to ubus
|
||||
[255]
|
||||
|
||||
$ ubus-san monitor
|
||||
Failed to connect to ubus
|
||||
[255]
|
24
tests/cram/test_ubusd.t
Normal file
24
tests/cram/test_ubusd.t
Normal file
|
@ -0,0 +1,24 @@
|
|||
set environment for convenience:
|
||||
|
||||
$ [ -n "$TEST_BIN_DIR" ] && export PATH="$TEST_BIN_DIR:$PATH"
|
||||
$ alias ubusd='valgrind --quiet --leak-check=full ubusd'
|
||||
|
||||
check usage:
|
||||
|
||||
$ ubusd -h
|
||||
ubusd: invalid option -- 'h'
|
||||
Usage: ubusd [<options>]
|
||||
Options:
|
||||
-A <path>:\t\tSet the path to ACL files (esc)
|
||||
-s <socket>:\t\tSet the unix domain socket to listen on (esc)
|
||||
|
||||
[1]
|
||||
|
||||
$ ubusd-san -h
|
||||
ubusd-san: invalid option -- 'h'
|
||||
Usage: ubusd-san [<options>]
|
||||
Options:
|
||||
-A <path>:\t\tSet the path to ACL files (esc)
|
||||
-s <socket>:\t\tSet the unix domain socket to listen on (esc)
|
||||
|
||||
[1]
|
18
tests/fuzz/CMakeLists.txt
Normal file
18
tests/fuzz/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
FILE(GLOB test_cases "test-*.c")
|
||||
|
||||
MACRO(ADD_FUZZER_TEST name)
|
||||
ADD_EXECUTABLE(${name} ${name}.c)
|
||||
TARGET_COMPILE_OPTIONS(${name} PRIVATE -g -O1 -fno-omit-frame-pointer -fsanitize=fuzzer,address,leak,undefined)
|
||||
TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
TARGET_LINK_OPTIONS(${name} PRIVATE -stdlib=libc++ -fsanitize=fuzzer,address,leak,undefined)
|
||||
TARGET_LINK_LIBRARIES(${name} ubus ubusd_library ${ubox_library} ${blob_library} ${json})
|
||||
ADD_TEST(
|
||||
NAME ${name}
|
||||
COMMAND ${name} -max_len=256 -timeout=10 -max_total_time=300 ${CMAKE_CURRENT_SOURCE_DIR}/corpus
|
||||
)
|
||||
ENDMACRO(ADD_FUZZER_TEST)
|
||||
|
||||
FOREACH(test_case ${test_cases})
|
||||
GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE)
|
||||
ADD_FUZZER_TEST(${test_case})
|
||||
ENDFOREACH(test_case)
|
BIN
tests/fuzz/corpus/05fe405753166f125559e7c9ac558654f107c7e9
Normal file
BIN
tests/fuzz/corpus/05fe405753166f125559e7c9ac558654f107c7e9
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/0660e49c13f6d167a8298d885f724bad8f62fc35
Normal file
BIN
tests/fuzz/corpus/0660e49c13f6d167a8298d885f724bad8f62fc35
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/37dadeab8d8ce7611f230f9524c1e8ab751c4a6a
Normal file
BIN
tests/fuzz/corpus/37dadeab8d8ce7611f230f9524c1e8ab751c4a6a
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a
Normal file
BIN
tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/73c72a4d2bd1cd31b0b44256a888feec9eaaba27
Normal file
BIN
tests/fuzz/corpus/73c72a4d2bd1cd31b0b44256a888feec9eaaba27
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/8db068f76b98df8730f5308b12c793fdf04c47c2
Normal file
BIN
tests/fuzz/corpus/8db068f76b98df8730f5308b12c793fdf04c47c2
Normal file
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
6
|
BIN
tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9
Normal file
BIN
tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-1b8fb1be45db3aff7699100f497fb74138f3df4f
Normal file
BIN
tests/fuzz/corpus/crash-1b8fb1be45db3aff7699100f497fb74138f3df4f
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-4c4d2c3c9ade5da9347534e290305c3b9760f627
Normal file
BIN
tests/fuzz/corpus/crash-4c4d2c3c9ade5da9347534e290305c3b9760f627
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-5e9937b197c88bf4e7b7ee2612456cad4cb83f5b
Normal file
BIN
tests/fuzz/corpus/crash-5e9937b197c88bf4e7b7ee2612456cad4cb83f5b
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-75b146c4e6fac64d3e62236b27c64b50657bab2a
Normal file
BIN
tests/fuzz/corpus/crash-75b146c4e6fac64d3e62236b27c64b50657bab2a
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-813f3e68661da09c26d4a87dbb9d5099e92be50f
Normal file
BIN
tests/fuzz/corpus/crash-813f3e68661da09c26d4a87dbb9d5099e92be50f
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-98595faa58ba01d85ba4fd0b109cd3d490b45795
Normal file
BIN
tests/fuzz/corpus/crash-98595faa58ba01d85ba4fd0b109cd3d490b45795
Normal file
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
BIN
tests/fuzz/corpus/crash-df9d1243057b27bbad6211e5a23d1cb699028aa2
Normal file
BIN
tests/fuzz/corpus/crash-df9d1243057b27bbad6211e5a23d1cb699028aa2
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/crash-e2fd5ecb3b37926743256f1083f47a07c39e10c2
Normal file
BIN
tests/fuzz/corpus/crash-e2fd5ecb3b37926743256f1083f47a07c39e10c2
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/e2814b29dd2fd5db02b1ab7c5e147e1194a489ce
Normal file
BIN
tests/fuzz/corpus/e2814b29dd2fd5db02b1ab7c5e147e1194a489ce
Normal file
Binary file not shown.
BIN
tests/fuzz/corpus/valid-blobmsg.bin
Normal file
BIN
tests/fuzz/corpus/valid-blobmsg.bin
Normal file
Binary file not shown.
40
tests/fuzz/test-fuzz.c
Normal file
40
tests/fuzz/test-fuzz.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <libubox/blob.h>
|
||||
#include <libubox/blobmsg.h>
|
||||
|
||||
#include "ubusmsg.h"
|
||||
#include "libubus.h"
|
||||
#include "libubus-internal.h"
|
||||
|
||||
static void _ubus_validate_hdr(const uint8_t *data, size_t size)
|
||||
{
|
||||
if (size > sizeof(struct ubus_msghdr))
|
||||
return;
|
||||
|
||||
ubus_validate_hdr((struct ubus_msghdr *) data);
|
||||
}
|
||||
|
||||
static void _ubus_parse_msg(const uint8_t *data, size_t size)
|
||||
{
|
||||
struct blob_attr *attr = (struct blob_attr *) data;
|
||||
|
||||
if (size < sizeof(struct blob_attr *))
|
||||
return;
|
||||
|
||||
if (blob_pad_len(attr) > UBUS_MAX_MSGLEN)
|
||||
return;
|
||||
|
||||
ubus_parse_msg(attr);
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
_ubus_validate_hdr(data, size);
|
||||
_ubus_parse_msg(data, size);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue