All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
@ 2018-02-02 10:03 Xiao Yang
  2018-02-02 10:20 ` Jan Stancek
  0 siblings, 1 reply; 14+ messages in thread
From: Xiao Yang @ 2018-02-02 10:03 UTC (permalink / raw)
  To: ltp

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);
+}
+
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_mmap,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-02 10:03 [LTP] [PATCH] syscalls/mmap17.c: Add new regression test Xiao Yang
@ 2018-02-02 10:20 ` Jan Stancek
  2018-02-05 10:45   ` Xiao Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Stancek @ 2018-02-02 10:20 UTC (permalink / raw)
  To: ltp



----- 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

Regards,
Jan

> +}
> +
> +static void cleanup(void)
> +{
> +	if (fd > 0)
> +		SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> +	.needs_root = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_mmap,
> +};
> --
> 1.8.3.1
> 
> 
> 
> 
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-02 10:20 ` Jan Stancek
@ 2018-02-05 10:45   ` Xiao Yang
  2018-02-05 11:42     ` Jan Stancek
  0 siblings, 1 reply; 14+ messages in thread
From: Xiao Yang @ 2018-02-05 10:45 UTC (permalink / raw)
  To: ltp

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?

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

Thanks,
Xiao Yang

> Regards,
> Jan
>
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> +	if (fd>  0)
>> +		SAFE_CLOSE(fd);
>> +}
>> +
>> +static struct tst_test test = {
>> +	.needs_root = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_mmap,
>> +};
>> --
>> 1.8.3.1
>>
>>
>>
>>
>> --
>> Mailing list info: https://lists.linux.it/listinfo/ltp
>>
>
> .
>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-05 10:45   ` Xiao Yang
@ 2018-02-05 11:42     ` Jan Stancek
  2018-02-06  6:41       ` Xiao Yang
  2018-02-06  6:43       ` [LTP] [PATCH v2] " Xiao Yang
  0 siblings, 2 replies; 14+ messages in thread
From: Jan Stancek @ 2018-02-05 11:42 UTC (permalink / raw)
  To: ltp


----- 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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-05 11:42     ` Jan Stancek
@ 2018-02-06  6:41       ` Xiao Yang
  2018-02-06 19:53         ` Jan Stancek
  2018-02-06  6:43       ` [LTP] [PATCH v2] " Xiao Yang
  1 sibling, 1 reply; 14+ messages in thread
From: Xiao Yang @ 2018-02-06  6:41 UTC (permalink / raw)
  To: ltp

On 2018/02/05 19:42, Jan Stancek wrote:
> ----- 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?
Hi Jan,

Sorry, i still can't find it in /proc and /sys. :-(
>> 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.
1) Before commit c64b04f, we couldn't read phys_addr_bits from 
/proc/cpuinfo in 32-bit kernel on x86.
2) On non-x86 architectures, we couldn't read phys_addr_bits from 
/proc/cpuinfo as well.

According to above reasons, i perfer to check phys_addr_bits in 
/proc/cpuinfo rather than the minimum
kernel version and x86 architecture.   We can skip this test if 
phys_addr_bits isn't available.

Thanks,
Xiao Yang
> Regards,
> Jan
>
>
> .
>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH v2] syscalls/mmap17.c: Add new regression test
  2018-02-05 11:42     ` Jan Stancek
  2018-02-06  6:41       ` Xiao Yang
