Skip to content

Commit f8f86f6

Browse files
committed
Add some checks on allocated memory with errors
1 parent 8039f3d commit f8f86f6

File tree

8 files changed

+99
-23
lines changed

8 files changed

+99
-23
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ static void on_data(ev_tcp_handle *client) {
9898

9999
static void on_connection(ev_tcp_handle *server) {
100100
ev_tcp_handle *client = malloc(sizeof(*client));
101+
if (!client) {
102+
fprintf(stderr, "On connection failed: Out of memory");
103+
exit(EXIT_FAILURE);
104+
}
101105
int err = ev_tcp_server_accept(server, client, on_data, on_write);
102106
if (err < 0)
103107
free(client);
@@ -109,7 +113,11 @@ int main(void) {
109113

110114
ev_context *ctx = ev_get_ev_context();
111115
ev_tcp_server server;
112-
ev_tcp_server_init(&server, ctx, 128);
116+
int err = 0;
117+
if ((err = ev_tcp_server_init(&server, ctx, 128)) < 0) {
118+
fprintf(stderr, "ev_tcp_server_init failed: %s", ev_tcp_err(err));
119+
exit(EXIT_FAILURE);
120+
}
113121
// To set TLS using OpenSSL
114122
// struct ev_tls_options tls_opt = {
115123
// .ca = CA,

ev.h

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
* Return codes */
118118
#define EV_OK 0
119119
#define EV_ERR -1
120+
#define EV_OOM -2
120121

121122
/*
122123
* Event types, meant to be OR-ed on a bitmask to define the type of an event
@@ -180,7 +181,7 @@ struct ev {
180181
* The first thing done is the initialization of the api pointer according to
181182
* the Mux IO backend found on the host machine
182183
*/
183-
void ev_init(ev_context *, int);
184+
int ev_init(ev_context *, int);
184185

185186
/*
186187
* Just check if the ev_context is running, return 0 if it's not running, 1
@@ -322,12 +323,15 @@ static int epoll_del(int efd, int fd) {
322323
return epoll_ctl(efd, EPOLL_CTL_DEL, fd, NULL);
323324
}
324325

325-
static void ev_api_init(ev_context *ctx, int events_nr) {
326+
static int ev_api_init(ev_context *ctx, int events_nr) {
326327
struct epoll_api *e_api = malloc(sizeof(*e_api));
328+
if (!e_api)
329+
return EV_OOM;
327330
e_api->fd = epoll_create1(0);
328331
e_api->events = calloc(events_nr, sizeof(struct epoll_event));
329332
ctx->api = e_api;
330333
ctx->maxfd = events_nr;
334+
return EV_OK;
331335
}
332336

333337
static void ev_api_destroy(ev_context *ctx) {
@@ -417,13 +421,16 @@ struct poll_api {
417421
struct pollfd *fds;
418422
};
419423

420-
static void ev_api_init(ev_context *ctx, int events_nr) {
424+
static int ev_api_init(ev_context *ctx, int events_nr) {
421425
struct poll_api *p_api = malloc(sizeof(*p_api));
426+
if (!p_api)
427+
return EV_OOM;
422428
p_api->nfds = 0;
423429
p_api->fds = calloc(events_nr, sizeof(struct pollfd));
424430
p_api->events_monitored = events_nr;
425431
ctx->api = p_api;
426432
ctx->maxfd = events_nr;
433+
return EV_OK;
427434
}
428435

429436
static void ev_api_destroy(ev_context *ctx) {
@@ -550,17 +557,20 @@ struct select_api {
550557
fd_set _rfds, _wfds;
551558
};
552559

553-
static void ev_api_init(ev_context *ctx, int events_nr) {
560+
static int ev_api_init(ev_context *ctx, int events_nr) {
554561
/*
555562
* fd_set is an array of 32 i32 and each FD is represented by a bit so
556563
* 32 x 32 = 1024 as hard limit
557564
*/
558565
assert(events_nr <= SELECT_FDS_HARDCAP);
559566
struct select_api *s_api = malloc(sizeof(*s_api));
567+
if (!s_api)
568+
return EV_OOM;
560569
FD_ZERO(&s_api->rfds);
561570
FD_ZERO(&s_api->wfds);
562571
ctx->api = s_api;
563572
ctx->maxfd = 0;
573+
return EV_OK;
564574
}
565575

566576
static void ev_api_destroy(ev_context *ctx) {
@@ -677,12 +687,15 @@ struct kqueue_api {
677687
struct kevent *events;
678688
};
679689

680-
static void ev_api_init(ev_context *ctx, int events_nr) {
690+
static int ev_api_init(ev_context *ctx, int events_nr) {
681691
struct kqueue_api *k_api = malloc(sizeof(*k_api));
692+
if (!k_api)
693+
return EV_OOM;
682694
k_api->fd = kqueue();
683695
k_api->events = calloc(events_nr, sizeof(struct kevent));
684696
ctx->api = k_api;
685697
ctx->maxfd = events_nr;
698+
return EV_OK;
686699
}
687700

688701
static void ev_api_destroy(ev_context *ctx) {
@@ -891,7 +904,9 @@ ev_context *ev_get_ev_context(void) {
891904
#endif
892905
signal(SIGINT, ev_sigint_handler);
893906
signal(SIGTERM, ev_sigint_handler);
894-
ev_init(&ev_default_ctx, EVENTLOOP_MAX_EVENTS);
907+
int err = ev_init(&ev_default_ctx, EVENTLOOP_MAX_EVENTS);
908+
if (err < EV_OK)
909+
return NULL;
895910
#ifdef __linux__
896911
ev_register_event(&ev_default_ctx, quit_sig,
897912
EV_CLOSEFD | EV_READ, ev_stop_callback, NULL);
@@ -904,14 +919,17 @@ ev_context *ev_get_ev_context(void) {
904919
return &ev_default_ctx;
905920
}
906921

907-
void ev_init(ev_context *ctx, int events_nr) {
908-
ev_api_init(ctx, events_nr);
922+
int ev_init(ev_context *ctx, int events_nr) {
923+
int err = ev_api_init(ctx, events_nr);
924+
if (err < EV_OK)
925+
return err;
909926
ctx->stop = 0;
910927
ctx->fired_events = 0;
911928
ctx->is_running = 0;
912929
ctx->maxevents = events_nr;
913930
ctx->events_nr = events_nr;
914931
ctx->events_monitored = calloc(events_nr, sizeof(struct ev));
932+
return EV_OK;
915933
}
916934

917935
int ev_is_running(const ev_context *ctx) {

ev_tcp.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#define EV_TCP_FAILURE -1
6363
#define EV_TCP_MISSING_CALLBACK -2
6464
#define EV_TCP_MISSING_CONTEXT -3
65+
#define EV_TCP_OUT_OF_MEMORY -4
6566

6667
/*
6768
* Default buffer size for connecting client, can be changed on the host
@@ -335,7 +336,7 @@ static inline int set_nonblocking(int fd) {
335336
if (result == -1)
336337
goto err;
337338

338-
return EV_OK;
339+
return EV_TCP_SUCCESS;
339340

340341
err:
341342

@@ -415,6 +416,8 @@ static void ev_server_on_stop(ev_context *ctx, void *data) {
415416

416417
static ev_connection *ev_connection_new(int fd) {
417418
ev_connection *conn = malloc(sizeof(*conn));
419+
if (!conn)
420+
return NULL;
418421
conn->fd = fd;
419422
conn->on_conn = NULL;
420423
conn->on_recv = NULL;
@@ -448,16 +451,21 @@ static void ev_buf_init(ev_buf *buf, size_t capacity) {
448451
/*
449452
* init a fresh new tcp_handle which can be used as a server or a client
450453
*/
451-
static void ev_tcp_handle_init(ev_tcp_handle *handle, int fd) {
454+
static int ev_tcp_handle_init(ev_tcp_handle *handle, int fd) {
452455
handle->c = ev_connection_new(fd);
456+
if (!handle->c)
457+
return EV_TCP_OUT_OF_MEMORY;
453458
ev_buf_init(&handle->buffer, EV_TCP_BUFSIZE);
454459
handle->to_read = handle->to_write = 0;
460+
return EV_TCP_SUCCESS;
455461
}
456462

457463
#ifdef HAVE_OPENSSL
458464

459465
static ev_connection *ev_tls_connection_new(int fd, SSL *ssl) {
460466
ev_tls_connection *conn = malloc(sizeof(*conn));
467+
if (!conn)
468+
return NULL;
461469
conn->c.fd = fd;
462470
conn->ssl = ssl;
463471
conn->c.on_conn = NULL;
@@ -569,11 +577,14 @@ static SSL *ssl_accept(SSL_CTX *ctx, int fd) {
569577
return ssl;
570578
}
571579

572-
static void ev_tls_tcp_handle_init(ev_tcp_handle *handle, int fd, SSL *ssl) {
580+
static int ev_tls_tcp_handle_init(ev_tcp_handle *handle, int fd, SSL *ssl) {
573581
handle->c = ev_tls_connection_new(fd, ssl);
582+
if (!handle->c)
583+
return EV_TCP_OUT_OF_MEMORY;
574584
ev_buf_init(&handle->buffer, EV_TCP_BUFSIZE);
575585
handle->ssl = 1;
576586
handle->to_read = handle->to_write = 0;
587+
return EV_TCP_SUCCESS;
577588
}
578589

579590
#endif // HAVE_OPENSSL
@@ -600,7 +611,9 @@ int ev_tcp_server_init(ev_tcp_server *server, ev_context *ctx, int backlog) {
600611
EV_CLOSEFD|EV_READ, ev_server_on_stop, NULL);
601612
#endif
602613
server->handle.c = ev_connection_new(-1);
603-
return EV_OK;
614+
if (!server->handle.c)
615+
return EV_TCP_OUT_OF_MEMORY;
616+
return EV_TCP_SUCCESS;
604617
}
605618

606619
int ev_tcp_server_listen_unix(ev_tcp_server *server, const char *socketpath,
@@ -752,10 +765,13 @@ int ev_tcp_server_accept(ev_tcp_handle *server, ev_tcp_handle *client,
752765
// XXX placeholder
753766
#ifdef HAVE_OPENSSL
754767
if (server->ssl == 1) {
755-
ev_tls_tcp_handle_init(client, fd, ssl_accept(server->ssl_ctx, fd));
768+
if (ev_tls_tcp_handle_init(client, fd,
769+
ssl_accept(server->ssl_ctx, fd)) < 0)
770+
return EV_TCP_OUT_OF_MEMORY;
756771
} else {
757772
#endif
758-
ev_tcp_handle_init(client, fd);
773+
if (ev_tcp_handle_init(client, fd) < 0)
774+
return EV_TCP_OUT_OF_MEMORY;
759775
#ifdef HAVE_OPENSSL
760776
}
761777
#endif
@@ -966,6 +982,8 @@ const char *ev_tcp_err(int rc) {
966982
return "Failure";
967983
case EV_TCP_MISSING_CALLBACK:
968984
return "Missing callback";
985+
case EV_TCP_OUT_OF_MEMORY:
986+
return "Out of memory";
969987
default:
970988
return "Unknown error";
971989
}

examples/echo_server.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,11 @@ int main(void) {
210210
if (listen(listen_fd, 32) != 0)
211211
goto err;
212212

213-
ev_init(&ctx, 32);
213+
int err = ev_init(&ctx, 32);
214+
if (err < EV_OK) {
215+
fprintf(stderr, "Ev context init failed: Out of memory");
216+
exit(EXIT_FAILURE);
217+
}
214218

215219
/* Register a callback on the listening socket for incoming connections */
216220
ev_register_event(&ctx, listen_fd, EV_READ, on_connection, &listen_fd);

examples/ev_tcp_server.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ static void on_data(ev_tcp_handle *client) {
3333
static void on_connection(ev_tcp_handle *server) {
3434
int err = 0;
3535
ev_tcp_handle *client = malloc(sizeof(*client));
36+
if (!client) {
37+
fprintf(stderr, "On connection failed: Out of memory");
38+
exit(EXIT_FAILURE);
39+
}
3640
if ((err = ev_tcp_server_accept(server, client, on_data, on_write)) < 0) {
3741
if (err == -1)
3842
fprintf(stderr, "Error occured: %s\n", strerror(errno));
@@ -49,8 +53,12 @@ int main(void) {
4953

5054
ev_context *ctx = ev_get_ev_context();
5155
ev_tcp_server server;
52-
ev_tcp_server_init(&server, ctx, BACKLOG);
53-
int err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
56+
int err = 0;
57+
if ((err = ev_tcp_server_init(&server, ctx, BACKLOG)) < 0) {
58+
fprintf(stderr, "ev_tcp_server_init failed: %s", ev_tcp_err(err));
59+
exit(EXIT_FAILURE);
60+
}
61+
err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
5462
if (err < 0) {
5563
if (err == -1)
5664
fprintf(stderr, "Error occured: %s\n", strerror(errno));

examples/ev_tcp_server_stats.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ static void on_data(ev_tcp_handle *client) {
3636
static void on_connection(ev_tcp_handle *server) {
3737
int err = 0;
3838
ev_tcp_handle *client = malloc(sizeof(*client));
39+
if (!client) {
40+
fprintf(stderr, "On connection failed: Out of memory");
41+
exit(EXIT_FAILURE);
42+
}
3943
if ((err = ev_tcp_server_accept(server, client, on_data, NULL)) < 0) {
4044
if (err == -1)
4145
fprintf(stderr, "Error occured: %s\n", strerror(errno));
@@ -54,8 +58,12 @@ int main(void) {
5458
ev_context *ctx = ev_get_ev_context();
5559
ev_register_cron(ctx, print_stats, NULL, STATS_PERIOD, 0);
5660
ev_tcp_server server;
57-
ev_tcp_server_init(&server, ctx, BACKLOG);
58-
int err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
61+
int err = 0;
62+
if ((err = ev_tcp_server_init(&server, ctx, BACKLOG)) < 0) {
63+
fprintf(stderr, "ev_tcp_server_init failed: %s", ev_tcp_err(err));
64+
exit(EXIT_FAILURE);
65+
}
66+
err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
5967
if (err < 0) {
6068
if (err == -1)
6169
fprintf(stderr, "Error occured: %s\n", strerror(errno));

examples/ev_tls_tcp_server.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ static void on_data(ev_tcp_handle *client) {
3131
static void on_connection(ev_tcp_handle *server) {
3232
int err = 0;
3333
ev_tcp_handle *client = malloc(sizeof(*client));
34+
if (!client) {
35+
fprintf(stderr, "On connection failed: Out of memory");
36+
exit(EXIT_FAILURE);
37+
}
3438
if ((err = ev_tcp_server_accept(server, client, on_data, NULL)) < 0) {
3539
if (err == -1)
3640
fprintf(stderr, "Something went wrong %s\n", strerror(errno));
@@ -52,9 +56,13 @@ int main(void) {
5256
.key = KEY
5357
};
5458
tls_opt.protocols = EV_TLSvAll;
55-
ev_tcp_server_init(&server, ctx, BACKLOG);
59+
int err = 0;
60+
if ((err = ev_tcp_server_init(&server, ctx, BACKLOG)) < 0) {
61+
fprintf(stderr, "ev_tcp_server_init failed: %s", ev_tcp_err(err));
62+
exit(EXIT_FAILURE);
63+
}
5664
ev_tcp_server_set_tls(&server, &tls_opt);
57-
int err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
65+
err = ev_tcp_server_listen(&server, HOST, PORT, on_connection);
5866
if (err < 0) {
5967
if (err == -1)
6068
fprintf(stderr, "Something went wrong %s\n", strerror(errno));

examples/ping_pong.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ static void pong(ev_context *ctx, void *data) {
1919

2020
int main(void) {
2121
ev_context ctx;
22-
ev_init(&ctx, 32);
22+
int err = ev_init(&ctx, 32);
23+
if (err < EV_OK) {
24+
fprintf(stderr, "Ev context init failed: Out of memory");
25+
exit(EXIT_FAILURE);
26+
}
2327
ev_register_cron(&ctx, ping, NULL, PING_SECONDS, 0);
2428
ev_register_cron(&ctx, pong, NULL, PONG_SECONDS, 0);
2529
ev_run(&ctx);

0 commit comments

Comments
 (0)