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