@ 2018-02-06  6:43       ` Xiao Yang
  1 sibling, 0 replies; 14+ messages in thread
From: Xiao Yang @ 2018-02-06  6:43 UTC (permalink / raw)
  To: ltp

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
may trigger 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 | 115 ++++++++++++++++++++++++++++++++
 3 files changed, 117 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..c008460
--- /dev/null
+++ b/testcases/kernel/syscalls/mmap/mmap17.c
@@ -0,0 +1,115 @@
+/*
+ * 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 may trigger 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 <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+
+#define MEM_PATH	"/dev/mem"
+#define CPUINFO_PATH	"/proc/cpuinfo"
+
+static int fd;
+static int phys_addr_bits;
+
+/* 1) Before commit c64b04f, we couldn't read phys_addr_bits from
+ *    /proc/cpuinfo in 32-bit kernel on x86.
+ * 2) On non-x86 architectures, we couldn't read phys_addr_bits from
+ *    /proc/cpuinfo as well.
+ * According to above reasons, we add a check for phys_addr_bits in
+ * /proc/cpuinfo.  We can skip this test if phys_addr_bits isn't available.
+ */
+static void check_phys_addr_bits(void)
+{
+	int existed = 0;
+	FILE *fp;
+	char line[BUFSIZ];
+
+	fp = SAFE_FOPEN(CPUINFO_PATH, "r");
+
+	while (fgets(line, BUFSIZ, fp)) {
+		if (strstr(line, "address sizes")) {
+			existed = 1;
+			break;
+		}
+	}
+
+	fclose(fp);
+
+	if (!existed) {
+		tst_brk(TCONF, "Couldn't read x86_phys_bits from %s",
+			CPUINFO_PATH);
+	}
+}
+
+static void verify_mmap(void)
+{
+	char *addr;
+
+	addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+		    1ULL<<phys_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);
+
+	check_phys_addr_bits();
+	SAFE_FILE_LINES_SCANF(CPUINFO_PATH, "address sizes\t: %d",
+			      &phys_addr_bits);
+}
+
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_mmap,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-06  6:41       ` Xiao Yang
@ 2018-02-06 19:53         ` Jan Stancek
  2018-02-06 21:15           ` Jan Stancek
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Stancek @ 2018-02-06 19:53 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> > 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.
> 1) Before commit c64b04f, we couldn't read phys_addr_bits from
> /proc/cpuinfo in 32-bit kernel on x86.
> 2) On non-x86 architectures, we couldn't read phys_addr_bits from
> /proc/cpuinfo as well.
> 
> According to above reasons, i perfer to check phys_addr_bits in
> /proc/cpuinfo rather than the minimum
> kernel version and x86 architecture.   We can skip this test if
> phys_addr_bits isn't available.

I was referring to kernel patch. Does it make sense for this test
to run on older kernels? Based on description it might crash, so
presumably yes.

But do we also want to report FAIL on older kernels if mmap succeeds?
That does not violate any docs.

> addr[0] = 'a';
If mmap works, this has potential of triggering signal,
which will lead to TBROK.

Regards,
Jan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-06 19:53         ` Jan Stancek
@ 2018-02-06 21:15           ` Jan Stancek
  2018-02-07 12:05             ` Xiao Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Stancek @ 2018-02-06 21:15 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> 
> 
> ----- Original Message -----
> > > 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.
> > 1) Before commit c64b04f, we couldn't read phys_addr_bits from
> > /proc/cpuinfo in 32-bit kernel on x86.
> > 2) On non-x86 architectures, we couldn't read phys_addr_bits from
> > /proc/cpuinfo as well.
> > 
> > According to above reasons, i perfer to check phys_addr_bits in
> > /proc/cpuinfo rather than the minimum
> > kernel version and x86 architecture.   We can skip this test if
> > phys_addr_bits isn't available.
> 
> I was referring to kernel patch. Does it make sense for this test
> to run on older kernels? Based on description it might crash, so
> presumably yes.

Though you need to be root and write to /dev/mem - which seems
like very rare use-case.

> 
> But do we also want to report FAIL on older kernels if mmap succeeds?
> That does not violate any docs.
> 
> > addr[0] = 'a';
> If mmap works, this has potential of triggering signal,
> which will lead to TBROK.

older kernels with lot of DEBUG options can survive:

# uname -r
3.10.0-810.el7.x86_64.debug

# ./mmap17
tst_test.c:980: INFO: Timeout per run is 0h 05m 00s
a1
tst_test.c:1020: INFO: If you are running on slow machine, try exporting LTP_TIMEOUT_MUL > 1
tst_test.c:1021: BROK: Test killed! (timeout?)

Summary:
passed   0
failed   0
skipped  0
warnings 0

I'd limit it to 4.14 and later - I'm assuming most people won't care
about this bug and we can ignore all outcomes from older kernels.
What do you think?

Regards,
Jan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-06 21:15           ` Jan Stancek
@ 2018-02-07 12:05             ` Xiao Yang
  2018-02-11 21:47               ` Jan Stancek
  0 siblings, 1 reply; 14+ messages in thread
From: Xiao Yang @ 2018-02-07 12:05 UTC (permalink / raw)
  To: ltp

