linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] selftests: x86: add version check in test_syscall_vdso
@ 2019-03-01  0:18 Steve Muckle
  2019-03-01 19:59 ` Andy Lutomirski
  0 siblings, 1 reply; 4+ messages in thread
From: Steve Muckle @ 2019-03-01  0:18 UTC (permalink / raw)
  To: Shuah Khan, Andy Lutomirski, Thomas Gleixner, linux-kselftest
  Cc: linux-kernel, kernel-team, Steve Muckle

Since 4.17 registers r8-r11 are not clobbered/zeroed by a 64-bit kernel
handling a 32-bit syscall and this behavior is enforced by the
test_syscall_vdso testcase. See commit 8bb2610bc496
("x86/entry/64/compat: Preserve r8-r11 in int $0x80").

Permit the old behavior in the testcase for kernels prior to 4.17.

Signed-off-by: Steve Muckle <smuckle@google.com>
---
 .../testing/selftests/x86/test_syscall_vdso.c | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/testing/selftests/x86/test_syscall_vdso.c b/tools/testing/selftests/x86/test_syscall_vdso.c
index c9c3281077bc..f7284dc4c32b 100644
--- a/tools/testing/selftests/x86/test_syscall_vdso.c
+++ b/tools/testing/selftests/x86/test_syscall_vdso.c
@@ -30,6 +30,7 @@
 #include <sys/time.h>
 #include <elf.h>
 #include <sys/ptrace.h>
+#include <sys/utsname.h>
 #include <sys/wait.h>
 
 #if !defined(__i386__)
@@ -71,6 +72,7 @@ struct regs64 {
 };
 struct regs64 regs64;
 int kernel_is_64bit;
+int clobber_ok;
 
 asm (
 	"	.pushsection .text\n"
@@ -130,6 +132,28 @@ void print_regs64(void)
 	printf("12:%016llx 13:%016llx 14:%016llx 15:%016llx\n", regs64.r12,  regs64.r13,  regs64.r14,  regs64.r15);
 }
 
+static void get_kernel_version(int *version, int *patchlevel)
+{
+	int ret, sublevel;
+	struct utsname utsname;
+
+	ret = uname(&utsname);
+	if (ret) {
+		perror("uname");
+		exit(1);
+	}
+
+	ret = sscanf(utsname.release, "%d.%d.%d", version, patchlevel,
+		     &sublevel);
+	if (ret < 0) {
+		perror("sscanf");
+		exit(1);
+	} else if (ret != 3) {
+		printf("Malformed kernel version %s\n", &utsname.release);
+		exit(1);
+	}
+}
+
 int check_regs64(void)
 {
 	int err = 0;
@@ -166,6 +190,8 @@ int check_regs64(void)
 			 * Historically (and probably unintentionally), they
 			 * were clobbered or zeroed.
 			 */
+			if (clobber_ok && *r64 == 0 && num <= 11)
+				continue;
 		}
 		printf("[FAIL]\tR%d has changed:%016llx\n", num, *r64);
 		err++;
@@ -385,6 +411,7 @@ int main(int argc, char **argv, char **envp)
 {
 	int exitcode = 0;
 	int cs;
+	int version, patchlevel;
 
 	asm("\n"
 	"	movl	%%cs, %%eax\n"
@@ -394,6 +421,9 @@ int main(int argc, char **argv, char **envp)
 	if (!kernel_is_64bit)
 		printf("[NOTE]\tNot a 64-bit kernel, won't test R8..R15 leaks\n");
 
+	get_kernel_version(&version, &patchlevel);
+	clobber_ok = version < 4 || (version == 4 && patchlevel < 17);
+
 	/* This only works for non-static builds:
 	 * syscall_addr = dlsym(dlopen("linux-gate.so.1", RTLD_NOW), "__kernel_vsyscall");
 	 */
-- 
2.21.0.352.gf09ad66450-goog


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

* Re: [PATCH] selftests: x86: add version check in test_syscall_vdso
  2019-03-01  0:18 [PATCH] selftests: x86: add version check in test_syscall_vdso Steve Muckle
@ 2019-03-01 19:59 ` Andy Lutomirski
  2019-03-02  9:10   ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Andy Lutomirski @ 2019-03-01 19:59 UTC (permalink / raw)
  To: Steve Muckle
  Cc: Shuah Khan, Andy Lutomirski, Thomas Gleixner,
	open list:KERNEL SELFTEST FRAMEWORK, LKML, Android Kernel Team

