this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mldr: Don't overwrite existing memory when loading files

Also, don't worry about failures mapping PAGEZERO; sane systems
already map out enough pages to reserve the area around `NULL`
as invalid memory.

This should fix some crashes that some users were getting (with mldr overwriting itself).

+11 -5
+11 -5
src/startup/mldr/loader.c
··· 167 167 addr += slide; 168 168 169 169 // Some segments' filesize != vmsize, thus this mprotect(). 170 - rv = mmap((void*)addr, seg->vmsize, useprot, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); 170 + rv = mmap((void*)addr, seg->vmsize, useprot, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0); 171 171 if (rv == (void*)MAP_FAILED) 172 172 { 173 - fprintf(stderr, "Cannot mmap segment %s at %p: %s\n", seg->segname, (void*)(uintptr_t)seg->vmaddr, strerror(errno)); 174 - exit(1); 173 + if (addr == 0 && useprot == 0) { 174 + // this is the PAGEZERO segment; 175 + // if we can't map it, assume everything is fine and the system has already made that area inaccessible 176 + rv = 0; 177 + } else { 178 + fprintf(stderr, "Cannot mmap segment %s at %p: %s\n", seg->segname, (void*)(uintptr_t)seg->vmaddr, strerror(errno)); 179 + exit(1); 180 + } 175 181 } 176 182 } 177 183 else 178 184 { 179 185 size_t size = seg->vmsize - seg->filesize; 180 186 rv = mmap((void*) PAGE_ALIGN(seg->vmaddr + seg->vmsize - size), PAGE_ROUNDUP(size), useprot, 181 - MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); 187 + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0); 182 188 if (rv == (void*)MAP_FAILED) 183 189 { 184 190 fprintf(stderr, "Cannot mmap segment %s at %p: %s\n", seg->segname, (void*)(uintptr_t)seg->vmaddr, strerror(errno)); ··· 191 197 { 192 198 unsigned long addr = seg->vmaddr + slide; 193 199 rv = mmap((void*)addr, seg->filesize, useprot, 194 - MAP_FIXED | MAP_PRIVATE, fd, seg->fileoff + fat_offset); 200 + MAP_FIXED_NOREPLACE | MAP_PRIVATE, fd, seg->fileoff + fat_offset); 195 201 if (rv == (void*)MAP_FAILED) 196 202 { 197 203 fprintf(stderr, "Cannot mmap segment %s at %p: %s\n", seg->segname, (void*)(uintptr_t)seg->vmaddr, strerror(errno));