98 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| /* Copyright (C) The libssh2 project and its contributors.
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-3-Clause
 | |
|  */
 | |
| #include <assert.h>
 | |
| #include <errno.h>
 | |
| #include <stdbool.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <sys/socket.h>
 | |
| #include <unistd.h>
 | |
| #include <libssh2.h>
 | |
| #include "testinput.h"
 | |
| 
 | |
| #define FUZZ_ASSERT(COND)                                                     \
 | |
|     if(!(COND))                                                               \
 | |
|     {                                                                         \
 | |
|       fprintf(stderr, "Assertion failed: " #COND "\n%s",                      \
 | |
|               strerror(errno));                                               \
 | |
|       assert((COND));                                                         \
 | |
|     }
 | |
| 
 | |
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 | |
| {
 | |
|   int socket_fds[2] = {-1, -1};
 | |
|   ssize_t written;
 | |
|   int rc;
 | |
|   LIBSSH2_SESSION *session = NULL;
 | |
|   int handshake_completed = 0;
 | |
| 
 | |
|   rc = libssh2_init(0);
 | |
| 
 | |
|   if(rc) {
 | |
|     fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
 | |
|     goto EXIT_LABEL;
 | |
|   }
 | |
| 
 | |
|   // Create a socket pair so data can be sent in.
 | |
|   rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds);
 | |
|   FUZZ_ASSERT(rc == 0);
 | |
| 
 | |
|   written = send(socket_fds[1], data, size, 0);
 | |
| 
 | |
|   if(written != size)
 | |
|   {
 | |
|     // Handle whatever error case we're in.
 | |
|     fprintf(stderr, "send() of %zu bytes returned %zu (%d)\n",
 | |
|             size,
 | |
|             written,
 | |
|             errno);
 | |
|     goto EXIT_LABEL;
 | |
|   }
 | |
| 
 | |
|   rc = shutdown(socket_fds[1], SHUT_WR);
 | |
|   if(rc)
 | |
|   {
 | |
|     fprintf(stderr, "socket shutdown failed (%d)\n", rc);
 | |
|     goto EXIT_LABEL;
 | |
|   }
 | |
| 
 | |
|   // Create a session and start the handshake using the fuzz data passed in.
 | |
|   session = libssh2_session_init();
 | |
|   if(session) {
 | |
|     libssh2_session_set_blocking(session, 1);
 | |
|   }
 | |
|   else {
 | |
|     goto EXIT_LABEL;
 | |
|   }
 | |
| 
 | |
|   if(libssh2_session_handshake(session, socket_fds[0])) {
 | |
|     goto EXIT_LABEL;
 | |
|   }
 | |
| 
 | |
|   // If we get here the handshake actually completed.
 | |
|   handshake_completed = 1;
 | |
| 
 | |
| EXIT_LABEL:
 | |
| 
 | |
|   if(session)
 | |
|   {
 | |
|     if(handshake_completed)
 | |
|     {
 | |
|       libssh2_session_disconnect(session,
 | |
|                                  "Normal Shutdown, Thank you for playing");
 | |
|     }
 | |
| 
 | |
|     libssh2_session_free(session);
 | |
|   }
 | |
| 
 | |
|   libssh2_exit();
 | |
| 
 | |
|   close(socket_fds[0]);
 | |
|   close(socket_fds[1]);
 | |
| 
 | |
|   return 0;
 | |
| }
 |