Skip to content

Commit

Permalink
fuzzing: add fuzzing tests
Browse files Browse the repository at this point in the history
Signed-off-by: Arjun <[email protected]>
  • Loading branch information
pkillarjun committed Nov 10, 2024
1 parent ffebcdd commit 4a922db
Show file tree
Hide file tree
Showing 15 changed files with 231 additions and 0 deletions.
40 changes: 40 additions & 0 deletions FUZZING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Fuzzing cockpit

## Build cockpit fuzzer using libFuzzer.

### Export flags for fuzzing.

Note that in `CFLAGS` and `CXXFLAGS`, any type of sanitizers can be added.

- [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
[ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html),
[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
[UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
[LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html).

```shell
$ export CC=clang
$ export CXX=clang++
$ export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
$ export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
$ export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
```

### Build cockpit for fuzzing.

```shell
$ ./autogen.sh --enable-fuzzing --disable-doc
$ make -j$(nproc)
```

### Running fuzzer.

```shell
$ mkdir -p fuzz_authorize_seed fuzz_base64_seed fuzz_websocket_seed

$ ./fuzz_authorize fuzz_authorize_seed src/common/fuzz_authorize_seed_corpus
$ ./fuzz_base64 fuzz_base64_seed src/common/fuzz_base64_seed_corpus
$ ./fuzz_websocket fuzz_websocket_seed src/websocket/fuzz_websocket_seed_corpus
```

Here is more information about [LibFuzzer](https://llvm.org/docs/LibFuzzer.html).
22 changes: 22 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,27 @@ AC_DEFINE_UNQUOTED([PATH_SSH_ADD], ["$SSH_ADD"], [Location of ssh-add binary])
AC_PATH_PROG([SSH_AGENT], [ssh-agent], [/usr/bin/ssh-agent], [$PATH:/usr/local/bin:/usr/bin:/bin])
AC_DEFINE_UNQUOTED([PATH_SSH_AGENT], ["$SSH_AGENT"], [Location of ssh-agent binary])

# Fuzzing
AC_MSG_CHECKING([for fuzzing])
AC_ARG_ENABLE(fuzzing,
AS_HELP_STRING([--enable-fuzzing=no/yes],
[Turn the fuzzing on or off])
)

if test "$enable_fuzzing" = "yes"; then
if test -z "$LIB_FUZZING_ENGINE"; then
FUZZING_ENGINE="-fsanitize=fuzzer"
else
FUZZING_ENGINE="$LIB_FUZZING_ENGINE"
fi
AC_SUBST(FUZZING_ENGINE)
fuzzing_status="yes"
else
fuzzing_status="no"
fi
AM_CONDITIONAL(WITH_FUZZING, test "$enable_fuzzing" = "yes")
AC_MSG_RESULT($fuzzing_status)

# Address sanitizer
AC_MSG_CHECKING([for asan flags])
AC_ARG_ENABLE(asan,
Expand Down Expand Up @@ -371,6 +392,7 @@ echo "
Debug mode: ${debug_status}
Node environment: ${NODE_ENV}
With coverage: ${enable_coverage}
With fuzzing: ${fuzzing_status}
With address sanitizer: ${asan_status}
SELinux Policy: ${enable_selinux_policy}

Expand Down
12 changes: 12 additions & 0 deletions src/common/Makefile-common.am
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,15 @@ TEST_PROGRAM += test-webserver
test_webserver_CPPFLAGS = $(libcockpit_common_a_CPPFLAGS) $(TEST_CPP)
test_webserver_LDADD = $(TEST_LIBS)
test_webserver_SOURCES = src/common/test-webserver.c

if WITH_FUZZING
noinst_PROGRAMS += fuzz_authorize
fuzz_authorize_SOURCES = src/common/fuzz_authorize.c
fuzz_authorize_CPPFLAGS = $(libcockpit_common_a_CPPFLAGS)
fuzz_authorize_LDADD = $(libcockpit_common_a_LIBS) $(FUZZING_ENGINE)

noinst_PROGRAMS += fuzz_base64
fuzz_base64_SOURCES = src/common/fuzz_base64.c
fuzz_base64_CPPFLAGS = $(libcockpit_common_a_CPPFLAGS)
fuzz_base64_LDADD = $(libcockpit_common_a_LIBS) $(FUZZING_ENGINE)
endif
59 changes: 59 additions & 0 deletions src/common/fuzz_authorize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "config.h"

#include "cockpitauthorize.h"

#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define kMinInputLength 2
#define kMaxInputLength 1024

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char *data_in;

if (size < kMinInputLength || size > kMaxInputLength)
return 0;

data_in = calloc(size + 1, sizeof(char));
if (data_in == NULL)
return 0;

memcpy(data_in, data, size);

{
char *user = "a";
char *password = NULL;

password = cockpit_authorize_parse_basic(data_in, &user);
if (password != NULL) {
free(password);
free(user);
}
}
{
void *result = NULL;

result = cockpit_authorize_parse_negotiate(data_in, NULL);
if (result != NULL)
free(result);
}
{
void *result = NULL;
char *conversation = NULL;

result = cockpit_authorize_parse_x_conversation(data_in, &conversation);
if (result != NULL)
free(result);

if (conversation != NULL)
free(conversation);
}

free(data_in);
return 0;
}
1 change: 1 addition & 0 deletions src/common/fuzz_authorize_seed_corpus/basic_fixtures.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Basic c2NydWZmeTp6ZXJvZw==
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Negotiate c2NydWZmeTp6ZXJvZw==
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
X-Conversation abcdefghi c2NydWZmeTp6ZXJvZw==
25 changes: 25 additions & 0 deletions src/common/fuzz_base64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "config.h"

#include "cockpitbase64.h"

#include <stdint.h>

#define kMinInputLength 2
#define kMaxInputLength 1024

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char encoded[2048];
uint8_t decoded[2048];

if (size < kMinInputLength || size > kMaxInputLength)
return 0;

cockpit_base64_ntop(data, size, encoded, sizeof(encoded));
cockpit_base64_pton((char *)data, size, decoded, sizeof(decoded));

return 0;
}
1 change: 1 addition & 0 deletions src/common/fuzz_base64_seed_corpus/decoded.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
QUFBQQ==
1 change: 1 addition & 0 deletions src/common/fuzz_base64_seed_corpus/encoded.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AAAA
7 changes: 7 additions & 0 deletions src/websocket/Makefile-websocket.am
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@ TEST_PROGRAM += test-websocket
test_websocket_CPPFLAGS = $(libwebsocket_a_CPPFLAGS) $(TEST_CPP)
test_websocket_LDADD = $(libwebsocket_a_LIBS) $(TEST_LIBS)
test_websocket_SOURCES = src/websocket/test-websocket.c

if WITH_FUZZING
noinst_PROGRAMS += fuzz_websocket
fuzz_websocket_SOURCES = src/websocket/fuzz_websocket.c
fuzz_websocket_CPPFLAGS = $(libwebsocket_a_CPPFLAGS)
fuzz_websocket_LDADD = $(libwebsocket_a_LIBS) $(libcockpit_common_a_LIBS) $(FUZZING_ENGINE)
endif
56 changes: 56 additions & 0 deletions src/websocket/fuzz_websocket.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "config.h"

#include "websocket.h"
#include "websocketprivate.h"

#include <stdint.h>

#define kMinInputLength 2
#define kMaxInputLength 1024

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char *data_in;

if (size < kMinInputLength || size > kMaxInputLength)
return 0;

data_in = calloc(size + 1, sizeof(char));
if (data_in == NULL)
return 0;

memcpy(data_in, data, size);

{
gchar *path = NULL;
gchar *method = NULL;

web_socket_util_parse_req_line((char *)data, size, &method, &path);
if (method != NULL)
g_free(method);

if (path != NULL)
g_free(path);
}
{
guint status;
gchar *reason = NULL;

web_socket_util_parse_status_line(data_in, size + 1, NULL, &status, &reason);
if (reason != NULL)
g_free(reason);
}
{
GHashTable *headers = NULL;

web_socket_util_parse_headers(data_in, size + 1, &headers);
if (headers != NULL)
g_hash_table_unref(headers);
}

free(data_in);
return 0;
}
1 change: 1 addition & 0 deletions src/websocket/fuzz_websocket_seed_corpus/headers.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Host:https://cockpit-project.org
2 changes: 2 additions & 0 deletions src/websocket/fuzz_websocket_seed_corpus/req_line.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /path/part HTTP/1.0

2 changes: 2 additions & 0 deletions src/websocket/fuzz_websocket_seed_corpus/status_line.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
HTTP/1.0 101 Switching Protocols

0 comments on commit 4a922db

Please sign in to comment.