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 }