Skip to content

Commit

Permalink
Improve limits check
Browse files Browse the repository at this point in the history
  • Loading branch information
babelouest committed Dec 30, 2023
1 parent fc108e6 commit 6c8d482
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/u_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ int u_map_put(struct _u_map * u_map, const char * key, const char * value) {
int u_map_put_binary(struct _u_map * u_map, const char * key, const char * value, uint64_t offset, size_t length) {
size_t i;
char * dup_key, * dup_value;
if (u_map != NULL && key != NULL && !o_strnullempty(key)) {
if (u_map != NULL && key != NULL && !o_strnullempty(key) && (offset+length+1) <= SIZE_MAX) {
for (i=0; i < (size_t)u_map->nb_values; i++) {
if (0 == o_strcmp(u_map->keys[i], key)) {
// Key already exist, extend and/or replace value
Expand Down
2 changes: 1 addition & 1 deletion src/u_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ char * ulfius_export_request_http(const struct _u_request * request) {
if (key_esc) {
value = u_map_get(request->map_post_body, keys[i]);
len = u_map_get_length(request->map_post_body, keys[i]);
if (value != NULL && utf8_check(value, (size_t)len) == NULL) {
if (value != NULL && len > 0 && utf8_check(value, (size_t)len) == NULL) {
value_esc = ulfius_url_encode(value);
if (value_esc != NULL) {
body = mstrcatf(body, "%s=%s", key_esc, value_esc);
Expand Down
111 changes: 60 additions & 51 deletions src/u_websocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ static struct _websocket_message * ulfius_build_message (const uint8_t opcode,
}
}
if (new_message != NULL) {
if (data_len > 0) {
if (data_len > 0 && data_len <= SIZE_MAX) {
memcpy(new_message->data, data, (size_t)data_len);
}
time(&new_message->datestamp);
Expand Down Expand Up @@ -599,44 +599,49 @@ static int ulfius_websocket_extension_message_in_perform_apply(struct _websocket
memcpy(data_in, message->data, message->data_len);
}
data_in_len = message->data_len;
for (i=0; i<len && ret == U_OK; i++) {
extension = pointer_list_get_at(websocket->websocket_manager->websocket_extension_list, (len-i-1));
if (extension != NULL &&
extension->enabled &&
extension->websocket_extension_message_in_perform != NULL &&
(message->rsv & extension->rsv)) {
if (extension->websocket_extension_message_in_perform(message->opcode,
data_in_len,
data_in,
&data_out_len,
&data_out,
0,
extension->websocket_extension_message_out_perform_user_data,
extension->context) != U_OK) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error performing websocket_extension_message_in_perform at index %zu", i);
ret = U_ERROR;
} else {
o_free(data_in);
data_in = NULL;
data_in_len = 0;
if (data_out_len) {
if ((data_in = o_malloc((size_t)data_out_len)) != NULL) {
memcpy(data_in, data_out, (size_t)data_out_len);
data_in_len = data_out_len;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for data_in (%zu) (incoming)", i);
ret = U_ERROR_MEMORY;
if (data_in_len <= SIZE_MAX) {
for (i=0; i<len && ret == U_OK; i++) {
extension = pointer_list_get_at(websocket->websocket_manager->websocket_extension_list, (len-i-1));
if (extension != NULL &&
extension->enabled &&
extension->websocket_extension_message_in_perform != NULL &&
(message->rsv & extension->rsv)) {
if (extension->websocket_extension_message_in_perform(message->opcode,
data_in_len,
data_in,
&data_out_len,
&data_out,
0,
extension->websocket_extension_message_out_perform_user_data,
extension->context) != U_OK) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error performing websocket_extension_message_in_perform at index %zu", i);
ret = U_ERROR;
} else {
o_free(data_in);
data_in = NULL;
data_in_len = 0;
if (data_out_len) {
if ((data_in = o_malloc((size_t)data_out_len)) != NULL) {
memcpy(data_in, data_out, (size_t)data_out_len);
data_in_len = data_out_len;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for data_in (%zu) (incoming)", i);
ret = U_ERROR_MEMORY;
}
}
o_free(data_out);
data_out = NULL;
data_out_len = 0;
}
o_free(data_out);
data_out = NULL;
data_out_len = 0;
}
}
o_free(message->data);
message->data = data_in;
message->data_len = (size_t)data_in_len;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for data_in (incoming) - size too large %zu", message->data_len);
ret = U_ERROR_MEMORY;
}
o_free(message->data);
message->data = data_in;
message->data_len = (size_t)data_in_len;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for data_in (incoming) %zu", message->data_len);
ret = U_ERROR_MEMORY;
Expand Down Expand Up @@ -855,11 +860,12 @@ static int ulfius_get_next_line_from_http_response(struct _websocket * websocket
static int ulfius_websocket_connection_handshake(struct _u_request * request, struct yuarel * y_url, struct _websocket * websocket, struct _u_response * response) {
int websocket_response_http = 0, ret, extension_enabled;
unsigned int websocket_response = 0, check_websocket = WEBSOCKET_RESPONSE_UPGRADE | WEBSOCKET_RESPONSE_CONNECTION | WEBSOCKET_RESPONSE_ACCEPT;
char * http_line, ** split_line = NULL, * key, * value, * separator, ** extension_list = NULL;
char * http_line, ** split_line = NULL, * key, * value, * separator, ** extension_list = NULL, * endptr = NULL;
char buffer[U_WEBSOCKET_RESPONSE_BUFFER_LEN+1] = {0};
const char ** keys;
size_t buffer_len = U_WEBSOCKET_RESPONSE_BUFFER_LEN, line_len, extension_len, i, j;
struct _websocket_extension * w_extension;
long int content_length;

// Send HTTP Request
http_line = msprintf("%s /%s%s%s HTTP/%s\r\n", request->http_verb, o_strlen(y_url->path)?y_url->path:"", y_url->query!=NULL?"?":"", y_url->query!=NULL?y_url->query:"", request->http_protocol);
Expand Down Expand Up @@ -955,18 +961,21 @@ static int ulfius_websocket_connection_handshake(struct _u_request * request, st

if (!websocket_response_http || !(websocket_response & check_websocket) || response->status != 101) {
if (u_map_has_key(response->map_header, "Content-Length")) {
response->binary_body_length = (size_t)strtol(u_map_get(response->map_header, "Content-Length"), NULL, 10);
if (response->binary_body) {
response->binary_body = o_malloc(response->binary_body_length);
if (response->binary_body != NULL) {
if (read_data_from_socket(websocket->websocket_manager, response->binary_body, response->binary_body_length) != (ssize_t)response->binary_body_length) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error read_data_from_socket for response->binary_body");
content_length = strtol(u_map_get(response->map_header, "Content-Length"), &endptr, 10);
if (content_length >= 0) {
response->binary_body_length = (size_t)content_length;
if (response->binary_body) {
response->binary_body = o_malloc(response->binary_body_length);
if (response->binary_body != NULL) {
if (read_data_from_socket(websocket->websocket_manager, response->binary_body, response->binary_body_length) != (ssize_t)response->binary_body_length) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error read_data_from_socket for response->binary_body");
}
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for response->binary_body");
}
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating resources for response->binary_body");
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error invalid response->binary_body_length");
}
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error invalid response->binary_body_length");
}
}
close(websocket->websocket_manager->tcp_sock);
Expand Down Expand Up @@ -1042,7 +1051,7 @@ static int ulfius_open_websocket(struct _u_request * request, struct yuarel * y_

websocket->websocket_manager->tcp_sock = socket(AF_INET, SOCK_STREAM, 0);
if (websocket->websocket_manager->tcp_sock != -1) {
if ((he = gethostbyname(y_url->host)) != NULL) {
if ((he = gethostbyname(y_url->host)) != NULL && he->h_length > 0) {
memcpy(&server.sin_addr, he->h_addr_list[0], (size_t)he->h_length);
server.sin_family = AF_INET;
server.sin_port = htons((uint16_t)y_url->port);
Expand Down Expand Up @@ -1098,7 +1107,7 @@ static int ulfius_open_websocket_tls(struct _u_request * request, struct yuarel
}
websocket->websocket_manager->tcp_sock = socket(AF_INET, SOCK_STREAM, 0);
if (websocket->websocket_manager->tcp_sock != -1) {
if ((he = gethostbyname(y_url->host)) != NULL) {
if ((he = gethostbyname(y_url->host)) != NULL && he->h_length > 0) {
memset(&server, '\0', sizeof(server));
memcpy(&server.sin_addr, he->h_addr_list[0], (size_t)he->h_length);
server.sin_family = AF_INET;
Expand Down Expand Up @@ -1530,7 +1539,7 @@ int ulfius_websocket_send_fragmented_message(struct _websocket_manager * websock
ret = U_OK;
} else {
ret = U_OK;
if ((data_len && (data_in = o_malloc((size_t)data_len)) != NULL) || !data_len) {
if ((data_len && data_len <= SIZE_MAX && (data_in = o_malloc((size_t)data_len)) != NULL) || !data_len) {
if (data != NULL) {
memcpy(data_in, data, (size_t)data_len);
} else {
Expand All @@ -1545,7 +1554,7 @@ int ulfius_websocket_send_fragmented_message(struct _websocket_manager * websock
} else {
rsv |= extension->rsv;
o_free(data_in);
if ((data_in = o_malloc((size_t)data_out_len)) != NULL) {
if (data_out_len <= SIZE_MAX && (data_in = o_malloc((size_t)data_out_len)) != NULL) {
memcpy(data_in, data_out, (size_t)data_out_len);
data_in_len = data_out_len;
} else {
Expand Down Expand Up @@ -1971,7 +1980,7 @@ int websocket_extension_message_out_deflate(const uint8_t opcode,

ret = U_OK;
do {
if ((*data_out = o_realloc(*data_out, (size_t)(*data_len_out)+_U_W_BUFF_LEN)) != NULL) {
if ((*data_len_out)+_U_W_BUFF_LEN <= SIZE_MAX && (*data_out = o_realloc(*data_out, (size_t)(*data_len_out)+_U_W_BUFF_LEN)) != NULL) {
deflate_context->defstream.avail_out = _U_W_BUFF_LEN;
deflate_context->defstream.next_out = ((Bytef *)*data_out)+(*data_len_out);
int res;
Expand All @@ -1988,7 +1997,7 @@ int websocket_extension_message_out_deflate(const uint8_t opcode,
(*data_len_out) += _U_W_BUFF_LEN - deflate_context->defstream.avail_out;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "websocket_extension_message_out_deflate - Error allocating resources for data_in_suffix");
ret = U_ERROR;
ret = U_ERROR_MEMORY;
}
} while (U_OK == ret && deflate_context->defstream.avail_out == 0);

Expand Down Expand Up @@ -2053,7 +2062,7 @@ int websocket_extension_message_in_inflate(const uint8_t opcode,
(void)fragment_len;
(void)user_data;

if (data_len_in) {
if (data_len_in && data_len_in <= (SIZE_MAX-4)) {
if (deflate_context != NULL) {
*data_out = NULL;
*data_len_out = 0;
Expand Down
58 changes: 35 additions & 23 deletions src/ulfius.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,16 +284,19 @@ void mhd_redirect_log(void * arg, const char * fmt, va_list ap) {
va_list args_cpy, args_cpy2;
size_t out_len = 0;
char * out = NULL, * new_fmt;
int v_out = 0;

va_copy(args_cpy, ap);
va_copy(args_cpy2, ap);
new_fmt = msprintf("MHD - %s", fmt);
out_len = (size_t)vsnprintf(NULL, 0, new_fmt, args_cpy);
out = o_malloc((out_len));
if (out != NULL) {
vsnprintf(out, (out_len), new_fmt, args_cpy2);
y_log_message(Y_LOG_LEVEL_ERROR, out);
o_free(out);
if ((v_out = vsnprintf(NULL, 0, new_fmt, args_cpy)) > 0) {
out_len = (size_t)v_out;
out = o_malloc((out_len));
if (out != NULL) {
vsnprintf(out, (out_len), new_fmt, args_cpy2);
y_log_message(Y_LOG_LEVEL_ERROR, out);
o_free(out);
}
}
o_free(new_fmt);
va_end(args_cpy);
Expand Down Expand Up @@ -360,50 +363,59 @@ static int mhd_iterate_post_data (void * coninfo_cls, enum MHD_ValueKind kind, c
ret = MHD_NO;
}
} else {

do {
if (con_info->u_instance->check_utf8) {
if (utf8_check(key, o_strlen(key)) != NULL || data == NULL || utf8_check(data, size) != NULL || (filename != NULL && utf8_check(filename, o_strlen(filename)) != NULL)) {
break;
}
}

if (con_info->max_post_param_size && off > con_info->max_post_param_size) {
break;
}


if (off > SIZE_MAX) {
ret = MHD_NO;
break;
}

if (con_info->max_post_param_size && off + size > con_info->max_post_param_size) {
data_size = (size_t)(con_info->max_post_param_size - off);
data_size = (con_info->max_post_param_size - (size_t)off);
}

if (filename != NULL) {
filename_param = msprintf("%s_filename", key);
if (!u_map_has_key((struct _u_map *)con_info->request->map_post_body, filename_param) && u_map_put((struct _u_map *)con_info->request->map_post_body, filename_param, filename) != U_OK) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error u_map_put filename value");
}
}
cur_data = u_map_get((struct _u_map *)con_info->request->map_post_body, key);
cur_size = u_map_get_length((struct _u_map *)con_info->request->map_post_body, key);
if (cur_data != NULL) {
if (off) {
if (u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, data, (size_t)cur_size, data_size) != U_OK) {
ret = MHD_NO;
break;
if ((cur_size = u_map_get_length((struct _u_map *)con_info->request->map_post_body, key)) >= 0) {
if (off) {
if (u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, data, (size_t)cur_size, data_size) != U_OK) {
ret = MHD_NO;
break;
}
} else {
if (u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, ",", (size_t)cur_size, 1) != U_OK ||
u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, data, (size_t)cur_size+1, data_size) != U_OK) {
ret = MHD_NO;
break;
}
}
} else {
if (u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, ",", (size_t)cur_size, 1) != U_OK ||
u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, data, (size_t)cur_size+1, data_size) != U_OK) {
ret = MHD_NO;
break;
}
ret = MHD_NO;
break;
}
} else {
if (u_map_put_binary((struct _u_map *)con_info->request->map_post_body, key, data, 0, data_size) != U_OK) {
ret = MHD_NO;
break;
}
}

} while (0);
o_free(data_concat);
o_free(filename_param);
Expand Down Expand Up @@ -533,7 +545,7 @@ static int ulfius_webservice_dispatcher (void * cls,
content_type = (char*)u_map_get_case(con_info->request->map_header, ULFIUS_HTTP_HEADER_CONTENT);

// Set POST Processor if content-type is properly set
if (content_type != NULL &&
if (content_type != NULL &&
((con_info->u_instance->allowed_post_processor&U_POST_PROCESS_URL_ENCODED && 0 == o_strncmp(MHD_HTTP_POST_ENCODING_FORM_URLENCODED, content_type, o_strlen(MHD_HTTP_POST_ENCODING_FORM_URLENCODED))) ||
(con_info->u_instance->allowed_post_processor&U_POST_PROCESS_MULTIPART_FORMDATA && 0 == o_strncmp(MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, content_type, o_strlen(MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA))))) {
con_info->has_post_processor = 1;
Expand Down

0 comments on commit 6c8d482

Please sign in to comment.