mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	glaring wrapfd problems fixed
--HG-- branch : fuzz
This commit is contained in:
		
							parent
							
								
									fdc6f32392
								
							
						
					
					
						commit
						c169423051
					
				@ -88,6 +88,10 @@ void chancleanup() {
 | 
			
		||||
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	if (!ses.channels) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TRACE(("enter chancleanup"))
 | 
			
		||||
	for (i = 0; i < ses.chansize; i++) {
 | 
			
		||||
		if (ses.channels[i] != NULL) {
 | 
			
		||||
 | 
			
		||||
@ -403,6 +403,7 @@ static void gen_new_zstream_recv() {
 | 
			
		||||
		ses.newkeys->recv.zstream->zfree = Z_NULL;
 | 
			
		||||
		
 | 
			
		||||
		if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
 | 
			
		||||
			m_free(ses.newkeys->recv.zstream);
 | 
			
		||||
			dropbear_exit("zlib error");
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
@ -82,14 +82,18 @@ void common_session_init(int sock_in, int sock_out) {
 | 
			
		||||
	ses.last_packet_time_any_sent = 0;
 | 
			
		||||
	ses.last_packet_time_keepalive_sent = 0;
 | 
			
		||||
	
 | 
			
		||||
	if (pipe(ses.signal_pipe) < 0) {
 | 
			
		||||
		dropbear_exit("Signal pipe failed");
 | 
			
		||||
#ifdef DROPBEAR_FUZZ
 | 
			
		||||
	if (!fuzz.fuzzing)
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		if (pipe(ses.signal_pipe) < 0) {
 | 
			
		||||
			dropbear_exit("Signal pipe failed");
 | 
			
		||||
		}
 | 
			
		||||
		setnonblocking(ses.signal_pipe[0]);
 | 
			
		||||
		setnonblocking(ses.signal_pipe[1]);
 | 
			
		||||
		ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]);
 | 
			
		||||
		ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]);
 | 
			
		||||
	}
 | 
			
		||||
	setnonblocking(ses.signal_pipe[0]);
 | 
			
		||||
	setnonblocking(ses.signal_pipe[1]);
 | 
			
		||||
 | 
			
		||||
	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]);
 | 
			
		||||
	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]);
 | 
			
		||||
	
 | 
			
		||||
	ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN);
 | 
			
		||||
	ses.transseq = 0;
 | 
			
		||||