On 2018/02/07 5:15, Jan Stancek wrote:
>
> ----- Original Message -----
>>
>> ----- Original Message -----
>>>> 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.
>>> 1) Before commit c64b04f, we couldn't read phys_addr_bits from
>>> /proc/cpuinfo in 32-bit kernel on x86.
>>> 2) On non-x86 architectures, we couldn't read phys_addr_bits from
>>> /proc/cpuinfo as well.
>>>
>>> According to above reasons, i perfer to check phys_addr_bits in
>>> /proc/cpuinfo rather than the minimum
>>> kernel version and x86 architecture.   We can skip this test if
>>> phys_addr_bits isn't available.
>> I was referring to kernel patch. Does it make sense for this test
>> to run on older kernels? Based on description it might crash, so
>> presumably yes.
> Though you need to be root and write to /dev/mem - which seems
> like very rare use-case.
>
>> But do we also want to report FAIL on older kernels if mmap succeeds?
>> That does not violate any docs.
>>
>>> addr[0] = 'a';
>> If mmap works, this has potential of triggering signal,
>> which will lead to TBROK.
> older kernels with lot of DEBUG options can survive:
>
> # uname -r
> 3.10.0-810.el7.x86_64.debug
>
> # ./mmap17
> tst_test.c:980: INFO: Timeout per run is 0h 05m 00s
> a1
> tst_test.c:1020: INFO: If you are running on slow machine, try exporting LTP_TIMEOUT_MUL>  1
> tst_test.c:1021: BROK: Test killed! (timeout?)
>
> Summary:
> passed   0
> failed   0
> skipped  0
> warnings 0
>
> I'd limit it to 4.14 and later - I'm assuming most people won't care
> about this bug and we can ignore all outcomes from older kernels.
> What do you think?
Hi Jan,

Thanks for your comment.  :-)

With 3.10.0-830.el7.x86_64 and 2.6.32-696.el6.x86_64, this case can trigger a crash easily,
so i want to run it on older kernels.  But, we can ignore all outcomes from older kernels
as you said.

If an invalid physical address was refused by mmap() or didn't trigger a crash, can we think
the bug didn't exist due to some protection mechanisms?

Please see the following code:
--------------------------------------------------------------------
static void verify_mmap(void)
{
         char *addr;

         addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 1ULL<<phys_addr_bits);
         if (addr == MAP_FAILED)
                 exit(0);

         addr[0] = 'a';
         SAFE_MUNMAP(addr, 1);
         exit(1);
}

static void do_mmap(void)
{
         pid_t pid;
         int status;

         pid = SAFE_FORK();
         if (!pid)
                 verify_mmap();

         SAFE_WAITPID(pid,&status, 0);
         if (WIFEXITED(status)&&  !WEXITSTATUS(status))
                 tst_res(TPASS, "Refused to map invalid physical address");
         else
                 tst_res(TPASS, "Mapped invalid physical address didn't trigger a crash");
}
--------------------------------------------------------------------

Thanks,
Xiao Yang

> Regards,
> Jan
>
>
>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-07 12:05             ` Xiao Yang
@ 2018-02-11 21:47               ` Jan Stancek
  2018-02-14  7:34                 ` Xiao Yang
  2018-02-22  7:32                 ` [LTP] [PATCH v3] " Xiao Yang
  0 siblings, 2 replies; 14+ messages in thread
From: Jan Stancek @ 2018-02-11 21:47 UTC (permalink / raw)
  To: ltp


