16efc896b0
- backport patches from gc-7_2-hotfix-2 branch in lieu of 7.2c release - gc 7.2 final abi broken when changing several symbols to hidden (#825473) - gc: malloc() and calloc() overflows (CVE-2012-2673, #828881)
94 lines
3.5 KiB
Diff
94 lines
3.5 KiB
Diff
From 1de90aeb38a078550f9b22a5900f959e6dcbd37b Mon Sep 17 00:00:00 2001
|
|
From: Ivan Maidanski <ivmai@mail.ru>
|
|
Date: Thu, 7 Jun 2012 22:00:37 +0400
|
|
Subject: [PATCH 6/9] Fix GC_scratch_alloc and GC_get_maps invocations to
|
|
prevent SEGV (if out of memory)
|
|
|
|
* dyn_load.c (GC_register_dynamic_libraries): If GC_scratch_alloc
|
|
fails (returns null) then abort (with the appropriate message) instead
|
|
of causing SEGV.
|
|
* os_dep.c (GC_dirty_init): Likewise.
|
|
* headers.c (GC_init_headers): Report error and exit if
|
|
GC_scratch_alloc fails.
|
|
* include/private/gc_priv.h (GC_scratch_alloc): Improve comment.
|
|
* os_dep.c (GC_print_address_map): If GC_get_maps return null then
|
|
print the appropriate message (instead of passing null to GC_err_puts
|
|
thus causing SEGV).
|
|
---
|
|
dyn_load.c | 2 ++
|
|
headers.c | 4 ++++
|
|
include/private/gc_priv.h | 2 +-
|
|
os_dep.c | 7 ++++++-
|
|
4 files changed, 13 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/dyn_load.c b/dyn_load.c
|
|
index a543d9e..39efc9b 100644
|
|
--- a/dyn_load.c
|
|
+++ b/dyn_load.c
|
|
@@ -760,6 +760,8 @@ GC_INNER void GC_register_dynamic_libraries(void)
|
|
/* Expansion, plus room for 0 record */
|
|
addr_map = (prmap_t *)GC_scratch_alloc(
|
|
(word)current_sz * sizeof(prmap_t));
|
|
+ if (addr_map == NULL)
|
|
+ ABORT("Insufficient memory for address map");
|
|
}
|
|
if (ioctl(fd, PIOCMAP, addr_map) < 0) {
|
|
GC_err_printf("fd = %d, errno = %d, needed_sz = %d, addr_map = %p\n",
|
|
diff --git a/headers.c b/headers.c
|
|
index de82c20..eac3e9f 100644
|
|
--- a/headers.c
|
|
+++ b/headers.c
|
|
@@ -196,6 +196,10 @@ GC_INNER void GC_init_headers(void)
|
|
register unsigned i;
|
|
|
|
GC_all_nils = (bottom_index *)GC_scratch_alloc((word)sizeof(bottom_index));
|
|
+ if (GC_all_nils == NULL) {
|
|
+ GC_err_printf("Insufficient memory for GC_all_nils\n");
|
|
+ EXIT();
|
|
+ }
|
|
BZERO(GC_all_nils, sizeof(bottom_index));
|
|
for (i = 0; i < TOP_SZ; i++) {
|
|
GC_top_index[i] = GC_all_nils;
|
|
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
|
|
index 9d728a9..b44347f 100644
|
|
--- a/include/private/gc_priv.h
|
|
+++ b/include/private/gc_priv.h
|
|
@@ -1589,7 +1589,7 @@ GC_INNER void GC_unpromote_black_lists(void);
|
|
GC_INNER ptr_t GC_scratch_alloc(size_t bytes);
|
|
/* GC internal memory allocation for */
|
|
/* small objects. Deallocation is not */
|
|
- /* possible. */
|
|
+ /* possible. May return NULL. */
|
|
|
|
/* Heap block layout maps: */
|
|
GC_INNER GC_bool GC_add_map_entry(size_t sz);
|
|
diff --git a/os_dep.c b/os_dep.c
|
|
index c1b7f20..333421d 100644
|
|
--- a/os_dep.c
|
|
+++ b/os_dep.c
|
|
@@ -3641,6 +3641,8 @@ GC_INNER void GC_dirty_init(void)
|
|
|
|
GC_dirty_maintained = TRUE;
|
|
GC_proc_buf = GC_scratch_alloc(GC_proc_buf_size);
|
|
+ if (GC_proc_buf == NULL)
|
|
+ ABORT("Insufficient space for /proc read");
|
|
}
|
|
|
|
# define READ read
|
|
@@ -4724,8 +4726,11 @@ GC_INNER void GC_print_callers(struct callinfo info[NFRAMES])
|
|
/* addresses in FIND_LEAK output. */
|
|
void GC_print_address_map(void)
|
|
{
|
|
+ char *maps;
|
|
+
|
|
GC_err_printf("---------- Begin address map ----------\n");
|
|
- GC_err_puts(GC_get_maps());
|
|
+ maps = GC_get_maps();
|
|
+ GC_err_puts(maps != NULL ? maps : "Failed to get map!\n");
|
|
GC_err_printf("---------- End address map ----------\n");
|
|
}
|
|
#endif /* LINUX && ELF */
|
|
--
|
|
1.7.10.2
|
|
|