summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Mulder <hansmu@xs4all.nl>1997-06-15 23:26:35 +1200
committerTim Bunce <Tim.Bunce@ig.co.uk>1997-08-07 00:00:00 +1200
commit57569e04d232667a3e52996dff0f1e57f7d36b43 (patch)
treef9fef4c94a68dafd8316e9f5e7665b2e8d8913b7
parentc9de509e331450a10058399280ce28f68f0faf39 (diff)
downloadperl-57569e04d232667a3e52996dff0f1e57f7d36b43.tar.gz
infinite recursion in malloc() with some compile flags
Apologies if you see this twice, but I'm afraid my first attempt fell into a black hole. Neither Achim's archive nor the NNTP gateway seem to have recieved it. If one tries to compile perl with all of -DPACK_MALLOC -DHIDEMYMALLOC -DUSE_PERL_SBRK -DPERL_SBRK_VIA_MALLOC then it's almost certain that miniperl will overflow the C stack on its first attempt to call malloc(). This happens because with -DPACK_MALLOC Perl_malloc() expects sbrk() to return 2K-aligned blocks and Perl_sbrk() provides the same sort of alignments as the system malloc(), i.e. 8 bytes or so. When Perl_malloc() notices the block returned by sbrk() isn't properly aligned, it tries to croak("panic: Off-page sbrk"). Croak() calls mess(); mess() calls mess_alloc(); mess_alloc() calls Perl_malloc(); Perl_malloc() again calls croak() and so on until the C stack overflows. I see two problems here; 1. With -DPACK_MALLOC, Perl_sbrk() should return 2K-aligned blocks. 2. croak() should not recurse infinitely. The patch below deals with #1. I'll think some more about #2. p5p-msgid: 199706240050.CAA10550@xs2.xs4all.nl
-rw-r--r--malloc.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/malloc.c b/malloc.c
index e9b200ba69..3aeb08846c 100644
--- a/malloc.c
+++ b/malloc.c
@@ -781,6 +781,9 @@ int size;
#ifdef PERL_CORE
reqsize = size; /* just for the DEBUG_m statement */
#endif
+#ifdef PACK_MALLOC
+ size = (size + 0x7ff) & ~0x7ff;
+#endif
if (size <= Perl_sbrk_oldsize) {
got = Perl_sbrk_oldchunk;
Perl_sbrk_oldchunk += size;
@@ -796,6 +799,9 @@ int size;
small = 1;
}
got = (IV)SYSTEM_ALLOC(size);
+#ifdef PACK_MALLOC
+ got = (got + 0x7ff) & ~0x7ff;
+#endif
if (small) {
/* Chunk is small, register the rest for future allocs. */
Perl_sbrk_oldchunk = got + reqsize;