Skip to content

Commit

Permalink
lib: monkey: merge scheduler and lib mode fixes
Browse files Browse the repository at this point in the history
 3d6fc3fe doc: add Fuzzing instructions
 7b9a4725 server: scheduler: mark unused variable
 8cbd5cb0 server: http parser: fix index condition to avoid access invalid address
 8fa3b7a3 server: scheduler: destroy threads upon drop connection
 c903a612 lib: on http done, do not remove the session
 1981f224 mk_server: http: do not force threads destroy
 ffac9e02 fuzz: mk_check: cleanup service code

Signed-off-by: Eduardo Silva <[email protected]>
  • Loading branch information
edsiper committed Apr 16, 2018
1 parent 3eb0f17 commit 37429ee
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 20 deletions.
33 changes: 33 additions & 0 deletions lib/monkey/FUZZ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Fuzz Monkey

## Prepare and Build

Set the compiler path:

```
$ export CC=PATH/TO/honggfuzz/hfuzz_cc/hfuzz-clang
```

Build Monkey Fuzz tool with the following options:

```
$ cd build/
$ cmake -DMK_LOCAL=On -DMK_DEBUG=On \
-DMK_LIB_ONLY=On -DMK_SYSTEM_MALLOC=On \
-DMK_FUZZ_MODE=On ../
$ make
```

the build process will generate two executables:

- mk_fuzz_me: to be used with honggfuzz for the Fuzzing process
- mk_check: used to validate a crash/fix

## Run HonggFuzz with mk-fuzz-me

Fuzz Monkey using Apache corpus and wordlist:

```
$ cd /path/to/honggfuzz/examples/apache-httpd/
$ honggfuzz -Q --logfile out.log -f corpus_http1 -w ./httpd.wordlist -- /path/to/mk-fuzz-me
```
11 changes: 11 additions & 0 deletions lib/monkey/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
set(src
mk_fuzz_me.c)

add_executable(mk_fuzz_me ${src})
target_link_libraries(mk_fuzz_me monkey-core-static)

set(src
mk_check.c)

add_executable(mk_check ${src})
target_link_libraries(mk_check monkey-core-static)
113 changes: 113 additions & 0 deletions lib/monkey/fuzz/mk_check.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#include <monkey/mk_lib.h>

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#define API_ADDR "127.0.0.1"
#define API_PORT "8080"

/* Main context set as global so the signal handler can use it */
mk_ctx_t *ctx;

void cb_main(mk_request_t *request, void *data)
{
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);

mk_http_send(request, ":)\n", 3, NULL);
mk_http_done(request);
}

void cb_test_chunks(mk_request_t *request, void *data)
{
int i = 0;
int len;
char tmp[32];
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);

for (i = 0; i < 1000; i++) {
len = snprintf(tmp, sizeof(tmp) -1, "test-chunk %6i\n ", i);
mk_http_send(request, tmp, len, NULL);
}
mk_http_done(request);
}

void cb_test_big_chunk(mk_request_t *request, void *data)
{
size_t chunk_size = 1024000000;
char *chunk;
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);

chunk = calloc(1, chunk_size);
mk_http_send(request, chunk, chunk_size, NULL);
free(chunk);
mk_http_done(request);
}


static void signal_handler(int signal)
{
write(STDERR_FILENO, "[engine] caught signal\n", 23);

switch (signal) {
case SIGTERM:
case SIGINT:
mk_stop(ctx);
mk_destroy(ctx);
_exit(EXIT_SUCCESS);
default:
break;
}
}

static void signal_init()
{
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
}

int main()
{
int vid;

signal_init();

ctx = mk_create();
if (!ctx) {
return -1;
}

mk_config_set(ctx,
"Listen", API_PORT,
NULL);

vid = mk_vhost_create(ctx, NULL);
mk_vhost_set(ctx, vid,
"Name", "monotop",
NULL);
mk_vhost_handler(ctx, vid, "/test_chunks", cb_test_chunks, NULL);
mk_vhost_handler(ctx, vid, "/test_big_chunk", cb_test_big_chunk, NULL);
mk_vhost_handler(ctx, vid, "/", cb_main, NULL);

mk_info("Service: http:https://%s:%s/test_chunks", API_ADDR, API_PORT);
mk_start(ctx);

sleep(3600);

mk_stop(ctx);
mk_destroy(ctx);

return 0;
}
143 changes: 143 additions & 0 deletions lib/monkey/fuzz/mk_fuzz_me.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#include <monkey/mk_lib.h>

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#define API_ADDR "127.0.0.1"
#define API_PORT "8080"

/* Main context set as global so the signal handler can use it */
mk_ctx_t *ctx;

void cb_main(mk_request_t *request, void *data)
{
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);
mk_http_send(request, ":)\n", 3, NULL);
mk_http_done(request);
}

void cb_test_chunks(mk_request_t *request, void *data)
{
int i = 0;
int len;
char tmp[32];
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);

for (i = 0; i < 1000; i++) {
len = snprintf(tmp, sizeof(tmp) -1, "test-chunk %6i\n ", i);
mk_http_send(request, tmp, len, NULL);
}
mk_http_done(request);
}

void cb_test_big_chunk(mk_request_t *request, void *data)
{
size_t chunk_size = 1024000000;
char *chunk;
(void) data;

mk_http_status(request, 200);
mk_http_header(request, "X-Monkey", 8, "OK", 2);

chunk = calloc(1, chunk_size);
mk_http_send(request, chunk, chunk_size, NULL);
free(chunk);
mk_http_done(request);
}


