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