Skip to content

Commit 5558233

Browse files
committed
update to facil.io 0.7.3
1 parent 8a816db commit 5558233

File tree

14 files changed

+85
-61
lines changed

14 files changed

+85
-61
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Please notice that this change log contains changes for upcoming releases as wel
66

77
## Changes:
88

9+
#### Change log v.0.7.34
10+
11+
**Security**: (`facil.io`, `http`) updated to facil.io 0.7.3, incorporating it's bug fixes and security updates.
12+
913
#### Change log v.0.7.33
1014

1115
**Fix**: (`iodine`) exception protection would fail and crash if the exception throws wasn't of type `Exception`. I'm not sure how this would happen, but on some Ruby versions it appeared to have occur, maybe where a custom `raise` would be called with a non-exception type. The issue was fixed by testing for the availability of the `message` and `backtrace` functions. Credit to Jan Biedermann (@janbiedermann) for exposing this issue (#76).

ext/iodine/fio.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,12 +1178,13 @@ static inline void fio_mark_time(void) {
11781178
/** Calculates the due time for a task, given it's interval */
11791179
static struct timespec fio_timer_calc_due(size_t interval) {
11801180
struct timespec now = fio_last_tick();
1181-
if (interval > 1000) {
1182-
now.tv_sec += interval / 1000;
1183-
interval -= interval / 1000;
1181+
if (interval >= 1000) {
1182+
unsigned long long secs = interval / 1000;
1183+
now.tv_sec += secs;
1184+
interval -= secs * 1000;
11841185
}
11851186
now.tv_nsec += (interval * 1000000UL);
1186-
if (now.tv_nsec > 1000000000L) {
1187+
if (now.tv_nsec >= 1000000000L) {
11871188
now.tv_nsec -= 1000000000L;
11881189
now.tv_sec += 1;
11891190
}
@@ -1346,7 +1347,7 @@ Section Start Marker
13461347
***************************************************************************** */
13471348

13481349
volatile uint8_t fio_signal_children_flag = 0;
1349-
1350+
volatile fio_lock_i fio_signal_set_flag = 0;
13501351
/* store old signal handlers to propegate signal handling */
13511352
static struct sigaction fio_old_sig_chld;
13521353
static struct sigaction fio_old_sig_pipe;
@@ -1415,15 +1416,15 @@ static void sig_int_handler(int sig) {
14151416
break;
14161417
}
14171418
/* propagate signale handling to previous existing handler (if any) */
1418-
if (old->sa_handler != SIG_IGN && old->sa_handler != SIG_DFL)
1419+
if (old && old->sa_handler != SIG_IGN && old->sa_handler != SIG_DFL)
14191420
old->sa_handler(sig);
14201421
}
14211422

14221423
/* setup handling for the SIGUSR1, SIGPIPE, SIGINT and SIGTERM signals. */
14231424
static void fio_signal_handler_setup(void) {
14241425
/* setup signal handling */
14251426
struct sigaction act;
1426-
if (fio_old_sig_int.sa_handler)
1427+
if (fio_trylock(&fio_signal_set_flag))
14271428
return;
14281429

14291430
memset(&act, 0, sizeof(act));
@@ -1457,8 +1458,9 @@ static void fio_signal_handler_setup(void) {
14571458

14581459
void fio_signal_handler_reset(void) {
14591460
struct sigaction old;
1460-
if (!fio_old_sig_int.sa_handler)
1461+
if (fio_signal_set_flag)
14611462
return;
1463+
fio_unlock(&fio_signal_set_flag);
14621464
memset(&old, 0, sizeof(old));
14631465
sigaction(SIGINT, &fio_old_sig_int, &old);
14641466
sigaction(SIGTERM, &fio_old_sig_term, &old);
@@ -2968,7 +2970,7 @@ ssize_t fio_flush(intptr_t uuid) {
29682970
goto test_errno;
29692971
}
29702972

2971-
if (uuid_data(uuid).packet_count >= 1024 &&
2973+
if (uuid_data(uuid).packet_count >= FIO_SLOWLORIS_LIMIT &&
29722974
uuid_data(uuid).packet == old_packet &&
29732975
uuid_data(uuid).sent >= old_sent &&
29742976
(uuid_data(uuid).sent - old_sent) < 32768) {
@@ -3533,11 +3535,12 @@ static void __attribute__((destructor)) fio_lib_destroy(void) {
35333535
fio_data->active = 0;
35343536
fio_on_fork();
35353537
fio_defer_perform();
3538+
fio_timer_clear_all();
3539+
fio_defer_perform();
35363540
fio_state_callback_force(FIO_CALL_AT_EXIT);
35373541
fio_state_callback_clear_all();
35383542
fio_defer_perform();
35393543
fio_poll_close();
3540-
fio_timer_clear_all();
35413544
fio_free(fio_data);
35423545
/* memory library destruction must be last */
35433546
fio_mem_destroy();
@@ -3811,15 +3814,16 @@ static void fio_worker_cleanup(void) {
38113814
fio_force_close(fd2uuid(i));
38123815
}
38133816
}
3814-
fio_defer_perform();
3815-
fio_state_callback_force(FIO_CALL_ON_FINISH);
3817+
fio_timer_clear_all();
38163818
fio_defer_perform();
38173819
if (!fio_data->is_worker) {
3818-
fio_cluster_signal_children();
3820+
kill(0, SIGINT);
38193821
while (wait(NULL) != -1)
38203822
;
38213823
}
38223824
fio_defer_perform();
3825+
fio_state_callback_force(FIO_CALL_ON_FINISH);
3826+
fio_defer_perform();
38233827
fio_signal_handler_reset();
38243828
if (fio_data->parent == getpid()) {
38253829
FIO_LOG_INFO(" --- Shutdown Complete ---\n");
@@ -5125,7 +5129,7 @@ struct subscription_s {
51255129
void *udata1;
51265130
void *udata2;
51275131
/** reference counter. */
5128-
uintptr_t ref;
5132+
volatile uintptr_t ref;
51295133
/** prevents the callback from running concurrently for multiple messages. */
51305134
fio_lock_i lock;
51315135
fio_lock_i unsubscribed;
@@ -6202,7 +6206,7 @@ static void fio_cluster_listen_on_close(intptr_t uuid,
62026206
(int)getpid());
62036207
#endif
62046208
if (fio_data->active)
6205-
fio_stop();
6209+
kill(0, SIGINT);
62066210
}
62076211
(void)uuid;
62086212
}
@@ -6244,6 +6248,7 @@ static void fio_cluster_client_handler(struct cluster_pr_s *pr) {
62446248
break;
62456249
case FIO_CLUSTER_MSG_SHUTDOWN:
62466250
fio_stop();
6251+
kill(getpid(), SIGINT);
62476252
case FIO_CLUSTER_MSG_ERROR: /* fallthrough */
62486253
case FIO_CLUSTER_MSG_PING: /* fallthrough */
62496254
case FIO_CLUSTER_MSG_ROOT: /* fallthrough */
@@ -6498,7 +6503,7 @@ static void fio_pubsub_on_fork(void) {
64986503
/** Signals children (or self) to shutdown) - NOT signal safe. */
64996504
static void fio_cluster_signal_children(void) {
65006505
if (fio_parent_pid() != getpid()) {
6501-
fio_stop();
6506+
kill(getpid(), SIGINT);
65026507
return;
65036508
}
65046509
fio_cluster_server_sender(fio_msg_internal_create(0, FIO_CLUSTER_MSG_SHUTDOWN,

ext/iodine/fio.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ Version and helper macros
109109

110110
#define FIO_VERSION_MAJOR 0
111111
#define FIO_VERSION_MINOR 7
112-
#define FIO_VERSION_PATCH 0
113-
#define FIO_VERSION_BETA 9
112+
#define FIO_VERSION_PATCH 3
113+
#define FIO_VERSION_BETA 0
114114

115115
/* Automatically convert version data to a string constant - ignore these two */
116116
#define FIO_MACRO2STR_STEP2(macro) #macro
@@ -1250,7 +1250,7 @@ inline FIO_FUNC ssize_t fio_write(const intptr_t uuid, const void *buffer,
12501250
inline FIO_FUNC ssize_t fio_sendfile(intptr_t uuid, intptr_t source_fd,
12511251
off_t offset, size_t length) {
12521252
return fio_write2(uuid, .data.fd = source_fd, .length = length, .is_fd = 1,
1253-
.offset = offset);
1253+
.offset = (uintptr_t)offset);
12541254
}
12551255

12561256
/**
@@ -2984,8 +2984,8 @@ FIO_FUNC inline void fio_reschedule_thread(void) {
29842984

29852985
/** Nanosleep the thread - a blocking throttle. */
29862986
FIO_FUNC inline void fio_throttle_thread(size_t nano_sec) {
2987-
const struct timespec tm = {.tv_nsec = (nano_sec % 1000000000),
2988-
.tv_sec = (nano_sec / 1000000000)};
2987+
const struct timespec tm = {.tv_nsec = (long)(nano_sec % 1000000000),
2988+
.tv_sec = (time_t)(nano_sec / 1000000000)};
29892989
nanosleep(&tm, NULL);
29902990
}
29912991

@@ -5494,10 +5494,10 @@ Done
54945494
* Note: FIO_SET_HASH_TYPE should, normaly be left alone (uintptr_t is
54955495
* enough). Also, the hash value 0 is reserved to indicate an empty slot.
54965496
*
5497-
* Note: the FIO_SET_OBJ_COMPARE for Sets or the FIO_SET_KEY_COMPARE will be
5498-
* used to compare against invalid as well as valid objects. Invalid
5499-
* objects have their bytes all zero. FIO_SET_*_DESTROY should somehow
5500-
* mark them as invalid.
5497+
* Note: the FIO_SET_OBJ_COMPARE or the FIO_SET_KEY_COMPARE will be used to
5498+
* compare against invalid as well as valid objects. Invalid objects have
5499+
* their bytes all zero. FIO_SET_*_DESTROY should somehow mark them as
5500+
* invalid.
55015501
*
55025502
* Note: Before freeing the Set, FIO_SET_OBJ_DESTROY will be automatically
55035503
* called for every existing object.
@@ -5610,16 +5610,16 @@ typedef struct {
56105610
#endif
56115611

56125612
/* The default Hash Map-Set has will use straight euqality operators */
5613-
#if !defined(FIO_SET_KEY_COMPARE)
5613+
#ifndef FIO_SET_KEY_COMPARE
56145614
#define FIO_SET_KEY_COMPARE(o1, o2) ((o1) == (o2))
56155615
#endif
56165616

56175617
/** Internal macros for object actions in Hash mode */
56185618
#define FIO_SET_COMPARE(o1, o2) FIO_SET_KEY_COMPARE((o1).key, (o2).key)
5619-
#define FIO_SET_COPY(dest, org) \
5619+
#define FIO_SET_COPY(dest, src) \
56205620
do { \
5621-
FIO_SET_OBJ_COPY((dest).obj, (org).obj); \
5622-
FIO_SET_KEY_COPY((dest).key, (org).key); \
5621+
FIO_SET_OBJ_COPY((dest).obj, (src).obj); \
5622+
FIO_SET_KEY_COPY((dest).key, (src).key); \
56235623
} while (0);
56245624
#define FIO_SET_DESTROY(couplet) \
56255625
do { \
@@ -5871,7 +5871,7 @@ FIO_FUNC inline FIO_NAME(_map_s_) *
58715871
if (FIO_SET_HASH_COMPARE(FIO_SET_HASH_INVALID, pos->hash))
58725872
return pos;
58735873
if (FIO_SET_HASH_COMPARE(pos->hash, hash_value_i)) {
5874-
if (!pos->pos || FIO_SET_COMPARE(pos->pos->obj, obj))
5874+
if (!pos->pos || (FIO_SET_COMPARE(pos->pos->obj, obj)))
58755875
return pos;
58765876
/* full hash value collision detected */
58775877
set->has_collisions = 1;
@@ -5890,7 +5890,7 @@ FIO_FUNC inline FIO_NAME(_map_s_) *
58905890
if (FIO_SET_HASH_COMPARE(FIO_SET_HASH_INVALID, pos->hash))
58915891
return pos;
58925892
if (FIO_SET_HASH_COMPARE(pos->hash, hash_value_i)) {
5893-
if (!pos->pos || FIO_SET_COMPARE(pos->pos->obj, obj))
5893+
if (!pos->pos || (FIO_SET_COMPARE(pos->pos->obj, obj)))
58945894
return pos;
58955895
/* full hash value collision detected */
58965896
set->has_collisions = 1;

ext/iodine/fio_cli.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,19 @@ static void fio_cli_set_arg(cstr_s arg, char const *value, char const *line,
272272
switch ((size_t)type) {
273273
case FIO_CLI_STRING__TYPE_I:
274274
fprintf(stderr,
275-
" \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m%*s\t\x1B[2msame as "
276-
"%.*s\x1B[0m\n",
275+
" \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m%*s\t(same as "
276+
"\x1B[1m%.*s\x1B[0m)\n",
277277
(int)(tmp - start), p + start, padding, "", first_len, p);
278278
break;
279279
case FIO_CLI_BOOL__TYPE_I:
280280
fprintf(stderr,
281-
" \x1B[1m%.*s\x1B[0m %*s\t\x1B[2msame as %.*s\x1B[0m\n",
281+
" \x1B[1m%.*s\x1B[0m %*s\t(same as \x1B[1m%.*s\x1B[0m)\n",
282282
(int)(tmp - start), p + start, padding, "", first_len, p);
283283
break;
284284
case FIO_CLI_INT__TYPE_I:
285285
fprintf(stderr,
286-
" \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m%*s\t\x1B[2msame as "
287-
"%.*s\x1B[0m\n",
286+
" \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m%*s\t(same as "
287+
"\x1B[1m%.*s\x1B[0m)\n",
288288
(int)(tmp - start), p + start, padding, "", first_len, p);
289289
break;
290290
}

ext/iodine/fio_tls_missing.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Feel free to copy, use and enjoy according to the license provided.
1919
*/
2020
#include "fio_tls.h"
2121

22-
#if 1 /* TODO: place library compiler flags here */
22+
#if !defined(FIO_TLS_FOUND) /* Library compiler flags */
2323

2424
#define REQUIRE_LIBRARY()
2525
#define FIO_TLS_WEAK
@@ -628,6 +628,7 @@ void FIO_TLS_WEAK fio_tls_destroy(fio_tls_s *tls) {
628628
fio_tls_destroy_context(tls);
629629
alpn_list_free(&tls->alpn);
630630
cert_ary_free(&tls->sni);
631+
trust_ary_free(&tls->trust);
631632
free(tls);
632633
}
633634

ext/iodine/fio_tls_openssl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,7 @@ void FIO_TLS_WEAK fio_tls_destroy(fio_tls_s *tls) {
10051005
fio_tls_destroy_context(tls);
10061006
alpn_list_free(&tls->alpn);
10071007
cert_ary_free(&tls->sni);
1008+
trust_ary_free(&tls->trust);
10081009
free(tls);
10091010
}
10101011

ext/iodine/fiobj4fio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ static inline __attribute__((unused)) ssize_t fiobj_send_free(intptr_t uuid,
1414
FIOBJ o) {
1515
fio_str_info_s s = fiobj_obj2cstr(o);
1616
return fio_write2(uuid, .data.buffer = (void *)(o),
17-
.offset = (((intptr_t)s.data) - ((intptr_t)(o))),
17+
.offset = (uintptr_t)(((intptr_t)s.data) - ((intptr_t)(o))),
1818
.length = s.len, .after.dealloc = fiobj4sock_dealloc);
1919
}
2020

ext/iodine/fiobj_numbers.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ size_t fio_ltoa(char *dest, int64_t num, uint8_t base);
8282
size_t fio_ftoa(char *dest, double num, uint8_t base);
8383

8484
/** Converts a number to a temporary, thread safe, C string object */
85-
fio_str_info_s fio_ltocstr(long);
85+
fio_str_info_s __attribute__((deprecated("use local buffer with fio_ltoa")))
86+
fio_ltocstr(long);
8687

8788
/** Converts a float to a temporary, thread safe, C string object */
88-
fio_str_info_s fio_ftocstr(double);
89+
fio_str_info_s __attribute__((deprecated("use local buffer with fio_ftoa")))
90+
fio_ftocstr(double);
8991

9092
/* *****************************************************************************
9193
Pointer Wrapping Helper MACROs (uses integers)

ext/iodine/http.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,21 @@ int http_sendfile(http_s *r, int fd, uintptr_t length, uintptr_t offset) {
356356
return ((http_vtable_s *)r->private_data.vtbl)
357357
->http_sendfile(r, fd, length, offset);
358358
}
359+
360+
static inline int http_test_encoded_path(const char *mem, size_t len) {
361+
const char *pos = NULL;
362+
const char *end = mem + len;
363+
while (mem < end && (pos = memchr(mem, '/', (size_t)len))) {
364+
len = end - pos;
365+
mem = pos + 1;
366+
if (pos[1] == '/')
367+
return -1;
368+
if (len > 3 && pos[1] == '.' && pos[2] == '.' && pos[3] == '/')
369+
return -1;
370+
}
371+
return 0;
372+
}
373+
359374
/**
360375
* Sends the response headers and the specified file (the response's body).
361376
*
@@ -391,14 +406,8 @@ int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
391406
char *pos = (char *)encoded;
392407
const char *end = encoded + encoded_len;
393408
while (pos < end) {
394-
/* test for path manipulations while decoding */
395-
if (*pos == '/' && (pos[1] == '/' ||
396-
(((uintptr_t)end - (uintptr_t)pos >= 4) &&
397-
pos[1] == '.' && pos[2] == '.' && pos[3] == '/')))
398-
return -1;
399409
if (*pos == '%') {
400-
// decode hex value
401-
// this is a percent encoded value.
410+
// decode hex value (this is a percent encoded value).
402411
if (hex2byte((uint8_t *)tmp.data + tmp.len, (uint8_t *)pos + 1))
403412
return -1;
404413
tmp.len++;
@@ -408,6 +417,9 @@ int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
408417
}
409418
tmp.data[tmp.len] = 0;
410419
fiobj_str_resize(filename, tmp.len);
420+
/* test for path manipulations after decoding */
421+
if (http_test_encoded_path(tmp.data + prefix_len, tmp.len - prefix_len))
422+
return -1;
411423
}
412424
if (tmp.data[tmp.len - 1] == '/')
413425
fiobj_str_write(filename, "index.html", 10);

ext/iodine/http.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ struct http_settings_s {
370370
* sockets count towards a server's limit.
371371
*/
372372
intptr_t max_clients;
373-
/** reserved for future SSL/TLS support. */
373+
/** SSL/TLS support. */
374374
void *tls;
375375
/** reserved for future use. */
376376
intptr_t reserved1;

0 commit comments

Comments
 (0)