Commit 47cb709b authored by Philipp Schafft's avatar Philipp Schafft 🦁
Browse files

Merge branch 'ph3-fix-bufferoverflow'

See: #2342
parents e75b85fe 162e3dd6
Pipeline #477 failed with stage
in 14 seconds
...@@ -343,6 +343,7 @@ static auth_result url_remove_client(auth_client *auth_user) ...@@ -343,6 +343,7 @@ static auth_result url_remove_client(auth_client *auth_user)
const char *agent; const char *agent;
char *user_agent, char *user_agent,
*ipaddr; *ipaddr;
int ret;
if (url->removeurl == NULL) if (url->removeurl == NULL)
return AUTH_OK; return AUTH_OK;
...@@ -378,7 +379,7 @@ static auth_result url_remove_client(auth_client *auth_user) ...@@ -378,7 +379,7 @@ static auth_result url_remove_client(auth_client *auth_user)
mount = util_url_escape(mountreq); mount = util_url_escape(mountreq);
ipaddr = util_url_escape(client->con->ip); ipaddr = util_url_escape(client->con->ip);
snprintf(post, sizeof (post), ret = snprintf(post, sizeof(post),
"action=%s&server=%s&port=%d&client=%lu&mount=%s" "action=%s&server=%s&port=%d&client=%lu&mount=%s"
"&user=%s&pass=%s&duration=%lu&ip=%s&agent=%s", "&user=%s&pass=%s&duration=%lu&ip=%s&agent=%s",
url->removeaction, /* already escaped */ url->removeaction, /* already escaped */
...@@ -392,6 +393,12 @@ static auth_result url_remove_client(auth_client *auth_user) ...@@ -392,6 +393,12 @@ static auth_result url_remove_client(auth_client *auth_user)
free(ipaddr); free(ipaddr);
free(user_agent); free(user_agent);
if (ret <= 0 || ret >= (ssize_t)sizeof(post)) {
ICECAST_LOG_ERROR("Authentication failed for client %p as header POST data is too long.", client);
auth_user_url_clear(auth_user);
return AUTH_FAILED;
}
if (strchr (url->removeurl, '@') == NULL) { if (strchr (url->removeurl, '@') == NULL) {
if (url->userpwd) { if (url->userpwd) {
curl_easy_setopt(url->handle, CURLOPT_USERPWD, url->userpwd); curl_easy_setopt(url->handle, CURLOPT_USERPWD, url->userpwd);
...@@ -499,6 +506,13 @@ static auth_result url_add_client(auth_client *auth_user) ...@@ -499,6 +506,13 @@ static auth_result url_add_client(auth_client *auth_user)
free(password); free(password);
free(ipaddr); free(ipaddr);
if (post_offset <= 0 || post_offset >= (ssize_t)sizeof(post)) {
ICECAST_LOG_ERROR("Authentication failed for client %p as header POST data is too long.", client);
auth_user_url_clear(auth_user);
return AUTH_FAILED;
}
pass_headers = NULL; pass_headers = NULL;
if (url->pass_headers) if (url->pass_headers)
pass_headers = strdup(url->pass_headers); pass_headers = strdup(url->pass_headers);
...@@ -513,13 +527,25 @@ static auth_result url_add_client(auth_client *auth_user) ...@@ -513,13 +527,25 @@ static auth_result url_add_client(auth_client *auth_user)
header_val = httpp_getvar (client->parser, cur_header); header_val = httpp_getvar (client->parser, cur_header);
if (header_val) { if (header_val) {
size_t left = sizeof(post) - post_offset;
int ret;
header_valesc = util_url_escape (header_val); header_valesc = util_url_escape (header_val);
post_offset += snprintf(post + post_offset, ret = snprintf(post + post_offset,
sizeof(post) - post_offset, sizeof(post) - post_offset,
"&%s%s=%s", "&%s%s=%s",
url->prefix_headers ? url->prefix_headers : "", url->prefix_headers ? url->prefix_headers : "",
cur_header, header_valesc); cur_header, header_valesc);
free(header_valesc); free(header_valesc);
if (ret <= 0 || (size_t)ret >= left) {
ICECAST_LOG_ERROR("Authentication failed for client %p as header \"%H\" is too long.", client, cur_header);
free(pass_headers);
auth_user_url_clear(auth_user);
return AUTH_FAILED;
} else {
post_offset += ret;
}
} }
cur_header = next_header; cur_header = next_header;
......
...@@ -295,7 +295,7 @@ static inline ssize_t __print_var(char *str, size_t remaining, const char *forma ...@@ -295,7 +295,7 @@ static inline ssize_t __print_var(char *str, size_t remaining, const char *forma
for (i = 0; i < var->values; i++) { for (i = 0; i < var->values; i++) {
ret = snprintf(str + done, remaining - done, format, first, var->value[i]); ret = snprintf(str + done, remaining - done, format, first, var->value[i]);
if (ret == -1) if (ret <= 0 || (size_t)ret >= (remaining - done))
return -1; return -1;
done += ret; done += ret;
...@@ -331,7 +331,7 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -331,7 +331,7 @@ static int format_prepare_headers (source_t *source, client_t *client)
client->respcode = 200; client->respcode = 200;
bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client); bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client);
if (bytes < 0) { if (bytes <= 0) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client->respcode = 500; client->respcode = 500;
return -1; return -1;
...@@ -342,7 +342,7 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -342,7 +342,7 @@ static int format_prepare_headers (source_t *source, client_t *client)
client->refbuf->data = ptr = new_ptr; client->refbuf->data = ptr = new_ptr;
client->refbuf->len = remaining = bytes + 1024; client->refbuf->len = remaining = bytes + 1024;
bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client); bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client);
if (bytes == -1 ) { if (bytes <= 0 || (size_t)bytes >= remaining) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client->respcode = 500; client->respcode = 500;
return -1; return -1;
...@@ -354,6 +354,11 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -354,6 +354,11 @@ static int format_prepare_headers (source_t *source, client_t *client)
} }
} }
if (bytes <= 0 || (size_t)bytes >= remaining) {
ICECAST_LOG_ERROR("Can not allocate headers for client %p", client);
client->respcode = 500;
return -1;
}
remaining -= bytes; remaining -= bytes;
ptr += bytes; ptr += bytes;
...@@ -421,6 +426,13 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -421,6 +426,13 @@ static int format_prepare_headers (source_t *source, client_t *client)
} }
} }
if (bytes < 0 || (size_t)bytes >= remaining) {
avl_tree_unlock(source->parser->vars);
ICECAST_LOG_ERROR("Can not allocate headers for client %p", client);
client->respcode = 500;
return -1;
}
remaining -= bytes; remaining -= bytes;
ptr += bytes; ptr += bytes;
if (next) if (next)
...@@ -429,6 +441,11 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -429,6 +441,11 @@ static int format_prepare_headers (source_t *source, client_t *client)
avl_tree_unlock(source->parser->vars); avl_tree_unlock(source->parser->vars);
bytes = snprintf(ptr, remaining, "\r\n"); bytes = snprintf(ptr, remaining, "\r\n");
if (bytes <= 0 || (size_t)bytes >= remaining) {
ICECAST_LOG_ERROR("Can not allocate headers for client %p", client);
client->respcode = 500;
return -1;
}
remaining -= bytes; remaining -= bytes;
ptr += bytes; ptr += bytes;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment