Merge fix/memory-safety into merge-all
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "stdlib.h"
|
#include <stdlib.h>
|
||||||
|
|
||||||
Data* data_create_empty(size_t data_size) {
|
Data* data_create_empty(size_t data_size) {
|
||||||
/* malloc(0) is UB; allocate at least 1 byte but preserve requested size */
|
/* malloc(0) is UB; allocate at least 1 byte but preserve requested size */
|
||||||
|
|||||||
+9
-24
@@ -34,14 +34,11 @@ static void bw_throttle(size_t bytes_written) {
|
|||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
/* Use unsigned long long for elapsed_ns to avoid overflow in multiplication.
|
long long elapsed_ns =
|
||||||
* time_t differences fit comfortably in 64-bit for any practical runtime. */
|
(now.tv_sec - bw_last_refill.tv_sec) * 1000000000LL + (now.tv_nsec - bw_last_refill.tv_nsec);
|
||||||
unsigned long long elapsed_ns =
|
|
||||||
(unsigned long long)(now.tv_sec - bw_last_refill.tv_sec) * 1000000000ULL +
|
|
||||||
(unsigned long long)(now.tv_nsec - bw_last_refill.tv_nsec);
|
|
||||||
bw_last_refill = now;
|
bw_last_refill = now;
|
||||||
|
|
||||||
long long tokens_to_add = (long long)((double)io_bwlimit * (double)elapsed_ns / 1000000000.0);
|
long long tokens_to_add = (long long)((double)io_bwlimit * elapsed_ns / 1000000000.0);
|
||||||
bw_tokens += tokens_to_add;
|
bw_tokens += tokens_to_add;
|
||||||
if (bw_tokens > (long long)io_bwlimit)
|
if (bw_tokens > (long long)io_bwlimit)
|
||||||
bw_tokens = (long long)io_bwlimit;
|
bw_tokens = (long long)io_bwlimit;
|
||||||
@@ -49,9 +46,7 @@ static void bw_throttle(size_t bytes_written) {
|
|||||||
bw_tokens -= (long long)bytes_written;
|
bw_tokens -= (long long)bytes_written;
|
||||||
|
|
||||||
if (bw_tokens < 0) {
|
if (bw_tokens < 0) {
|
||||||
long long deficit_ns = (long long)((double)(-bw_tokens) / (double)io_bwlimit * 1000000000.0);
|
long long deficit_ns = (long long)((double)(-bw_tokens) / io_bwlimit * 1000000000.0);
|
||||||
if (deficit_ns < 0)
|
|
||||||
deficit_ns = 0;
|
|
||||||
struct timespec sleep_time, remaining;
|
struct timespec sleep_time, remaining;
|
||||||
sleep_time.tv_sec = deficit_ns / 1000000000LL;
|
sleep_time.tv_sec = deficit_ns / 1000000000LL;
|
||||||
sleep_time.tv_nsec = deficit_ns % 1000000000LL;
|
sleep_time.tv_nsec = deficit_ns % 1000000000LL;
|
||||||
@@ -84,11 +79,6 @@ bool send_n_data(int file_descriptor, const void* data, size_t data_size) {
|
|||||||
else
|
else
|
||||||
bytes_send = write(fd, (const char*)data + total_bytes_send, chunk);
|
bytes_send = write(fd, (const char*)data + total_bytes_send, chunk);
|
||||||
if (bytes_send <= 0) {
|
if (bytes_send <= 0) {
|
||||||
if (io_ssl) {
|
|
||||||
int ssl_err = SSL_get_error(io_ssl, (int)bytes_send);
|
|
||||||
if (ssl_err == SSL_ERROR_WANT_WRITE || ssl_err == SSL_ERROR_WANT_READ)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
log_message(LOG_LEVEL_ERROR, "Could not send data");
|
log_message(LOG_LEVEL_ERROR, "Could not send data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -112,11 +102,6 @@ bool receive_n_data(int file_descriptor, void* data, size_t data_size) {
|
|||||||
bytes_received =
|
bytes_received =
|
||||||
read(fd, (char*)data + total_bytes_received, data_size - total_bytes_received);
|
read(fd, (char*)data + total_bytes_received, data_size - total_bytes_received);
|
||||||
if (bytes_received <= 0) {
|
if (bytes_received <= 0) {
|
||||||
if (io_ssl) {
|
|
||||||
int ssl_err = SSL_get_error(io_ssl, (int)bytes_received);
|
|
||||||
if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (bytes_received == 0)
|
if (bytes_received == 0)
|
||||||
log_message(LOG_LEVEL_ERROR, "Connection closed while receiving data");
|
log_message(LOG_LEVEL_ERROR, "Connection closed while receiving data");
|
||||||
else
|
else
|
||||||
@@ -193,18 +178,18 @@ bool send_data(int file_descriptor, const Data* data) {
|
|||||||
return false;
|
return false;
|
||||||
if (!send_n_data(file_descriptor, data->data, data_size))
|
if (!send_n_data(file_descriptor, data->data, data_size))
|
||||||
return false;
|
return false;
|
||||||
log_message(LOG_LEVEL_DEBUG, "Send %lld data", data_size);
|
log_message(LOG_LEVEL_DEBUG, "Send %llu data", data_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_DATA_SIZE (1024ULL * 1024 * 1024) // 1 GB
|
#define MAX_DATA_SIZE (1024ULL * 1024 * 1024)
|
||||||
|
|
||||||
Data* receive_data(int file_descriptor) {
|
Data* receive_data(int file_descriptor) {
|
||||||
unsigned long long size = 0;
|
unsigned long long size = 0;
|
||||||
if (!receive_n_data(file_descriptor, &size, sizeof(unsigned long long)))
|
if (!receive_n_data(file_descriptor, &size, sizeof(unsigned long long)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (size > MAX_DATA_SIZE) {
|
if ((size_t)size != size || size > MAX_DATA_SIZE) {
|
||||||
log_message(LOG_LEVEL_ERROR, "receive_data: size %llu exceeds maximum", size);
|
log_message(LOG_LEVEL_ERROR, "receive_data size %llu exceeds limits", size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void* data = malloc((size_t)size);
|
void* data = malloc((size_t)size);
|
||||||
@@ -214,7 +199,7 @@ Data* receive_data(int file_descriptor) {
|
|||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
log_message(LOG_LEVEL_DEBUG, "Received %lld data", size);
|
log_message(LOG_LEVEL_DEBUG, "Received %llu data", size);
|
||||||
return data_create(data, (size_t)size);
|
return data_create(data, (size_t)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -134,7 +134,7 @@ static void delete_extras_walk(const char* abs_path, const char* rel_path, Array
|
|||||||
if (!dir)
|
if (!dir)
|
||||||
return;
|
return;
|
||||||
bool all_removed = true;
|
bool all_removed = true;
|
||||||
struct dirent* entry;
|
const struct dirent* entry;
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -184,18 +184,17 @@ void delete_extras(const char* dest_root, ArrayList* manifest) {
|
|||||||
delete_extras_walk(dest_root, "", manifest);
|
delete_extras_walk(dest_root, "", manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* path_cat(const char* path1, char* path2) {
|
char* path_cat(const char* path1, const char* path2) {
|
||||||
if (path1 == NULL || *path1 == '\0')
|
if (path1 == NULL || *path1 == '\0')
|
||||||
return str_dup(path2);
|
return str_dup(path2);
|
||||||
if (path2 == NULL || *path2 == '\0')
|
if (path2 == NULL || *path2 == '\0')
|
||||||
return str_dup(path1);
|
return str_dup(path1);
|
||||||
int path1_len = strlen(path1);
|
int path1_len = strlen(path1);
|
||||||
int path2_len = strlen(path2);
|
int path2_len = strlen(path2);
|
||||||
char* path2_pointer = path2;
|
|
||||||
if (path1[path1_len - 1] == '/')
|
if (path1[path1_len - 1] == '/')
|
||||||
path1_len -= 1;
|
path1_len -= 1;
|
||||||
if (path2[0] == '/') {
|
if (path2[0] == '/') {
|
||||||
path2_pointer += 1;
|
path2++;
|
||||||
path2_len -= 1;
|
path2_len -= 1;
|
||||||
}
|
}
|
||||||
char* new_path = malloc(path1_len + path2_len + 2);
|
char* new_path = malloc(path1_len + path2_len + 2);
|
||||||
@@ -203,7 +202,7 @@ char* path_cat(const char* path1, char* path2) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
memcpy(new_path, path1, path1_len);
|
memcpy(new_path, path1, path1_len);
|
||||||
new_path[path1_len] = '/';
|
new_path[path1_len] = '/';
|
||||||
memcpy(new_path + path1_len + 1, path2_pointer, path2_len);
|
memcpy(new_path + path1_len + 1, path2, path2_len);
|
||||||
new_path[path1_len + path2_len + 1] = '\0';
|
new_path[path1_len + path2_len + 1] = '\0';
|
||||||
return new_path;
|
return new_path;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
bool mkdir_r(const char* path);
|
bool mkdir_r(const char* path);
|
||||||
char* str_dup(const char* string);
|
char* str_dup(const char* string);
|
||||||
char* path_cat(const char* path1, char* path2);
|
char* path_cat(const char* path1, const char* path2);
|
||||||
bool glob_match(const char* pattern, const char* str);
|
bool glob_match(const char* pattern, const char* str);
|
||||||
void delete_extras(const char* dest_root, ArrayList* manifest);
|
void delete_extras(const char* dest_root, ArrayList* manifest);
|
||||||
|
|
||||||
|
|||||||
@@ -179,8 +179,7 @@ static void test_receive_str_oversized() {
|
|||||||
size_t huge = MAX_STRING_SIZE + 1;
|
size_t huge = MAX_STRING_SIZE + 1;
|
||||||
EXPECT_TRUE(send_n_data(0, &huge, sizeof(size_t)));
|
EXPECT_TRUE(send_n_data(0, &huge, sizeof(size_t)));
|
||||||
|
|
||||||
/* cppcheck-suppress constVariablePointer */
|
const char* received = receive_str(0);
|
||||||
char* received = receive_str(0);
|
|
||||||
EXPECT_NULL(received);
|
EXPECT_NULL(received);
|
||||||
|
|
||||||
close(p[0]);
|
close(p[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user