[LTP] [PATCH] syscalls/mmap17.c: Add new regression test

Jan Stancek jstancek@redhat.com
Mon Feb 5 12:42:01 CET 2018


----- Original Message -----
> On 2018/02/02 18:20, Jan Stancek wrote:
> >
> > ----- Original Message -----
> >> We add a regression test to check if mmap() can't map invalid physical
> >> addresses.  If mmap() maps /dev/mem offsets outside of the addressable
> >> limits of a system, setting reserved bits corrupts the page table and
> >> triggers a kernel crash.
> >>
> >> The kernel bug has been fixed by:
> >> 'commit ce56a86 ("x86/mm: Limit mmap() of /dev/mem to valid physical
> >> addresses")'
> >>
> >> Signed-off-by: Xiao Yang<yangx.jy@cn.fujitsu.com>
> >> ---
> >>   runtest/syscalls                        |  1 +
> >>   testcases/kernel/syscalls/.gitignore    |  1 +
> >>   testcases/kernel/syscalls/mmap/mmap17.c | 81
> >>   +++++++++++++++++++++++++++++++++
> >>   3 files changed, 83 insertions(+)
> >>   create mode 100644 testcases/kernel/syscalls/mmap/mmap17.c
> >>
> >> diff --git a/runtest/syscalls b/runtest/syscalls
> >> index 2a4fad0..4342f03 100644
> >> --- a/runtest/syscalls
> >> +++ b/runtest/syscalls
> >> @@ -641,6 +641,7 @@ mmap14 mmap14
> >>   #mmap11 mmap11 -i 30000
> >>   mmap15 mmap15
> >>   mmap16 mmap16
> >> +mmap17 mmap17
> >>
> >>   modify_ldt01 modify_ldt01
> >>   modify_ldt02 modify_ldt02
> >> diff --git a/testcases/kernel/syscalls/.gitignore
> >> b/testcases/kernel/syscalls/.gitignore
> >> index 67211ca..6a8560a 100644
> >> --- a/testcases/kernel/syscalls/.gitignore
> >> +++ b/testcases/kernel/syscalls/.gitignore
> >> @@ -584,6 +584,7 @@
> >>   /mmap/mmap14
> >>   /mmap/mmap15
> >>   /mmap/mmap16
> >> +/mmap/mmap17
> >>   /modify_ldt/modify_ldt01
> >>   /modify_ldt/modify_ldt02
> >>   /modify_ldt/modify_ldt03
> >> diff --git a/testcases/kernel/syscalls/mmap/mmap17.c
> >> b/testcases/kernel/syscalls/mmap/mmap17.c
> >> new file mode 100644
> >> index 0000000..b83050f
> >> --- /dev/null
> >> +++ b/testcases/kernel/syscalls/mmap/mmap17.c
> >> @@ -0,0 +1,81 @@
> >> +/*
> >> + * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
> >> + * Author: Xiao Yang<yangx.jy@cn.fujitsu.com>
> >> + *
> >> + * This program is free software;  you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY;  without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> >> + * the GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> along
> >> + * with this program; if not, see<http://www.gnu.org/licenses/>.
> >> + */
> >> +
> >> +/*
> >> + * Description:
> >> + * A regression test to check if mmap() can't map invalid physical
> >> addresses.
> >> + * If mmap() maps /dev/mem offsets outside of the addressable limits of a
> >> + * system, setting reserved bits corrupts the page table and triggers a
> >> kernel
> >> + * crash.
> >> + *
> >> + * The kernel bug has been fixed by:
> >> + * 'commit ce56a86 ("x86/mm: Limit mmap() of /dev/mem to valid physical
> >> addresses")'
> >> + */
> >> +
> >> +#include<errno.h>
> >> +#include<unistd.h>
> >> +#include<sys/mman.h>
> >> +
> >> +#include "tst_test.h"
> >> +
> >> +#define MEM_PATH	"/dev/mem"
> >> +#define CPUINFO_PATH	"/proc/cpuinfo"
> >> +
> >> +static int fd;
> >> +static int phy_addr_bits;
> >> +
> >> +static void verify_mmap(void)
> >> +{
> >> +	char *addr;
> >> +
> >> +	addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
> >> +		    1ULL<<phy_addr_bits);
> >> +	if (addr == MAP_FAILED) {
> >> +		tst_res(TPASS | TERRNO,
> >> +			"Refused to map invalid physical address");
> >> +		return;
> >> +	}
> >> +
> >> +	addr[0] = 'a';
> >> +	SAFE_MUNMAP(addr, 1);
> >> +	tst_res(TFAIL, "Mapped and set invalid physical address successfully");
> >> +}
> >> +
> >> +static void setup(void)
> >> +{
> >> +	if (access(MEM_PATH, F_OK))
> >> +		tst_brk(TCONF, "%s didn't exist", MEM_PATH);
> >> +
> >> +	fd = SAFE_OPEN(MEM_PATH, O_RDWR | O_SYNC);
> >> +
> >> +	SAFE_FILE_LINES_SCANF(CPUINFO_PATH, "address sizes\t: %d",
> >> +			&phy_addr_bits);
> > This looks like a problem for architectures other than x86:
> >
> > $ grep -l "address sizes" -r arch/
> > arch/sh/kernel/cpu/proc.c
> > arch/x86/kernel/cpu/proc.c
> > arch/x86/kernel/umip.c
> > arch/x86/lib/insn-eval.c
> Hi Jan,
> 
> I tried to find a generic way to get physical address bits from all
> architectures, but failed.
> Do you know how to get physical address bits in generic way?

Maybe some /proc or /sys that exposes max (arch) pfn?

> 
> If we don't have a better way, can we just test the bug which is fixed for
> x86 on x86 architecture?

The patch you referenced is x86 specific, so we can restrict the test to x86.
Also please set the minimum kernel version this is expected to fail on.

Regards,
Jan


More information about the ltp mailing list