@ -311,6 +315,16 @@ void session_cleanup() {
 | 
			
		||||
		buf_free(dequeue(&ses.writequeue));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_free(ses.newkeys);
 | 
			
		||||
#ifndef DISABLE_ZLIB
 | 
			
		||||
	if (ses.keys->recv.zstream != NULL) {
 | 
			
		||||
		if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
 | 
			
		||||
			dropbear_exit("Crypto error");
 | 
			
		||||
		}
 | 
			
		||||
		m_free(ses.keys->recv.zstream);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	m_free(ses.remoteident);
 | 
			
		||||
	m_free(ses.authstate.pw_dir);
 | 
			
		||||
	m_free(ses.authstate.pw_name);
 | 
			
		||||
 | 
			
		||||
@ -181,7 +181,8 @@ static void write_urandom()
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void seedfuzz(void) {
 | 
			
		||||
#ifdef DROPBEAR_FUZZ
 | 
			
		||||
void seedfuzz(void) {
 | 
			
		||||
	hash_state hs;
 | 
			
		||||
	sha1_init(&hs);
 | 
			
		||||
	sha1_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz"));
 | 
			
		||||
@ -190,6 +191,7 @@ static void seedfuzz(void) {
 | 
			
		||||
	counter = 0;
 | 
			
		||||
	donerandinit = 1;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Initialise the prng from /dev/urandom or prngd. This function can
 | 
			
		||||
 * be called multiple times */
 | 
			
		||||
@ -203,7 +205,6 @@ void seedrandom() {
 | 
			
		||||
 | 
			
		||||
#ifdef DROPBEAR_FUZZ
 | 
			
		||||
	if (fuzz.fuzzing || fuzz.recordf) {
 | 
			
		||||
		seedfuzz();
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								dbutil.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								dbutil.c
									
									
									
									
									
								
							@ -569,7 +569,16 @@ void setnonblocking(int fd) {
 | 
			
		||||
			 * can't be set to non-blocking */
 | 
			
		||||
			TRACE(("ignoring ENODEV for setnonblocking"))
 | 
			
		||||
		} else {
 | 
			
		||||
			dropbear_exit("Couldn't set nonblocking");
 | 
			
		||||
#ifdef DROPBEAR_FUZZ
 | 
			
		||||
			if (fuzz.fuzzing) 
 | 
			
		||||
			{
 | 
			
		||||
				TRACE(("fuzzing ignore setnonblocking failure for %d", fd))
 | 
			
		||||
			} 
 | 
			
		||||
			else 
 | 
			
		||||
#endif
 | 
			
		||||
			{
 | 
			
		||||
				dropbear_exit("Couldn't set nonblocking");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	TRACE(("leave setnonblocking"))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								debug.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								debug.h
									
									
									
									
									
								
							@ -64,6 +64,7 @@
 | 
			
		||||
 | 
			
		||||
/* you don't need to touch this block */
 | 
			
		||||
#if DEBUG_TRACE
 | 
			
		||||
extern int debug_trace;
 | 
			
		||||
#define TRACE(X) dropbear_trace X;
 | 
			
		||||
#define TRACE2(X) dropbear_trace2 X;
 | 
			
		||||
#else /*DEBUG_TRACE*/
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,9 @@ int fuzzer_set_input(const uint8_t *Data, size_t Size) {
 | 
			
		||||
    fuzz.input->len = Size;
 | 
			
		||||
    fuzz.input->pos = 0;
 | 
			
		||||
 | 
			
		||||
    memset(&ses, 0x0, sizeof(ses));
 | 
			
		||||
    memset(&svr_ses, 0x0, sizeof(svr_ses));
 | 
			
		||||
 | 
			
		||||
    // get prefix. input format is
 | 
			
		||||
    // string prefix
 | 
			
		||||
    //     uint32 wrapfd seed
 | 
			
		||||
@ -44,7 +47,7 @@ int fuzzer_set_input(const uint8_t *Data, size_t Size) {
 | 
			
		||||
    uint32_t wrapseed = buf_getint(fuzz.input);
 | 
			
		||||
    wrapfd_setup(wrapseed);
 | 
			
		||||
 | 
			
		||||
    seedrandom();
 | 
			
		||||
    seedfuzz();
 | 
			
		||||
 | 
			
		||||
    return DROPBEAR_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,9 @@ int main(int argc, char ** argv) {
 | 
			
		||||
        buf_readfile(input, fn);
 | 
			
		||||
        buf_setpos(input, 0);
 | 
			
		||||
 | 
			
		||||
        printf("Running %s\n", fn);
 | 
			
		||||
        printf("Running %s once \n", fn);
 | 
			
		||||
        LLVMFuzzerTestOneInput(input->data, input->len);
 | 
			
		||||
        printf("Running %s twice \n", fn);
 | 
			
		||||
        LLVMFuzzerTestOneInput(input->data, input->len);
 | 
			
		||||
        printf("Done %s\n", fn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,8 @@ static const double CHANCE_WRITE2 = 0.3;
 | 
			
		||||
struct fdwrap {
 | 
			
		||||
	enum wrapfd_mode mode;
 | 
			
		||||
	buffer *buf;
 | 
			
		||||
	int closein;
 | 
			
		||||
	int closeout;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
 | 
			
		||||
@ -28,21 +30,25 @@ void wrapfd_setup(uint32_t seed) {
 | 
			
		||||
	TRACE(("wrapfd_setup %x", seed))
 | 
			
		||||
	nused = 0;
 | 
			
		||||
	memset(wrap_fds, 0x0, sizeof(wrap_fds));
 | 
			
		||||
	memset(wrap_used, 0x0, sizeof(wrap_used));
 | 
			
		||||
 | 
			
		||||
	memset(rand_state, 0x0, sizeof(rand_state));
 | 
			
		||||
	*((uint32_t*)rand_state) = seed;
 | 
			
		||||
	nrand48(rand_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) {
 | 
			
		||||
	TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode))
 | 
			
		||||
	assert(fd >= 0);
 | 
			
		||||
	assert(fd <= IOWRAP_MAXFD);
 | 
			
		||||
	assert(wrap_fds[fd].mode == UNUSED);
 | 
			
		||||
	assert(buf || mode == RANDOMIN);
 | 
			
		||||
 | 
			
		||||
	TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode))
 | 
			
		||||
 | 
			
		||||
	wrap_fds[fd].mode = mode;
 | 
			
		||||
	wrap_fds[fd].buf = buf;
 | 
			
		||||
	wrap_fds[fd].closein = 0;
 | 
			
		||||
	wrap_fds[fd].closeout = 0;
 | 
			
		||||
	wrap_used[nused] = fd;
 | 
			
		||||
 | 
			
		||||
	nused++;
 | 
			
		||||
@ -50,12 +56,12 @@ void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) {
 | 
			
		||||
 | 
			
		||||
void wrapfd_remove(int fd) {
 | 
			
		||||
	unsigned int i, j;
 | 
			
		||||
	TRACE(("wrapfd_remove %d", fd))
 | 
			
		||||
	assert(fd >= 0);
 | 
			
		||||
	assert(fd <= IOWRAP_MAXFD);
 | 
			
		||||
	assert(wrap_fds[fd].mode != UNUSED);
 | 
			
		||||
	wrap_fds[fd].mode = UNUSED;
 | 
			
		||||
 | 
			
		||||
	TRACE(("wrapfd_remove %d", fd))
 | 
			
		||||
 | 
			
		||||
	// remove from used list
 | 
			
		||||
	for (i = 0, j = 0; i < nused; i++) {
 | 
			
		||||
@ -67,6 +73,9 @@ void wrapfd_remove(int fd) {
 | 
			
		||||
	nused--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wrapfd_close(int fd) {
 | 
			
		||||
	wrapfd_remove(fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int wrapfd_read(int fd, void *out, size_t count) {
 | 
			
		||||
	size_t maxread;
 | 
			
		||||
@ -85,9 +94,10 @@ int wrapfd_read(int fd, void *out, size_t count) {
 | 
			
		||||
 | 
			
		||||
	assert(count != 0);
 | 
			
		||||
 | 
			
		||||
	if (erand48(rand_state) < CHANCE_CLOSE) {
 | 
			
		||||
		wrapfd_remove(fd);
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (wrap_fds[fd].closein || erand48(rand_state) < CHANCE_CLOSE) {
 | 
			
		||||
		wrap_fds[fd].closein = 1;
 | 
			
		||||
		errno = ECONNRESET;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (erand48(rand_state) < CHANCE_INTR) {
 | 
			
		||||
@ -135,9 +145,10 @@ int wrapfd_write(int fd, const void* in, size_t count) {
 | 
			
		||||
		(void)volin[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (erand48(rand_state) < CHANCE_CLOSE) {
 | 
			
		||||
		wrapfd_remove(fd);
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (wrap_fds[fd].closeout || erand48(rand_state) < CHANCE_CLOSE) {
 | 
			
		||||
		wrap_fds[fd].closeout = 1;
 | 
			
		||||
		errno = ECONNRESET;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (erand48(rand_state) < CHANCE_INTR) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								fuzz.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								fuzz.h
									
									
									
									
									
								
							@ -23,6 +23,7 @@ void fuzz_kex_fakealgos(void);
 | 
			
		||||
        wrapfd_select(nfds, readfds, writefds, exceptfds, timeout)
 | 
			
		||||
#define write(fd, buf, count) wrapfd_write(fd, buf, count)
 | 
			
		||||
#define read(fd, buf, count) wrapfd_read(fd, buf, count)
 | 
			
		||||
#define close(fd) wrapfd_close(fd)
 | 
			
		||||
#endif // FUZZ_SKIP_WRAP
 | 
			
		||||
 | 
			
		||||
struct dropbear_fuzz_options {
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,11 @@
 | 
			
		||||
#include "dbrandom.h"
 | 
			
		||||
#include "session.h"
 | 
			
		||||
#include "fuzz-wrapfd.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
static void setup_fuzzer(void) {
 | 
			
		||||
	svr_setup_fuzzer();
 | 
			
		||||
	//debug_trace = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
 | 
			
		||||
 | 
			
		||||
@ -245,7 +245,9 @@ void svr_dropbear_log(int priority, const char* format, va_list param) {
 | 
			
		||||
static void svr_remoteclosed() {
 | 
			
		||||
 | 
			
		||||
	m_close(ses.sock_in);
 | 
			
		||||
	m_close(ses.sock_out);
 | 
			
		||||
	if (ses.sock_in != ses.sock_out) {
 | 
			
		||||
		m_close(ses.sock_out);
 | 
			
		||||
	}
 | 
			
		||||
	ses.sock_in = -1;
 | 
			
		||||
	ses.sock_out = -1;
 | 
			
		||||
	dropbear_close("Exited normally");
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user