@@ -830,6 +830,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
830
830
struct elf_phdr * elf_ppnt , * elf_phdata , * interp_elf_phdata = NULL ;
831
831
struct elf_phdr * elf_property_phdata = NULL ;
832
832
unsigned long elf_brk ;
833
+ bool brk_moved = false;
833
834
int retval , i ;
834
835
unsigned long elf_entry ;
835
836
unsigned long e_entry ;
@@ -1097,15 +1098,19 @@ static int load_elf_binary(struct linux_binprm *bprm)
1097
1098
/* Calculate any requested alignment. */
1098
1099
alignment = maximum_alignment (elf_phdata , elf_ex -> e_phnum );
1099
1100
1100
- /*
1101
- * There are effectively two types of ET_DYN
1102
- * binaries: programs (i.e. PIE: ET_DYN with PT_INTERP)
1103
- * and loaders (ET_DYN without PT_INTERP, since they
1104
- * _are_ the ELF interpreter). The loaders must
1105
- * be loaded away from programs since the program
1106
- * may otherwise collide with the loader (especially
1107
- * for ET_EXEC which does not have a randomized
1108
- * position). For example to handle invocations of
1101
+ /**
1102
+ * DOC: PIE handling
1103
+ *
1104
+ * There are effectively two types of ET_DYN ELF
1105
+ * binaries: programs (i.e. PIE: ET_DYN with
1106
+ * PT_INTERP) and loaders (i.e. static PIE: ET_DYN
1107
+ * without PT_INTERP, usually the ELF interpreter
1108
+ * itself). Loaders must be loaded away from programs
1109
+ * since the program may otherwise collide with the
1110
+ * loader (especially for ET_EXEC which does not have
1111
+ * a randomized position).
1112
+ *
1113
+ * For example, to handle invocations of
1109
1114
* "./ld.so someprog" to test out a new version of
1110
1115
* the loader, the subsequent program that the
1111
1116
* loader loads must avoid the loader itself, so
@@ -1118,6 +1123,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
1118
1123
* ELF_ET_DYN_BASE and loaders are loaded into the
1119
1124
* independently randomized mmap region (0 load_bias
1120
1125
* without MAP_FIXED nor MAP_FIXED_NOREPLACE).
1126
+ *
1127
+ * See below for "brk" handling details, which is
1128
+ * also affected by program vs loader and ASLR.
1121
1129
*/
1122
1130
if (interpreter ) {
1123
1131
/* On ET_DYN with PT_INTERP, we do the ASLR. */
@@ -1234,8 +1242,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
1234
1242
start_data += load_bias ;
1235
1243
end_data += load_bias ;
1236
1244
1237
- current -> mm -> start_brk = current -> mm -> brk = ELF_PAGEALIGN (elf_brk );
1238
-
1239
1245
if (interpreter ) {
1240
1246
elf_entry = load_elf_interp (interp_elf_ex ,
1241
1247
interpreter ,
@@ -1291,27 +1297,44 @@ static int load_elf_binary(struct linux_binprm *bprm)
1291
1297
mm -> end_data = end_data ;
1292
1298
mm -> start_stack = bprm -> p ;
1293
1299
1294
- if ((current -> flags & PF_RANDOMIZE ) && (snapshot_randomize_va_space > 1 )) {
1300
+ /**
1301
+ * DOC: "brk" handling
1302
+ *
1303
+ * For architectures with ELF randomization, when executing a
1304
+ * loader directly (i.e. static PIE: ET_DYN without PT_INTERP),
1305
+ * move the brk area out of the mmap region and into the unused
1306
+ * ELF_ET_DYN_BASE region. Since "brk" grows up it may collide
1307
+ * early with the stack growing down or other regions being put
1308
+ * into the mmap region by the kernel (e.g. vdso).
1309
+ *
1310
+ * In the CONFIG_COMPAT_BRK case, though, everything is turned
1311
+ * off because we're not allowed to move the brk at all.
1312
+ */
1313
+ if (!IS_ENABLED (CONFIG_COMPAT_BRK ) &&
1314
+ IS_ENABLED (CONFIG_ARCH_HAS_ELF_RANDOMIZE ) &&
1315
+ elf_ex -> e_type == ET_DYN && !interpreter ) {
1316
+ elf_brk = ELF_ET_DYN_BASE ;
1317
+ /* This counts as moving the brk, so let brk(2) know. */
1318
+ brk_moved = true;
1319
+ }
1320
+ mm -> start_brk = mm -> brk = ELF_PAGEALIGN (elf_brk );
1321
+
1322
+ if ((current -> flags & PF_RANDOMIZE ) && snapshot_randomize_va_space > 1 ) {
1295
1323
/*
1296
- * For architectures with ELF randomization, when executing
1297
- * a loader directly (i.e. no interpreter listed in ELF
1298
- * headers), move the brk area out of the mmap region
1299
- * (since it grows up, and may collide early with the stack
1300
- * growing down), and into the unused ELF_ET_DYN_BASE region.
1324
+ * If we didn't move the brk to ELF_ET_DYN_BASE (above),
1325
+ * leave a gap between .bss and brk.
1301
1326
*/
1302
- if (IS_ENABLED (CONFIG_ARCH_HAS_ELF_RANDOMIZE ) &&
1303
- elf_ex -> e_type == ET_DYN && !interpreter ) {
1304
- mm -> brk = mm -> start_brk = ELF_ET_DYN_BASE ;
1305
- } else {
1306
- /* Otherwise leave a gap between .bss and brk. */
1327
+ if (!brk_moved )
1307
1328
mm -> brk = mm -> start_brk = mm -> brk + PAGE_SIZE ;
1308
- }
1309
1329
1310
1330
mm -> brk = mm -> start_brk = arch_randomize_brk (mm );
1331
+ brk_moved = true;
1332
+ }
1333
+
1311
1334
#ifdef compat_brk_randomized
1335
+ if (brk_moved )
1312
1336
current -> brk_randomized = 1 ;
1313
1337
#endif
1314
- }
1315
1338
1316
1339
if (current -> personality & MMAP_PAGE_ZERO ) {
1317
1340
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
0 commit comments