Skip to content

Commit 42e7645

Browse files
committed
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-3.0-pull-request' into staging
Fix safe_syscall() on ppc64 host Fix mmap() 0 length error case # gpg: Signature made Tue 31 Jul 2018 09:41:07 BST # gpg: using RSA key F30C38BD3F2FBE3C # gpg: Good signature from "Laurent Vivier <[email protected]>" # gpg: aka "Laurent Vivier <[email protected]>" # gpg: aka "Laurent Vivier (Red Hat) <[email protected]>" # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-3.0-pull-request: linux-user: ppc64: don't use volatile register during safe_syscall tests: add check_invalid_maps to test-mmap linux-user/mmap.c: handle invalid len maps correctly Signed-off-by: Peter Maydell <[email protected]>
2 parents 45a505d + 5d9f3ea commit 42e7645

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

linux-user/host/ppc64/safe-syscall.inc.S

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ safe_syscall_base:
4949
* and returns the result in r3
5050
* Shuffle everything around appropriately.
5151
*/
52-
mr 11, 3 /* signal_pending */
52+
std 14, 16(1) /* Preserve r14 in SP+16 */
53+
.cfi_offset 14, 16
54+
mr 14, 3 /* signal_pending */
5355
mr 0, 4 /* syscall number */
5456
mr 3, 5 /* syscall arguments */
5557
mr 4, 6
@@ -67,12 +69,13 @@ safe_syscall_base:
6769
*/
6870
safe_syscall_start:
6971
/* if signal_pending is non-zero, don't do the call */
70-
lwz 12, 0(11)
72+
lwz 12, 0(14)
7173
cmpwi 0, 12, 0
7274
bne- 0f
7375
sc
7476
safe_syscall_end:
7577
/* code path when we did execute the syscall */
78+
ld 14, 16(1) /* restore r14 to its original value */
7679
bnslr+
7780

7881
/* syscall failed; return negative errno */
@@ -81,6 +84,7 @@ safe_syscall_end:
8184

8285
/* code path when we didn't execute the syscall */
8386
0: addi 3, 0, -TARGET_ERESTARTSYS
87+
ld 14, 16(1) /* restore r14 to its orginal value */
8488
blr
8589
.cfi_endproc
8690

linux-user/mmap.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,14 +391,23 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
391391
}
392392
#endif
393393

394-
if (offset & ~TARGET_PAGE_MASK) {
394+
if (!len) {
395395
errno = EINVAL;
396396
goto fail;
397397
}
398398

399+
/* Also check for overflows... */
399400
len = TARGET_PAGE_ALIGN(len);
400-
if (len == 0)
401-
goto the_end;
401+
if (!len) {
402+
errno = ENOMEM;
403+
goto fail;
404+
}
405+
406+
if (offset & ~TARGET_PAGE_MASK) {
407+
errno = EINVAL;
408+
goto fail;
409+
}
410+
402411
real_start = start & qemu_host_page_mask;
403412
host_offset = offset & qemu_host_page_mask;
404413

tests/tcg/multiarch/test-mmap.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <stdint.h>
2828
#include <string.h>
2929
#include <unistd.h>
30-
30+
#include <errno.h>
3131
#include <sys/mman.h>
3232

3333
#define D(x)
@@ -435,6 +435,25 @@ void checked_write(int fd, const void *buf, size_t count)
435435
fail_unless(rc == count);
436436
}
437437

438+
void check_invalid_mmaps(void)
439+
{
440+
unsigned char *addr;
441+
442+
/* Attempt to map a zero length page. */
443+
addr = mmap(NULL, 0, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
444+
fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
445+
fail_unless(addr == MAP_FAILED);
446+
fail_unless(errno == EINVAL);
447+
448+
/* Attempt to map a over length page. */
449+
addr = mmap(NULL, -4, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
450+
fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
451+
fail_unless(addr == MAP_FAILED);
452+
fail_unless(errno == ENOMEM);
453+
454+
fprintf(stdout, " passed\n");
455+
}
456+
438457
int main(int argc, char **argv)
439458
{
440459
char tempname[] = "/tmp/.cmmapXXXXXX";
@@ -476,6 +495,7 @@ int main(int argc, char **argv)
476495
check_file_fixed_mmaps();
477496
check_file_fixed_eof_mmaps();
478497
check_file_unfixed_eof_mmaps();
498+
check_invalid_mmaps();
479499

480500
/* Fails at the moment. */
481501
/* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */

0 commit comments

Comments
 (0)