summaryrefslogtreecommitdiff
path: root/devel
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-07 12:22:23 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-07 12:23:51 +0200
commit1545fb57b861d55e65fe046c9e30cc5346264288 (patch)
treed10393608ce11fa93b1d0227d82106dba815f714 /devel
parente996ffb4082cd181b809fb8d5ba46629b9c0913d (diff)
downloadgnutls-1545fb57b861d55e65fe046c9e30cc5346264288.tar.gz
fuzz: gnutls-client-fuzzer: read directly from memory [ci skip]
Also updated to read the prefixed boringssl corpus files. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'devel')
-rw-r--r--devel/fuzz/gnutls_client_fuzzer.cc140
1 files changed, 95 insertions, 45 deletions
diff --git a/devel/fuzz/gnutls_client_fuzzer.cc b/devel/fuzz/gnutls_client_fuzzer.cc
index 7719502230..81718500cf 100644
--- a/devel/fuzz/gnutls_client_fuzzer.cc
+++ b/devel/fuzz/gnutls_client_fuzzer.cc
@@ -1,5 +1,6 @@
/*
# Copyright 2016 Google Inc.
+# Copyright 2017 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -20,57 +21,106 @@
#include <fcntl.h>
#include <stdint.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
#include <gnutls/gnutls.h>
+struct mem_st {
+ const uint8_t *data;
+ size_t size;
+};
+
+#define MIN(x,y) ((x)<(y)?(x):(y))
+static ssize_t
+client_push(gnutls_transport_ptr_t tr, const void *data, size_t len)
+{
+ return len;
+}
+
+static ssize_t client_pull(gnutls_transport_ptr_t tr, void *data, size_t len)
+{
+ struct mem_st *p = (struct mem_st *)tr;
+
+ if (p->size == 0) {
+ return 0;
+ }
+
+ len = MIN(len, p->size);
+ memcpy(data, p->data, len);
+
+ p->size -= len;
+ p->data += len;
+
+ return len;
+}
+
+int client_pull_timeout_func(gnutls_transport_ptr_t tr, unsigned int ms)
+{
+ struct mem_st *p = (struct mem_st *)tr;
+
+ if (p->size > 0)
+ return 1; /* available data */
+ else
+ return 0; /* timeout */
+}
#ifdef __cplusplus
extern "C"
#endif
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- int res;
- gnutls_session_t session;
- gnutls_certificate_credentials_t xcred;
-
- int socket_fds[2];
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds);
- assert(res >= 0);
- ssize_t send_res = send(socket_fds[1], data, size, 0);
- assert((size_t)send_res == size);
- res = shutdown(socket_fds[1], SHUT_WR);
- assert(res == 0);
-
- res = gnutls_init(&session, GNUTLS_CLIENT);
- assert(res >= 0);
-
- res = gnutls_certificate_allocate_credentials(&xcred);
- assert(res >= 0);
- res = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
- assert(res >= 0);
-
- res = gnutls_set_default_priority(session);
- assert(res >= 0);
-
- gnutls_transport_set_int(session, socket_fds[0]);
-
- do {
- res = gnutls_handshake(session);
- } while (res < 0 && gnutls_error_is_fatal(res) == 0);
- if (res >= 0) {
- while (true) {
- char buf[16384];
- res = gnutls_record_recv(session, buf, sizeof(buf));
- if (res <= 0) {
- break;
- }
- }
- }
-
- close(socket_fds[0]);
- close(socket_fds[1]);
- gnutls_deinit(session);
- gnutls_certificate_free_credentials(xcred);
- return 0;
+int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
+{
+ int res;
+ gnutls_session_t session;
+ gnutls_certificate_credentials_t xcred;
+ struct mem_st memdata;
+ uint16_t tag;
+
+ if (size < 2)
+ abort();
+
+ memcpy(&tag, data, 2);
+ data += 2;
+ size -= 2;
+
+ if (tag != 0) /* ignore */
+ return 0;
+
+ res = gnutls_init(&session, GNUTLS_CLIENT);
+ assert(res >= 0);
+
+ res = gnutls_certificate_allocate_credentials(&xcred);
+ assert(res >= 0);
+ res = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+ assert(res >= 0);
+
+ res = gnutls_set_default_priority(session);
+ assert(res >= 0);
+
+ memdata.data = data;
+ memdata.size = size;
+
+ gnutls_transport_set_push_function(session, client_push);
+ gnutls_transport_set_pull_function(session, client_pull);
+ gnutls_transport_set_pull_timeout_function(session,
+ client_pull_timeout_func);
+ gnutls_transport_set_ptr(session, &memdata);
+
+ do {
+ res = gnutls_handshake(session);
+ } while (res < 0 && gnutls_error_is_fatal(res) == 0);
+ if (res >= 0) {
+ while (true) {
+ char buf[16384];
+ res = gnutls_record_recv(session, buf, sizeof(buf));
+ if (res <= 0) {
+ break;
+ }
+ }
+ }
+
+ gnutls_deinit(session);
+ gnutls_certificate_free_credentials(xcred);
+ return 0;
}