Skip to content

Commit 33f98a9

Browse files
keesPeter Zijlstra
authored andcommitted
x86/boot/compressed: Avoid duplicate malloc() implementations
The early malloc() and free() implementation in include/linux/decompress/mm.h (which is also included by the static decompressors) is static. This is fine when the only thing interested in using malloc() is the decompression code, but the x86 early boot environment may use malloc() in a couple places, leading to a potential collision when the static copies of the available memory region ("malloc_ptr") gets reset to the global "free_mem_ptr" value. As it happened, the existing usage pattern was accidentally safe because each user did 1 malloc() and 1 free() before returning and were not nested: extract_kernel() (misc.c) choose_random_location() (kaslr.c) mem_avoid_init() handle_mem_options() malloc() ... free() ... parse_elf() (misc.c) malloc() ... free() Once the future FGKASLR series is added, however, it will insert additional malloc() calls local to fgkaslr.c in the middle of parse_elf()'s malloc()/free() pair: parse_elf() (misc.c) malloc() if (...) { layout_randomized_image(output, &ehdr, phdrs); malloc() <- boom ... else layout_image(output, &ehdr, phdrs); free() To avoid collisions, there must be a single implementation of malloc(). Adjust include/linux/decompress/mm.h so that visibility can be controlled, provide prototypes in misc.h, and implement the functions in misc.c. This also results in a small size savings: $ size vmlinux.before vmlinux.after text data bss dec hex filename 8842314 468 178320 9021102 89a6ae vmlinux.before 8842240 468 178320 9021028 89a664 vmlinux.after Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0d054d4 commit 33f98a9

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

arch/x86/boot/compressed/kaslr.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@
3232
#include <generated/utsrelease.h>
3333
#include <asm/efi.h>
3434

35-
/* Macros used by the included decompressor code below. */
36-
#define STATIC
37-
#include <linux/decompress/mm.h>
38-
3935
#define _SETUP
4036
#include <asm/setup.h> /* For COMMAND_LINE_SIZE */
4137
#undef _SETUP

arch/x86/boot/compressed/misc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828

2929
/* Macros used by the included decompressor code below. */
3030
#define STATIC static
31+
/* Define an externally visible malloc()/free(). */
32+
#define MALLOC_VISIBLE
33+
#include <linux/decompress/mm.h>
3134

3235
/*
3336
* Provide definitions of memzero and memmove as some of the decompressors will

arch/x86/boot/compressed/misc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ extern char _head[], _end[];
4444
/* misc.c */
4545
extern memptr free_mem_ptr;
4646
extern memptr free_mem_end_ptr;
47+
void *malloc(int size);
48+
void free(void *where);
4749
extern struct boot_params *boot_params;
4850
void __putstr(const char *s);
4951
void __puthex(unsigned long value);

include/linux/decompress/mm.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@
2525
#define STATIC_RW_DATA static
2626
#endif
2727

28+
/*
29+
* When an architecture needs to share the malloc()/free() implementation
30+
* between compilation units, it needs to have non-local visibility.
31+
*/
32+
#ifndef MALLOC_VISIBLE
33+
#define MALLOC_VISIBLE static
34+
#endif
35+
2836
/* A trivial malloc implementation, adapted from
2937
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
3038
*/
3139
STATIC_RW_DATA unsigned long malloc_ptr;
3240
STATIC_RW_DATA int malloc_count;
3341

34-
static void *malloc(int size)
42+
MALLOC_VISIBLE void *malloc(int size)
3543
{
3644
void *p;
3745

@@ -52,7 +60,7 @@ static void *malloc(int size)
5260
return p;
5361
}
5462

55-
static void free(void *where)
63+
MALLOC_VISIBLE void free(void *where)
5664
{
5765
malloc_count--;
5866
if (!malloc_count)

0 commit comments

Comments
 (0)