----- Original Message -----
> On 2018/02/07 5:15, Jan Stancek wrote:
> >
> > ----- Original Message -----
> >>
> >> ----- Original Message -----
> >>>> 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.
> >>> 1) Before commit c64b04f, we couldn't read phys_addr_bits from
> >>> /proc/cpuinfo in 32-bit kernel on x86.
> >>> 2) On non-x86 architectures, we couldn't read phys_addr_bits from
> >>> /proc/cpuinfo as well.
> >>>
> >>> According to above reasons, i perfer to check phys_addr_bits in
> >>> /proc/cpuinfo rather than the minimum
> >>> kernel version and x86 architecture.   We can skip this test if
> >>> phys_addr_bits isn't available.
> >> I was referring to kernel patch. Does it make sense for this test
> >> to run on older kernels? Based on description it might crash, so
> >> presumably yes.
> > Though you need to be root and write to /dev/mem - which seems
> > like very rare use-case.
> >
> >> But do we also want to report FAIL on older kernels if mmap succeeds?
> >> That does not violate any docs.
> >>
> >>> addr[0] = 'a';
> >> If mmap works, this has potential of triggering signal,
> >> which will lead to TBROK.
> > older kernels with lot of DEBUG options can survive:
> >
> > # uname -r
> > 3.10.0-810.el7.x86_64.debug
> >
> > # ./mmap17
> > tst_test.c:980: INFO: Timeout per run is 0h 05m 00s
> > a1
> > tst_test.c:1020: INFO: If you are running on slow machine, try exporting
> > LTP_TIMEOUT_MUL>  1
> > tst_test.c:1021: BROK: Test killed! (timeout?)
> >
> > Summary:
> > passed   0
> > failed   0
> > skipped  0
> > warnings 0
> >
> > I'd limit it to 4.14 and later - I'm assuming most people won't care
> > about this bug and we can ignore all outcomes from older kernels.
> > What do you think?
> Hi Jan,
> 
> Thanks for your comment.  :-)
> 
> With 3.10.0-830.el7.x86_64 and 2.6.32-696.el6.x86_64, this case can trigger a
> crash easily,
> so i want to run it on older kernels.  But, we can ignore all outcomes from
> older kernels
> as you said.
> 
> If an invalid physical address was refused by mmap() or didn't trigger a
> crash, can we think
> the bug didn't exist due to some protection mechanisms?

That or it corrupted different place in memory. Or somebody backported
a patch to older kernel that changes behaviour in some other way.

> 
> Please see the following code:

That should work, though it still feels to me like test for
very unusual corner-case. I'd be interested to hear what
other people think.

Regards,
Jan