static void signal_handler(int signal)
{
write(STDERR_FILENO, "[engine] caught signal\n", 23);

switch (signal) {
case SIGTERM:
case SIGINT:
mk_stop(ctx);
mk_destroy(ctx);
_exit(EXIT_SUCCESS);
default:
break;
}
}

static void signal_init()
{
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
}

static void cb_queue_message(mk_mq_t *queue, void *data, size_t size, void *ctx)
{
size_t i;
char *buf;
(void) ctx;
(void) queue;

printf("=== cb queue message === \n");
printf(" => %lu bytes\n", size);
printf(" => ");

buf = data;
for (i = 0; i < size; i++) {
printf("%c", buf[i]);
}
printf("\n\n");
}


HFND_FUZZING_ENTRY_FUNCTION(int argc, const char *const *argv)
{
int i = 0;
int len;
int vid;
int qid;
char msg[800000];

signal_init();

ctx = mk_create();
if (!ctx) {
return -1;
}

/* Create a message queue and a callback for each message */
qid = mk_mq_create(ctx, "/data", cb_queue_message, NULL);

mk_config_set(ctx,
"Listen", API_PORT,
NULL);

vid = mk_vhost_create(ctx, NULL);
mk_vhost_set(ctx, vid,
"Name", "monotop",
NULL);
mk_vhost_handler(ctx, vid, "/test_chunks", cb_test_chunks, NULL);
mk_vhost_handler(ctx, vid, "/test_big_chunk", cb_test_big_chunk, NULL);
mk_vhost_handler(ctx, vid, "/", cb_main, NULL);

mk_info("Service: http:https://%s:%s/test_chunks", API_ADDR, API_PORT);
mk_start(ctx);

for (i = 0; i < 5; i++) {
len = snprintf(msg, sizeof(msg) - 1, "[...] message ID: %i\n", i);
mk_mq_send(ctx, qid, &msg, len);
}

sleep(3600);

mk_stop(ctx);
mk_destroy(ctx);

return 0;
}
20 changes: 9 additions & 11 deletions lib/monkey/mk_server/mk_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ void mk_http_request_init(struct mk_http_session *session,
request->real_path.data = NULL;
request->handler_data = NULL;

request->in_file.fd = -1;

/* Response Headers */
mk_header_response_reset(&request->headers);

Expand Down Expand Up @@ -715,7 +717,6 @@ int mk_http_init(struct mk_http_session *cs, struct mk_http_request *sr,
sr->method != MK_METHOD_PUT)) {
sr->_content_length.data = NULL;
sr->_content_length.len = 0;
//return mk_http_error(MK_CLIENT_BAD_REQUEST, cs, sr, server);
}

ret_file = mk_file_get_info(sr->real_path.data, &sr->file_info, MK_FILE_READ);
Expand All @@ -734,6 +735,7 @@ int mk_http_init(struct mk_http_session *cs, struct mk_http_request *sr,
handlers = &sr->host_conf->handlers;
mk_list_foreach(head, handlers) {
h_handler = mk_list_entry(head, struct mk_vhost_handler, _head);

if (regexec(h_handler->match,
sr->uri_processed.data, 0, NULL, 0) != 0) {
continue;
Expand Down Expand Up @@ -1379,10 +1381,6 @@ void mk_http_session_remove(struct mk_http_session *cs,
mk_list_del(&cs->request_list);

cs->_sched_init = MK_FALSE;

/* Remove any pending thread context */
struct mk_sched_worker *sched = mk_sched_get_thread_conf();
mk_sched_threads_destroy_all(sched);
}

/* FIXME: nobody is using this */
Expand Down Expand Up @@ -1608,15 +1606,15 @@ int mk_http_sched_done(struct mk_sched_conn *conn,
struct mk_server *server)
{
(void) worker;
struct mk_http_session *cs;
struct mk_http_session *session;
struct mk_http_request *sr;

cs = mk_http_session_get(conn);
sr = mk_list_entry_first(&cs->request_list, struct mk_http_request, _head);

mk_plugin_stage_run_40(cs, sr, server);
session = mk_http_session_get(conn);
sr = mk_list_entry_first(&session->request_list,
struct mk_http_request, _head);
mk_plugin_stage_run_40(session, sr, server);

return mk_http_request_end(cs, server);
return mk_http_request_end(session, server);
}

struct mk_sched_handler mk_http_handler = {
Expand Down
5 changes: 1 addition & 4 deletions lib/monkey/mk_server/mk_http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,8 @@ static inline int header_lookup(struct mk_http_parser *p, char *buffer)
struct row_entry *h;

len = (p->header_sep - p->header_key);

for (i = p->header_min; i <= p->header_max; i++) {
for (i = p->header_min; i <= p->header_max && i >= 0; i++) {
h = &mk_headers_table[i];

/* Check string length first */
if (h->len != len) {
continue;
Expand Down Expand Up @@ -381,7 +379,6 @@ int mk_http_parser(struct mk_http_request *req, struct mk_http_parser *p,
int len;

/* lazy test
printf("p->i=%i buf_len=%i\n",
p->i, buf_len);
Expand Down
1 change: 0 additions & 1 deletion lib/monkey/mk_server/mk_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,6 @@ int mk_http_done(mk_request_t *req)

if (req->session->close_now == MK_TRUE) {
mk_lib_yield(req);
mk_http_session_remove(req->session, req->session->server);
}

return 0;
Expand Down
Loading

0 comments on commit 37429ee

Please sign in to comment.