diff options
author | Philip Sanderson <philip.k.sanderson@gmail.com> | 2011-01-20 22:37:28 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-01-20 06:07:29 -0500 |
commit | 5230ff0cccb0611830bb02b097535868df02752a (patch) | |
tree | 7d1345e1ede12e2fd85918c9944fe929017cde6b /Documentation | |
parent | 8aeb36e8f6d7eaa9cafc970b700414205743b258 (diff) |
lguest: example launcher to use guard pages, drop PROT_EXEC, fix limit logic
PROT_EXEC seems to be completely unnecessary (as the lguest binary
never executes there), and will allow it to work with SELinux (and
more importantly, PaX :-) as they can/do forbid writable and
executable mappings.
Also, map PROT_NONE guard pages at start and end of guest memory for extra
paranoia.
I changed the length check to addr + size > guest_limit because >= is wrong
(addr of 0, size of getpagesize() with a guest_limit of getpagesize() would
false positive).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/lguest/lguest.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index f64b85bcd6d4..d9da7e148538 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -301,20 +301,27 @@ static void *map_zeroed_pages(unsigned int num) | |||
301 | 301 | ||
302 | /* | 302 | /* |
303 | * We use a private mapping (ie. if we write to the page, it will be | 303 | * We use a private mapping (ie. if we write to the page, it will be |
304 | * copied). | 304 | * copied). We allocate an extra two pages PROT_NONE to act as guard |
305 | * pages against read/write attempts that exceed allocated space. | ||
305 | */ | 306 | */ |
306 | addr = mmap(NULL, getpagesize() * num, | 307 | addr = mmap(NULL, getpagesize() * (num+2), |
307 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); | 308 | PROT_NONE, MAP_PRIVATE, fd, 0); |
309 | |||
308 | if (addr == MAP_FAILED) | 310 | if (addr == MAP_FAILED) |
309 | err(1, "Mmapping %u pages of /dev/zero", num); | 311 | err(1, "Mmapping %u pages of /dev/zero", num); |
310 | 312 | ||
313 | if (mprotect(addr + getpagesize(), getpagesize() * num, | ||
314 | PROT_READ|PROT_WRITE) == -1) | ||
315 | err(1, "mprotect rw %u pages failed", num); | ||
316 | |||
311 | /* | 317 | /* |
312 | * One neat mmap feature is that you can close the fd, and it | 318 | * One neat mmap feature is that you can close the fd, and it |
313 | * stays mapped. | 319 | * stays mapped. |
314 | */ | 320 | */ |
315 | close(fd); | 321 | close(fd); |
316 | 322 | ||
317 | return addr; | 323 | /* Return address after PROT_NONE page */ |
324 | return addr + getpagesize(); | ||
318 | } | 325 | } |
319 | 326 | ||
320 | /* Get some more pages for a device. */ | 327 | /* Get some more pages for a device. */ |
@@ -346,7 +353,7 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len) | |||
346 | * done to it. This allows us to share untouched memory between | 353 | * done to it. This allows us to share untouched memory between |
347 | * Guests. | 354 | * Guests. |
348 | */ | 355 | */ |
349 | if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC, | 356 | if (mmap(addr, len, PROT_READ|PROT_WRITE, |
350 | MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) | 357 | MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) |
351 | return; | 358 | return; |
352 | 359 | ||
@@ -576,10 +583,10 @@ static void *_check_pointer(unsigned long addr, unsigned int size, | |||
576 | unsigned int line) | 583 | unsigned int line) |
577 | { | 584 | { |
578 | /* | 585 | /* |
579 | * We have to separately check addr and addr+size, because size could | 586 | * Check if the requested address and size exceeds the allocated memory, |
580 | * be huge and addr + size might wrap around. | 587 | * or addr + size wraps around. |
581 | */ | 588 | */ |
582 | if (addr >= guest_limit || addr + size >= guest_limit) | 589 | if ((addr + size) > guest_limit || (addr + size) < addr) |
583 | errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); | 590 | errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); |
584 | /* | 591 | /* |
585 | * We return a pointer for the caller's convenience, now we know it's | 592 | * We return a pointer for the caller's convenience, now we know it's |