diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-07 12:22:23 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-07 12:23:51 +0200 |
commit | 1545fb57b861d55e65fe046c9e30cc5346264288 (patch) | |
tree | d10393608ce11fa93b1d0227d82106dba815f714 /devel | |
parent | e996ffb4082cd181b809fb8d5ba46629b9c0913d (diff) | |
download | gnutls-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.cc | 140 |
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; } |