> On Feb 28, 2019, at 4:18 PM, Steve Muckle <smuckle@google.com> wrote:
>
> Since 4.17 registers r8-r11 are not clobbered/zeroed by a 64-bit kernel
> handling a 32-bit syscall and this behavior is enforced by the
> test_syscall_vdso testcase. See commit 8bb2610bc496
> ("x86/entry/64/compat: Preserve r8-r11 in int $0x80").
>
> Permit the old behavior in the testcase for kernels prior to 4.17.

NAK.  If you want an old buggy kernel to pass a test, please either
patch the kernel or run an old test.


>
> Signed-off-by: Steve Muckle <smuckle@google.com>
> ---
> .../testing/selftests/x86/test_syscall_vdso.c | 30 +++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/tools/testing/selftests/x86/test_syscall_vdso.c b/tools/testing/selftests/x86/test_syscall_vdso.c
> index c9c3281077bc..f7284dc4c32b 100644
> --- a/tools/testing/selftests/x86/test_syscall_vdso.c
> +++ b/tools/testing/selftests/x86/test_syscall_vdso.c
> @@ -30,6 +30,7 @@
> #include <sys/time.h>
> #include <elf.h>
> #include <sys/ptrace.h>
> +#include <sys/utsname.h>
> #include <sys/wait.h>
>
> #if !defined(__i386__)
> @@ -71,6 +72,7 @@ struct regs64 {
> };
> struct regs64 regs64;
> int kernel_is_64bit;
> +int clobber_ok;
>
> asm (
>    "    .pushsection .text\n"
> @@ -130,6 +132,28 @@ void print_regs64(void)
>    printf("12:%016llx 13:%016llx 14:%016llx 15:%016llx\n", regs64.r12,  regs64.r13,  regs64.r14,  regs64.r15);
> }
>
> +static void get_kernel_version(int *version, int *patchlevel)
> +{
> +    int ret, sublevel;
> +    struct utsname utsname;
> +
> +    ret = uname(&utsname);
> +    if (ret) {
> +        perror("uname");
> +        exit(1);
> +    }
> +
> +    ret = sscanf(utsname.release, "%d.%d.%d", version, patchlevel,
> +             &sublevel);
> +    if (ret < 0) {
> +        perror("sscanf");
> +        exit(1);
> +    } else if (ret != 3) {
> +        printf("Malformed kernel version %s\n", &utsname.release);
> +        exit(1);
> +    }
> +}
> +
> int check_regs64(void)
> {
>    int err = 0;
> @@ -166,6 +190,8 @@ int check_regs64(void)
>             * Historically (and probably unintentionally), they
>             * were clobbered or zeroed.
>             */
> +            if (clobber_ok && *r64 == 0 && num <= 11)
> +                continue;
>        }
>        printf("[FAIL]\tR%d has changed:%016llx\n", num, *r64);
>        err++;
> @@ -385,6 +411,7 @@ int main(int argc, char **argv, char **envp)
> {
>    int exitcode = 0;
>    int cs;
> +    int version, patchlevel;
>
>    asm("\n"
>    "    movl    %%cs, %%eax\n"
> @@ -394,6 +421,9 @@ int main(int argc, char **argv, char **envp)
>    if (!kernel_is_64bit)
>        printf("[NOTE]\tNot a 64-bit kernel, won't test R8..R15 leaks\n");
>
> +    get_kernel_version(&version, &patchlevel);
> +    clobber_ok = version < 4 || (version == 4 && patchlevel < 17);
> +
>    /* This only works for non-static builds:
>     * syscall_addr = dlsym(dlopen("linux-gate.so.1", RTLD_NOW), "__kernel_vsyscall");
>     */
> --
> 2.21.0.352.gf09ad66450-goog
>

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

* Re: [PATCH] selftests: x86: add version check in test_syscall_vdso
  2019-03-01 19:59 ` Andy Lutomirski
@ 2019-03-02  9:10   ` Greg KH
  2019-03-02 18:31     ` shuah
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2019-03-02  9:10 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Steve Muckle, Shuah Khan, Thomas Gleixner,
	open list:KERNEL SELFTEST FRAMEWORK, LKML, Android Kernel Team

On Fri, Mar 01, 2019 at 11:59:24AM -0800, Andy Lutomirski wrote:
> > On Feb 28, 2019, at 4:18 PM, Steve Muckle <smuckle@google.com> wrote:
> >
> > Since 4.17 registers r8-r11 are not clobbered/zeroed by a 64-bit kernel
> > handling a 32-bit syscall and this behavior is enforced by the
> > test_syscall_vdso testcase. See commit 8bb2610bc496
> > ("x86/entry/64/compat: Preserve r8-r11 in int $0x80").
> >
> > Permit the old behavior in the testcase for kernels prior to 4.17.
> 
> NAK.  If you want an old buggy kernel to pass a test, please either
> patch the kernel or run an old test.

Yeah, this isn't ok, especially as you might have 4.14 or 4.9 kernels
that can pass the test if the needed patches were backported.  Checking
kernel version numbers should never be used for anything.

greg k-h

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

* Re: [PATCH] selftests: x86: add version check in test_syscall_vdso
  2019-03-02  9:10   ` Greg KH
@ 2019-03-02 18:31     ` shuah
  0 siblings, 0 replies; 4+ messages in thread
From: shuah @ 2019-03-02 18:31 UTC (permalink / raw)
  To: Greg KH, Andy Lutomirski
  Cc: Steve Muckle, Thomas Gleixner,
	open list:KERNEL SELFTEST FRAMEWORK, LKML, Android Kernel Team,
	shuah

On 3/2/19 2:10 AM, Greg KH wrote:
> On Fri, Mar 01, 2019 at 11:59:24AM -0800, Andy Lutomirski wrote:
>>> On Feb 28, 2019, at 4:18 PM, Steve Muckle <smuckle@google.com> wrote:
>>>
>>> Since 4.17 registers r8-r11 are not clobbered/zeroed by a 64-bit kernel
>>> handling a 32-bit syscall and this behavior is enforced by the
>>> test_syscall_vdso testcase. See commit 8bb2610bc496
>>> ("x86/entry/64/compat: Preserve r8-r11 in int $0x80").
>>>
>>> Permit the old behavior in the testcase for kernels prior to 4.17.
>>
>> NAK.  If you want an old buggy kernel to pass a test, please either
>> patch the kernel or run an old test.
> 
> Yeah, this isn't ok, especially as you might have 4.14 or 4.9 kernels
> that can pass the test if the needed patches were backported.  Checking
> kernel version numbers should never be used for anything.
> 

Also, this test failure can tell us if we should backport important
fixes. I have had requests to add kernel version checking in tests
before and the recommendation is "don't check kernel versions and
reply on feature type checks". In the case of fixes like this one,
it is better for the test to fail than make us feel warm and fuzzy
by making it pass.

thanks,
-- Shuah



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

end of thread, other threads:[~2019-03-02 18:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-01  0:18 [PATCH] selftests: x86: add version check in test_syscall_vdso Steve Muckle
2019-03-01 19:59 ` Andy Lutomirski
2019-03-02  9:10   ` Greg KH
2019-03-02 18:31     ` shuah

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).