1 #include <assert.h>
2 #include <errno.h>
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/socket.h>
8 #include <unistd.h>
9 #include <libssh2.h>
10 #include "testinput.h"
11 
12 #define FUZZ_ASSERT(COND)                                                     \
13         if(!(COND))                                                           \
14         {                                                                     \
15           fprintf(stderr, "Assertion failed: " #COND "\n%s",                  \
16                   strerror(errno));                                           \
17           assert((COND));                                                     \
18         }
19 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)20 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
21 {
22   int socket_fds[2] = {-1, -1};
23   ssize_t written;
24   int rc;
25   LIBSSH2_SESSION *session = NULL;
26   int handshake_completed = 0;
27 
28   rc = libssh2_init(0);
29 
30   if(rc != 0) {
31     fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
32     goto EXIT_LABEL;
33   }
34 
35   // Create a socket pair so data can be sent in.
36   rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds);
37   FUZZ_ASSERT(rc == 0);
38 
39   written = send(socket_fds[1], data, size, 0);
40 
41   if (written != size)
42   {
43     // Handle whatever error case we're in.
44     fprintf(stderr, "send() of %zu bytes returned %zu (%d)\n",
45             size,
46             written,
47             errno);
48     goto EXIT_LABEL;
49   }
50 
51   rc = shutdown(socket_fds[1], SHUT_WR);
52   if (rc != 0)
53   {
54     fprintf(stderr, "socket shutdown failed (%d)\n", rc);
55     goto EXIT_LABEL;
56   }
57 
58   // Create a session and start the handshake using the fuzz data passed in.
59   session = libssh2_session_init();
60 
61   if(libssh2_session_handshake(session, socket_fds[0])) {
62     goto EXIT_LABEL;
63   }
64 
65   // If we get here the handshake actually completed.
66   handshake_completed = 1;
67 
68 EXIT_LABEL:
69 
70   if (session != NULL)
71   {
72     if (handshake_completed)
73     {
74       libssh2_session_disconnect(session,
75                                  "Normal Shutdown, Thank you for playing");
76     }
77 
78     libssh2_session_free(session);
79   }
80 
81   libssh2_exit();
82 
83   close(socket_fds[0]);
84   close(socket_fds[1]);
85 
86   return 0;
87 }