Skip to content

Commit c8af4e9

Browse files
authored
test: add one first fuzz target
re google/oss-fuzz#5137 for oss-fuzz integration
1 parent 6e5f96e commit c8af4e9

5 files changed

Lines changed: 87 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,21 @@ jobs:
4444
cd build
4545
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll test/ || true # used only for MinGW tests, ok to fail for other cases
4646
ctest --output-on-failure
47+
fuzzing_build:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v3
51+
- name: Install Ubuntu Build Dependencies
52+
run: |
53+
sudo apt update
54+
sudo apt install libsdl2-dev liblzo2-dev libssl-dev gnutls-dev libgcrypt-dev mingw-w64-x86-64-dev binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 wine clang
55+
- name: Build
56+
env:
57+
CC: "clang"
58+
LIB_FUZZING_ENGINE: "-fsanitize=fuzzer"
59+
CFLAGS: "-fsanitize=address,fuzzer-no-link -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"
60+
run: |
61+
mkdir build
62+
cd build
63+
cmake ..
64+
cmake --build .

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,12 @@ endif(WITH_EXAMPLES)
647647

648648
if(WITH_TESTS)
649649

650+
# First fuzzing
651+
if(DEFINED ENV{LIB_FUZZING_ENGINE})
652+
add_executable(fuzz_server ${TESTS_DIR}/fuzz_server.c)
653+
target_link_libraries(fuzz_server vncserver ${CMAKE_THREAD_LIBS_INIT} ${CARBON_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} $ENV{LIB_FUZZING_ENGINE})
654+
endif()
655+
650656
if(UNIX)
651657
set(ADDITIONAL_TEST_LIBS m)
652658
endif(UNIX)

libvncserver/rfbserver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
358358
rfbReleaseClientIterator(iterator);
359359
rfbLog(" %lu other clients\n", (unsigned long) otherClientsCount);
360360

361+
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
361362
if(!rfbSetNonBlocking(sock)) {
362363
rfbCloseSocket(sock);
363364
return NULL;
@@ -370,6 +371,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
370371

371372
FD_SET(sock,&(rfbScreen->allFds));
372373
rfbScreen->maxFd = rfbMax(sock,rfbScreen->maxFd);
374+
#endif
373375

374376
INIT_MUTEX(cl->outputMutex);
375377
INIT_MUTEX(cl->refCountMutex);
@@ -469,6 +471,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
469471
cl->pipe_notify_client_thread[1] = -1;
470472
#endif
471473

474+
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
472475
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
473476
/*
474477
* Wait a few ms for the client to send WebSockets connection (TLS/SSL or plain)
@@ -480,6 +483,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
480483
return NULL;
481484
}
482485
#endif
486+
#endif
483487

484488
#ifdef LIBVNCSERVER_HAVE_LIBZ
485489
cl->enableExtendedClipboard = FALSE;

libvncserver/sockets.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
545545
void
546546
rfbCloseClient(rfbClientPtr cl)
547547
{
548+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
549+
cl->sock = RFB_INVALID_SOCKET;
550+
#endif
548551
rfbExtensionData* extension;
549552

550553
for(extension=cl->extensions; extension; extension=extension->next)
@@ -638,6 +641,12 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
638641
return sock;
639642
}
640643

644+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
645+
size_t fuzz_offset;
646+
size_t fuzz_size;
647+
const uint8_t *fuzz_data;
648+
#endif
649+
641650
/*
642651
* ReadExact reads an exact number of bytes from a client. Returns 1 if
643652
* those bytes have been read, 0 if the other end has closed, or -1 if an error
@@ -647,6 +656,14 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
647656
int
648657
rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
649658
{
659+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
660+
if (fuzz_offset + len <= fuzz_size) {
661+
memcpy(buf, fuzz_data + fuzz_offset, len);
662+
fuzz_offset += len;
663+
return 1;
664+
}
665+
return 0;
666+
#endif
650667
rfbSocket sock = cl->sock;
651668
int n;
652669
fd_set fds;
@@ -739,6 +756,14 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len)
739756
int
740757
rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
741758
{
759+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
760+
if (fuzz_offset + len <= fuzz_size) {
761+
memcpy(buf, fuzz_data + fuzz_offset, len);
762+
fuzz_offset += len;
763+
return 1;
764+
}
765+
return 0;
766+
#endif
742767
rfbSocket sock = cl->sock;
743768
int n;
744769
fd_set fds;
@@ -817,6 +842,9 @@ rfbWriteExact(rfbClientPtr cl,
817842
const char *buf,
818843
int len)
819844
{
845+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
846+
return 1;
847+
#endif
820848
rfbSocket sock = cl->sock;
821849
int n;
822850
fd_set fds;

test/fuzz_server.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <rfb/rfb.h>
2+
3+
static int initialized = 0;
4+
rfbScreenInfoPtr server;
5+
char *fakeargv[] = {"fuzz_server"};
6+
7+
extern size_t fuzz_offset;
8+
extern size_t fuzz_size;
9+
extern const uint8_t *fuzz_data;
10+
11+
12+
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
13+
if (initialized == 0) {
14+
int fakeargc=1;
15+
server=rfbGetScreen(&fakeargc,fakeargv,400,300,8,3,4);
16+
server->frameBuffer=malloc(400*300*4);
17+
rfbInitServer(server);
18+
initialized = 1;
19+
}
20+
rfbClientPtr cl = rfbNewClient(server, RFB_INVALID_SOCKET - 1);
21+
22+
fuzz_data = Data;
23+
fuzz_offset = 0;
24+
fuzz_size = Size;
25+
while (cl->sock != RFB_INVALID_SOCKET) {
26+
rfbProcessClientMessage(cl);
27+
}
28+
rfbClientConnectionGone(cl);
29+
return 0;
30+
}
31+

0 commit comments

Comments
 (0)