> --------------------------------------------------------------------
> static void verify_mmap(void)
> {
>          char *addr;
> 
>          addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
>          1ULL<<phys_addr_bits);
>          if (addr == MAP_FAILED)
>                  exit(0);
> 
>          addr[0] = 'a';
>          SAFE_MUNMAP(addr, 1);
>          exit(1);
> }
> 
> static void do_mmap(void)
> {
>          pid_t pid;
>          int status;
> 
>          pid = SAFE_FORK();
>          if (!pid)
>                  verify_mmap();
> 
>          SAFE_WAITPID(pid,&status, 0);
>          if (WIFEXITED(status)&&  !WEXITSTATUS(status))
>                  tst_res(TPASS, "Refused to map invalid physical address");
>          else
>                  tst_res(TPASS, "Mapped invalid physical address didn't
>                  trigger a crash");
> }
> --------------------------------------------------------------------
> 
> Thanks,
> Xiao Yang
> 
> > Regards,
> > Jan
> >
> >
> >
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH] syscalls/mmap17.c: Add new regression test
  2018-02-11 21:47               ` Jan Stancek
@ 2018-02-14  7:34                 ` Xiao Yang
  2018-02-22  7:32                 ` [LTP] [PATCH v3] " Xiao Yang
  1 sibling, 0 replies; 14+ messages in thread
From: Xiao Yang @ 2018-02-14  7:34 UTC (permalink / raw)
  To: ltp

Hi Cyril,

What do you think of this test? :-)

Thanks,
Xiao Yang
于 2018/02/12 5:47, Jan Stancek 写道:
> ----- Original Message -----
>> On 2018/02/07 5:15, Jan Stancek wrote:
>>> ----- Original Message -----
>>>> ----- Original Message -----
>>>>>> 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.
>>>>> 1) Before commit c64b04f, we couldn't read phys_addr_bits from
>>>>> /proc/cpuinfo in 32-bit kernel on x86.
>>>>> 2) On non-x86 architectures, we couldn't read phys_addr_bits from
>>>>> /proc/cpuinfo as well.
>>>>>
>>>>> According to above reasons, i perfer to check phys_addr_bits in
>>>>> /proc/cpuinfo rather than the minimum
>>>>> kernel version and x86 architecture.   We can skip this test if
>>>>> phys_addr_bits isn't available.
>>>> I was referring to kernel patch. Does it make sense for this test
>>>> to run on older kernels? Based on description it might crash, so
>>>> presumably yes.
>>> Though you need to be root and write to /dev/mem - which seems
>>> like very rare use-case.
>>>
>>>> But do we also want to report FAIL on older kernels if mmap succeeds?
>>>> That does not violate any docs.
>>>>
>>>>> addr[0] = 'a';
>>>> If mmap works, this has potential of triggering signal,
>>>> which will lead to TBROK.
>>> older kernels with lot of DEBUG options can survive:
>>>
>>> # uname -r
>>> 3.10.0-810.el7.x86_64.debug
>>>
>>> # ./mmap17
>>> tst_test.c:980: INFO: Timeout per run is 0h 05m 00s
>>> a1
>>> tst_test.c:1020: INFO: If you are running on slow machine, try exporting
>>> LTP_TIMEOUT_MUL>   1
>>> tst_test.c:1021: BROK: Test killed! (timeout?)
>>>
>>> Summary:
>>> passed   0
>>> failed   0
>>> skipped  0
>>> warnings 0
>>>
>>> I'd limit it to 4.14 and later - I'm assuming most people won't care
>>> about this bug and we can ignore all outcomes from older kernels.
>>> What do you think?
>> Hi Jan,
>>
>> Thanks for your comment.  :-)
>>
>> With 3.10.0-830.el7.x86_64 and 2.6.32-696.el6.x86_64, this case can trigger a
>> crash easily,
>> so i want to run it on older kernels.  But, we can ignore all outcomes from
>> older kernels
>> as you said.
>>
>> If an invalid physical address was refused by mmap() or didn't trigger a
>> crash, can we think
>> the bug didn't exist due to some protection mechanisms?
> That or it corrupted different place in memory. Or somebody backported
> a patch to older kernel that changes behaviour in some other way.
>
>> Please see the following code:
> That should work, though it still feels to me like test for
> very unusual corner-case. I'd be interested to hear what
> other people think.
>
> Regards,
> Jan
>
>> --------------------------------------------------------------------
>> static void verify_mmap(void)
>> {
>>           char *addr;
>>
>>           addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
>>           1ULL<<phys_addr_bits);
>>           if (addr == MAP_FAILED)
>>                   exit(0);
>>
>>           addr[0] = 'a';
>>           SAFE_MUNMAP(addr, 1);
>>           exit(1);
>> }
>>
>> static void do_mmap(void)
>> {
>>           pid_t pid;
>>           int status;
>>
>>           pid = SAFE_FORK();
>>           if (!pid)
>>                   verify_mmap();
>>
>>           SAFE_WAITPID(pid,&status, 0);
>>           if (WIFEXITED(status)&&   !WEXITSTATUS(status))
>>                   tst_res(TPASS, "Refused to map invalid physical address");
>>           else
>>                   tst_res(TPASS, "Mapped invalid physical address didn't
>>                   trigger a crash");
>> }
>> --------------------------------------------------------------------
>>
>> Thanks,
>> Xiao Yang
>>
>>> Regards,
>>> Jan
>>>
>>>
>>>
>>
>>
>>
>
> .
>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH v3] syscalls/mmap17.c: Add new regression test
  2018-02-11 21:47               ` Jan Stancek
  2018-02-14  7:34                 ` Xiao Yang
@ 2018-02-22  7:32                 ` Xiao Yang
  2018-04-04 14:31                   ` Cyril Hrubis
  1 sibling, 1 reply; 14+ messages in thread
From: Xiao Yang @ 2018-02-22  7:32 UTC (permalink / raw)
  To: ltp

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
may trigger 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 | 138 ++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+)
 create mode 100644 testcases/kernel/syscalls/mmap/mmap17.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 7c3cd5b..e72c7fc 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 e67d726..119a065 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..fb41a8d
--- /dev/null
+++ b/testcases/kernel/syscalls/mmap/mmap17.c
@@ -0,0 +1,138 @@
+/*
+ * 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 may trigger 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+
+#define MEM_PATH	"/dev/mem"
+#define CPUINFO_PATH	"/proc/cpuinfo"
+
+static int fd;
+static int phys_addr_bits;
+
+/* 1) Before commit c64b04f, we couldn't read phys_addr_bits from
+ *    /proc/cpuinfo in 32-bit kernel on x86.
+ * 2) On non-x86 architectures, we couldn't read phys_addr_bits from
+ *    /proc/cpuinfo as well.
+ * According to above reasons, we add a check for phys_addr_bits in
+ * /proc/cpuinfo.  We can skip this test if phys_addr_bits isn't available.
+ */
+static void check_phys_addr_bits(void)
+{
+	int existed = 0;
+	FILE *fp;
+	char line[BUFSIZ];
+
+	fp = SAFE_FOPEN(CPUINFO_PATH, "r");
+
+	while (fgets(line, BUFSIZ, fp)) {
+		if (strstr(line, "address sizes")) {
+			existed = 1;
+			break;
+		}
+	}
+
+	fclose(fp);
+
+	if (!existed) {
+		tst_brk(TCONF, "Couldn't read x86_phys_bits from %s",
+			CPUINFO_PATH);
+	}
+}
+
+static void verify_mmap(void)
+{
+	char *addr;
+
+	addr = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+		    1ULL<<phys_addr_bits);
+	if (addr == MAP_FAILED)
+		exit(0);
+
+	addr[0] = 'a';
+	SAFE_MUNMAP(addr, 1);
+	exit(1);
+}
+
+static void do_mmap(void)
+{
+	pid_t pid;
+	int status;
+
+	pid = SAFE_FORK();
+	if (!pid)
+		verify_mmap();
+
+	SAFE_WAITPID(pid, &status, 0);
+
+	if (WIFEXITED(status)) {
+		if (!WEXITSTATUS(status))
+			tst_res(TPASS, "Refused to map invalid physical address");
+		else
+			tst_res(TFAIL, "Mapped and set invalid physical address successfully");
+		return;
+	}
+
+	tst_res(TPASS, "Failed to set invalid physical address");
+}
+
+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);
+
+	check_phys_addr_bits();
+	SAFE_FILE_LINES_SCANF(CPUINFO_PATH, "address sizes\t: %d",
+			      &phys_addr_bits);
+}
+
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = do_mmap,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [LTP] [PATCH v3] syscalls/mmap17.c: Add new regression test
  2018-02-22  7:32                 ` [LTP] [PATCH v3] " Xiao Yang
