Commit 36b042fb authored by Simon Marlow's avatar Simon Marlow

Make integer overflow less likely to happen (#7762)

The particular problematic code in #7762 was this:

            nat newSize = size - n;
            char *freeAddr = MBLOCK_ROUND_DOWN(bd->start);
            freeAddr += newSize * MBLOCK_SIZE;
                        ^^^^^^^^^^^^^^^^^^^^^^  OVERFLOW!!!

For good measure, I'm going to fix the bug twice.  This patch fixes
the class of bugs of this kind, by making sure that any expressions
involving BLOCK_SIZE or MBLOCK_SIZE are promoted to unsigned long.  In
a separate patch, I'll fix a bunch of individual instances (including
the one above).
parent 29be1a8a
......@@ -15,7 +15,13 @@
/* Block related constants (BLOCK_SHIFT is defined in Constants.h) */
// Note [integer overflow]
#define BLOCK_SIZE_W (BLOCK_SIZE/sizeof(W_))
......@@ -24,7 +30,13 @@
/* Megablock related constants (MBLOCK_SHIFT is defined in Constants.h) */
// Note [integer overflow]
#define MBLOCK_SIZE_W (MBLOCK_SIZE/sizeof(W_))
......@@ -37,6 +49,18 @@
#define LARGE_OBJECT_THRESHOLD ((nat)(BLOCK_SIZE * 8 / 10))
* Note [integer overflow]
* The UL suffix in BLOCK_SIZE and MBLOCK_SIZE promotes the expression
* to an unsigned long, which means that expressions involving these
* will be promoted to unsigned long, which makes integer overflow
* less likely. Historically, integer overflow in expressions like
* (n * BLOCK_SIZE)
* where n is int or unsigned int, have caused obscure segfaults in
* programs that use large amounts of memory (e.g. #7762, #5086).
/* -----------------------------------------------------------------------------
* Block descriptor. This structure *must* be the right length, so we
* can do pointer arithmetic on pointers to it.
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment