-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0006-loader-Explicitly-munmap-the-preloader-s-ELF-EHDR.mypatch
127 lines (111 loc) · 4.4 KB
/
0006-loader-Explicitly-munmap-the-preloader-s-ELF-EHDR.mypatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From c4217da4e458428c701e02cb67d27dd5db147100 Mon Sep 17 00:00:00 2001
From: Jinoh Kang <[email protected]>
Date: Wed, 29 Dec 2021 23:29:36 +0900
Subject: [PATCH 06/13] loader: Explicitly munmap() the preloader's ELF EHDR.
Today, the preloader reserves some predefined address ranges without
checking if there are any overlapping virtual memory mappings.
One side effect of this behaviour is that the preloader's ELF EHDR gets
unmapped. Note the following overlapping address ranges:
- 0x00110000 - 0x68000000: low memory area (preload_info)
- 0x08040000 - 0x08041000: preloader ELF EHDR (x86)
- 0x00400000 - 0x00401000: preloader ELF EHDR (AMD64)
In practice, unmapping the preloader ELF EHDR is harmless; this is
because the dynamic linker does not recognise the preloader binary.
Make the unmapping behaviour explicit by calling munmap() on the
preloader's ELF EHDR.
Signed-off-by: Jinoh Kang <[email protected]>
---
loader/preloader.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/loader/preloader.c b/loader/preloader.c
index fb22eff5f61..3f1d4ff7b21 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -223,6 +223,7 @@ struct
* then jumps to the address wld_start returns.
*/
void _start(void);
+extern char __executable_start[];
extern char _end[];
__ASM_GLOBAL_FUNC(_start,
__ASM_CFI("\t.cfi_undefined %eip\n")
@@ -342,6 +343,15 @@ __ASM_GLOBAL_FUNC(wld_mmap,
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
"\tret\n" )
+static inline int wld_munmap( void *addr, size_t len )
+{
+ long ret;
+ __asm__ __volatile__( "int $0x80"
+ : "=a" (ret) : "0" (91 /* SYS_munmap */), "b" (addr), "c" (len)
+ : "memory" );
+ return SYSCALL_RET(ret);
+}
+
static inline int wld_prctl( int code, long arg )
{
long ret;
@@ -361,6 +371,7 @@ void *thread_data[256];
* then jumps to the address wld_start returns.
*/
void _start(void);
+extern char __executable_start[];
extern char _end[];
__ASM_GLOBAL_FUNC(_start,
__ASM_CFI(".cfi_undefined %rip\n\t")
@@ -424,6 +435,9 @@ SYSCALL_FUNC( wld_mmap, 9 /* SYS_mmap */ );
int wld_mprotect( const void *addr, size_t len, int prot );
SYSCALL_FUNC( wld_mprotect, 10 /* SYS_mprotect */ );
+int wld_munmap( void *addr, size_t len );
+SYSCALL_FUNC( wld_munmap, 11 /* SYS_munmap */ );
+
int wld_prctl( int code, long arg );
SYSCALL_FUNC( wld_prctl, 157 /* SYS_prctl */ );
@@ -450,6 +464,7 @@ void *thread_data[256];
* then jumps to the address wld_start returns.
*/
void _start(void);
+extern char __executable_start[];
extern char _end[];
__ASM_GLOBAL_FUNC(_start,
"mov x0, SP\n\t"
@@ -530,6 +545,9 @@ SYSCALL_FUNC( wld_mmap, 222 /* SYS_mmap */ );
int wld_mprotect( const void *addr, size_t len, int prot );
SYSCALL_FUNC( wld_mprotect, 226 /* SYS_mprotect */ );
+int wld_munmap( void *addr, size_t len );
+SYSCALL_FUNC( wld_munmap, 215 /* SYS_munmap */ );
+
int wld_prctl( int code, long arg );
SYSCALL_FUNC( wld_prctl, 167 /* SYS_prctl */ );
@@ -556,6 +574,7 @@ void *thread_data[256];
* then jumps to the address wld_start returns.
*/
void _start(void);
+extern char __executable_start[];
extern char _end[];
__ASM_GLOBAL_FUNC(_start,
"mov r0, sp\n\t"
@@ -628,6 +647,9 @@ void *wld_mmap( void *start, size_t len, int prot, int flags, int fd, off_t offs
int wld_mprotect( const void *addr, size_t len, int prot );
SYSCALL_FUNC( wld_mprotect, 125 /* SYS_mprotect */ );
+int wld_munmap( void *addr, size_t len );
+SYSCALL_FUNC( wld_munmap, 91 /* SYS_munmap */ );
+
int wld_prctl( int code, long arg );
SYSCALL_FUNC( wld_prctl, 172 /* SYS_prctl */ );
@@ -1527,6 +1549,14 @@ void* wld_start( void **stack )
preloader_start = (char *)_start - ((unsigned long)_start & page_mask);
preloader_end = (char *)((unsigned long)(_end + page_mask) & ~page_mask);
+ if ((unsigned long)preloader_start >= (unsigned long)__executable_start + page_size)
+ {
+ /* Unmap preloader's ELF EHDR */
+ wld_munmap( __executable_start,
+ ((unsigned long)preloader_start -
+ (unsigned long)__executable_start) & ~page_mask );
+ }
+
#ifdef DUMP_AUX_INFO
wld_printf( "stack = %p\n", state.s.stack );
for( i = 0; i < state.s.argc; i++ ) wld_printf("argv[%lx] = %s\n", i, state.s.argv[i]);
--
2.31.1