@ 2018-04-04 14:31                   ` Cyril Hrubis
  2019-04-16 10:42                     ` xuyang
  0 siblings, 1 reply; 14+ messages in thread
From: Cyril Hrubis @ 2018-04-04 14:31 UTC (permalink / raw)
  To: ltp

Hi!
> 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
> may trigger a kernel crash.

I wonder if we can address Jan's comment and make it more generic by
trying to mmap a certain sequence of offsets in /dev/mem and either
expect them to return a valid pointer or fail with MAP_FAILED. We would
have to make sure that we got the 1ULL<<phys_addr_bits there for the x86
case but we wouldn't have to skip the test on non-x86 hardware.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [LTP] [PATCH v3] syscalls/mmap17.c: Add new regression test
  2018-04-04 14:31                   ` Cyril Hrubis
@ 2019-04-16 10:42                     ` xuyang
  0 siblings, 0 replies; 14+ messages in thread
From: xuyang @ 2019-04-16 10:42 UTC (permalink / raw)
  To: ltp

on 3:59, Cyril Hrubis wrote:

> I wonder if we can address Jan's comment and make it more generic by
> trying to mmap a certain sequence of offsets in /dev/mem and either
> expect them to return a valid pointer or fail with MAP_FAILED. We would
> have to make sure that we got the 1ULL<<phys_addr_bits there for the x86
> case but we wouldn't have to skip the test on non-x86 hardware.
Hi Cyril

   This patch has been created long time ago, we should start it again. I think we
   should make this case more generic.  It should test mmap whether check physical
   addr size valid instead of triggering a rare crash.

   We can look for a max phys_addr_bit on all arch architectures.  AFAIK, the max
   phys_addr_bit is 52, we can test it as below:

   mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 1ULL<<52)




^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2019-04-16 10:42 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-02 10:03 [LTP] [PATCH] syscalls/mmap17.c: Add new regression test Xiao Yang
2018-02-02 10:20 ` Jan Stancek
2018-02-05 10:45   ` Xiao Yang
2018-02-05 11:42     ` Jan Stancek
2018-02-06  6:41       ` Xiao Yang
2018-02-06 19:53         ` Jan Stancek
2018-02-06 21:15           ` Jan Stancek
2018-02-07 12:05             ` Xiao Yang
2018-02-11 21:47               ` Jan Stancek
2018-02-14  7:34                 ` Xiao Yang
2018-02-22  7:32                 ` [LTP] [PATCH v3] " Xiao Yang
2018-04-04 14:31                   ` Cyril Hrubis
2019-04-16 10:42                     ` xuyang
2018-02-06  6:43       ` [LTP] [PATCH v2] " Xiao Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.