Skip to content

Commit 3bc3c5e

Browse files
Fix unchecked malloc returns, NULL dereferences, and resource leaks
- store_file.c: check malloc(header_len) before use - store_memcached.c: check malloc(header_len) before use - store_rados.c: check malloc(header_len), malloc(sz2); fix ctx-only NULL check to also cover store; log error and return on failure - renderd.c: check malloc for render_threads and slave_threads arrays - store_ro_http_proxy.c: free chunk.memory on curl error paths to prevent memory leak when transfer is partially completed before failure - store_ro_composite.c: check strstr() results before pointer arithmetic (NULL deref if separator missing); check malloc for primary connection string; free intermediate strings on all error paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7d379dc commit 3bc3c5e

6 files changed

Lines changed: 74 additions & 1 deletion

File tree

src/renderd.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,12 @@ int main(int argc, char **argv)
888888

889889
render_threads = (pthread_t *) malloc(sizeof(pthread_t) * config.num_threads);
890890

891+
if (render_threads == NULL) {
892+
g_logger(G_LOG_LEVEL_CRITICAL, "Failed to allocate memory for render threads");
893+
close(fd);
894+
return 7;
895+
}
896+
891897
for (i = 0; i < config.num_threads; i++) {
892898
if (pthread_create(&render_threads[i], NULL, render_thread, (void *)maps)) {
893899
g_logger(G_LOG_LEVEL_CRITICAL, "Could not spawn rendering thread");
@@ -901,6 +907,12 @@ int main(int argc, char **argv)
901907
k = 0;
902908
slave_threads = (pthread_t *) malloc(sizeof(pthread_t) * num_slave_threads);
903909

910+
if (slave_threads == NULL) {
911+
g_logger(G_LOG_LEVEL_CRITICAL, "Failed to allocate memory for slave threads");
912+
close(fd);
913+
return 7;
914+
}
915+
904916
for (i = 1; i < MAX_SLAVES; i++) {
905917
for (j = 0; j < config_slaves[i].num_threads; j++) {
906918
if (pthread_create(&slave_threads[k++], NULL, slave_thread, (void *) &config_slaves[i])) {

src/store_file.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ static int file_tile_read(struct storage_backend * store, const char *xmlconfig,
7474
struct meta_layout *m = (struct meta_layout *)malloc(header_len);
7575
size_t file_offset, tile_size;
7676

77+
if (m == NULL) {
78+
snprintf(log_msg, PATH_MAX - 1, "Failed to allocate memory for metatile header\n");
79+
return -1;
80+
}
81+
7782
meta_offset = xyzo_to_meta(path, sizeof(path), store->storage_ctx, xmlconfig, options, x, y, z);
7883

7984
fd = open(path, O_RDONLY);

src/store_memcached.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ static int memcached_tile_read(struct storage_backend * store, const char *xmlco
8080
memcached_return_t rc;
8181
char * buf_raw;
8282

83+
if (m == NULL) {
84+
snprintf(log_msg, 1024, "Failed to allocate memory for metatile header\n");
85+
return -1;
86+
}
87+
8388
mask = METATILE - 1;
8489
meta_offset = (x & mask) * METATILE + (y & mask);
8590

src/store_rados.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ static int rados_tile_read(struct storage_backend * store, const char *xmlconfig
134134
int err;
135135
char * buf_raw;
136136

137+
if (m == NULL) {
138+
snprintf(log_msg, 1024, "Failed to allocate memory for metatile header\n");
139+
return -1;
140+
}
141+
137142
mask = METATILE - 1;
138143
meta_offset = (x & mask) * METATILE + (y & mask);
139144

@@ -234,6 +239,11 @@ static int rados_metatile_write(struct storage_backend * store, const char *xmlc
234239
char * buf2 = malloc(sz2);
235240
int err;
236241

242+
if (buf2 == NULL) {
243+
g_logger(G_LOG_LEVEL_ERROR, "rados_metatile_write: failed to allocate memory for write buffer");
244+
return -1;
245+
}
246+
237247
tile_stat.expired = 0;
238248
tile_stat.size = sz;
239249
tile_stat.mtime = time(NULL);
@@ -351,7 +361,7 @@ struct storage_backend * init_storage_rados(const char * connection_string)
351361
int err;
352362
int i;
353363

354-
if (ctx == NULL) {
364+
if (ctx == NULL || store == NULL) {
355365
free(ctx);
356366
free(store);
357367
return NULL;

src/store_ro_composite.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,23 @@ struct storage_backend * init_storage_ro_composite(const char * connection_strin
248248
}
249249

250250
connection_string_secondary = strstr(connection_string, "}{");
251+
252+
if (connection_string_secondary == NULL) {
253+
g_logger(G_LOG_LEVEL_ERROR, "init_storage_ro_composite: malformed connection string, missing '}{' separator: %s", connection_string);
254+
free(ctx);
255+
free(store);
256+
return NULL;
257+
}
258+
251259
connection_string_primary = malloc(strlen(connection_string) - strlen("composite:{") - strlen(connection_string_secondary) + 1);
260+
261+
if (connection_string_primary == NULL) {
262+
g_logger(G_LOG_LEVEL_ERROR, "init_storage_ro_composite: failed to allocate memory for primary connection string");
263+
free(ctx);
264+
free(store);
265+
return NULL;
266+
}
267+
252268
memcpy(connection_string_primary, connection_string + strlen("composite:{"), strlen(connection_string) - strlen("composite:{") - strlen(connection_string_secondary));
253269
connection_string_primary[strlen(connection_string) - strlen("composite:{") - strlen(connection_string_secondary)] = 0;
254270
connection_string_secondary = strdup(connection_string_secondary + 2);
@@ -258,18 +274,41 @@ struct storage_backend * init_storage_ro_composite(const char * connection_strin
258274
g_logger(G_LOG_LEVEL_DEBUG, "init_storage_ro_composite: Secondary storage backend: %s", connection_string_secondary);
259275

260276
tmp = strstr(connection_string_primary, ",");
277+
278+
if (tmp == NULL) {
279+
g_logger(G_LOG_LEVEL_ERROR, "init_storage_ro_composite: malformed primary connection string, missing ',' separator: %s", connection_string_primary);
280+
free(connection_string_primary);
281+
free(connection_string_secondary);
282+
free(ctx);
283+
free(store);
284+
return NULL;
285+
}
286+
261287
memcpy(ctx->xmlconfig_primary, connection_string_primary, tmp - connection_string_primary);
262288
ctx->xmlconfig_primary[tmp - connection_string_primary] = 0;
263289
ctx->store_primary = init_storage_backend(tmp + 1);
264290

265291
if (ctx->store_primary == NULL) {
266292
g_logger(G_LOG_LEVEL_ERROR, "init_storage_ro_composite: failed to initialise primary storage backend");
293+
free(connection_string_primary);
294+
free(connection_string_secondary);
267295
free(ctx);
268296
free(store);
269297
return NULL;
270298
}
271299

272300
tmp = strstr(connection_string_secondary, ",");
301+
302+
if (tmp == NULL) {
303+
g_logger(G_LOG_LEVEL_ERROR, "init_storage_ro_composite: malformed secondary connection string, missing ',' separator: %s", connection_string_secondary);
304+
free(connection_string_primary);
305+
free(connection_string_secondary);
306+
ctx->store_primary->close_storage(ctx->store_primary);
307+
free(ctx);
308+
free(store);
309+
return NULL;
310+
}
311+
273312
memcpy(ctx->xmlconfig_secondary, connection_string_secondary, tmp - connection_string_secondary);
274313
ctx->xmlconfig_secondary[tmp - connection_string_secondary] = 0;
275314
ctx->store_secondary = init_storage_backend(tmp + 1);

src/store_ro_http_proxy.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static int ro_http_proxy_tile_retrieve(struct storage_backend * store, const cha
116116

117117
if (res != CURLE_OK) {
118118
g_logger(G_LOG_LEVEL_ERROR, "ro_http_proxy_tile_fetch: failed to retrieve file: %s", curl_easy_strerror(res));
119+
free(chunk.memory);
119120
ctx->cache.x = -1;
120121
ctx->cache.y = -1;
121122
ctx->cache.z = -1;
@@ -126,6 +127,7 @@ static int ro_http_proxy_tile_retrieve(struct storage_backend * store, const cha
126127

127128
if (res != CURLE_OK) {
128129
g_logger(G_LOG_LEVEL_ERROR, "ro_http_proxy_tile_fetch: failed to retrieve HTTP code: %s", curl_easy_strerror(res));
130+
free(chunk.memory);
129131
ctx->cache.x = -1;
130132
ctx->cache.y = -1;
131133
ctx->cache.z = -1;

0 commit comments

Comments
 (0)