Public bug reported:

SRU Justification

Impact: On kernels prior to 5.8 when a task is in traced state (due to
audit, ptrace, or seccomp) s390x and a syscall is issued that the kernel
doesn't know about s390x will not return ENOSYS in r2 but instead will
return the syscall number. This breaks userspace all over the place. The
following program compiled on s390x will output 500 instead of -ENOSYS:

root@test:~# cat test.c
#define _GNU_SOURCE
#include <libgen.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

static inline int dummy_inline_asm(void)
{
        register long r1 asm("r1") = 500;
        register long r2 asm("r2") = -1;
        register long r3 asm("r3") = -1;
        register long r4 asm("r4") = -1;
        register long r5 asm("r5") = -1;
        register long __res_r2 asm("r2");
        asm volatile(
            "svc 0\n\t"
             : "=d"(__res_r2)
             : "d"(r1), "0"(r2), "d"(r3), "d"(r4), "d"(r5)
             : "memory");
        return (int) __res_r2;
}

static inline int dummy_syscall(void)
{
        return syscall(500, -1, -1, -1, -1);
}

int main(int argc, char *argv[])
{
        printf("Uhm: %d\n", dummy_inline_asm());
        printf("Uhm: %d\n", dummy_syscall());

        exit(EXIT_SUCCESS);
}

This breaks LXD on s390x currently completely as well as strace.

Fix: Backport
commit cd29fa798001075a554b978df3a64e6656c25794
Author: Sven Schnelle <sv...@linux.ibm.com>
Date:   Fri Mar 6 13:18:31 2020 +0100

    s390/ptrace: return -ENOSYS when invalid syscall is supplied

    The current code returns the syscall number which an invalid
    syscall number is supplied and tracing is enabled. This makes
    the strace testsuite fail.

    Signed-off-by: Sven Schnelle <sv...@linux.ibm.com>
    Signed-off-by: Vasily Gorbik <g...@linux.ibm.com>

which got released with 5.8. The commit missed to Cc stable and although
I've asked Sven to include it in stable I'm not sure when or if it will
show up there.

Regression Potential: Limited to s390x.

Test Case: The reproducer given above needs to output -ENOSYS instead of
500.

** Affects: linux (Ubuntu)
     Importance: Undecided
         Status: Confirmed

** Changed in: linux (Ubuntu)
       Status: New => Confirmed

** Description changed:

  SRU Justification
  
  Impact: On kernels prior to 5.8 when a task is in traced state (due to
  audit, ptrace, or seccomp) s390x and a syscall is issued that the kernel
  doesn't know about s390x will not return ENOSYS in r2 but instead will
  return the syscall number. This breaks userspace all over the place. The
  following program compiled on s390x will output 500 instead of -ENOSYS:
  
  root@test:~# cat test.c
  #define _GNU_SOURCE
  #include <libgen.h>
  #include <errno.h>
  #include <fcntl.h>
  #include <limits.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/stat.h>
  #include <sys/syscall.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <unistd.h>
  
  static inline int dummy_inline_asm(void)
  {
-         register long r1 asm("r1") = 500;
-         register long r2 asm("r2") = -1;
-         register long r3 asm("r3") = -1;
-         register long r4 asm("r4") = -1;
-         register long r5 asm("r5") = -1;
-         register long __res_r2 asm("r2");
-         asm volatile(
-             "svc 0\n\t"
-              : "=d"(__res_r2)
-              : "d"(r1), "0"(r2), "d"(r3), "d"(r4), "d"(r5)
-              : "memory");
-         return (int) __res_r2;
+         register long r1 asm("r1") = 500;
+         register long r2 asm("r2") = -1;
+         register long r3 asm("r3") = -1;
+         register long r4 asm("r4") = -1;
+         register long r5 asm("r5") = -1;
+         register long __res_r2 asm("r2");
+         asm volatile(
+             "svc 0\n\t"
+              : "=d"(__res_r2)
+              : "d"(r1), "0"(r2), "d"(r3), "d"(r4), "d"(r5)
+              : "memory");
+         return (int) __res_r2;
  }
  
  static inline int dummy_syscall(void)
  {
-         return syscall(500, -1, -1, -1, -1);
+         return syscall(500, -1, -1, -1, -1);
  }
  
  int main(int argc, char *argv[])
  {
-         printf("Uhm: %d\n", dummy_inline_asm());
-         printf("Uhm: %d\n", dummy_syscall());
+         printf("Uhm: %d\n", dummy_inline_asm());
+         printf("Uhm: %d\n", dummy_syscall());
  
-         exit(EXIT_SUCCESS);
+         exit(EXIT_SUCCESS);
  }
+ 
+ This breaks LXD on s390x currently completely as well as strace.
  
  Fix: Backport
  commit cd29fa798001075a554b978df3a64e6656c25794
  Author: Sven Schnelle <sv...@linux.ibm.com>
  Date:   Fri Mar 6 13:18:31 2020 +0100
  
-     s390/ptrace: return -ENOSYS when invalid syscall is supplied
+     s390/ptrace: return -ENOSYS when invalid syscall is supplied
  
-     The current code returns the syscall number which an invalid
-     syscall number is supplied and tracing is enabled. This makes
-     the strace testsuite fail.
+     The current code returns the syscall number which an invalid
+     syscall number is supplied and tracing is enabled. This makes
+     the strace testsuite fail.
  
-     Signed-off-by: Sven Schnelle <sv...@linux.ibm.com>
-     Signed-off-by: Vasily Gorbik <g...@linux.ibm.com>
+     Signed-off-by: Sven Schnelle <sv...@linux.ibm.com>
+     Signed-off-by: Vasily Gorbik <g...@linux.ibm.com>
  
  which got released with 5.8. The commit missed to Cc stable and although
  I've asked Sven to include it in stable I'm not sure when or if it will
  show up there.
  
  Regression Potential: Limited to s390x.
  
  Test Case: The reproducer given above needs to output -ENOSYS instead of
  500.

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1895132

Title:
  s390x broken with unknown syscall number on kernels < 5.8

Status in linux package in Ubuntu:
  Confirmed

Bug description:
  SRU Justification

  Impact: On kernels prior to 5.8 when a task is in traced state (due to
  audit, ptrace, or seccomp) s390x and a syscall is issued that the
  kernel doesn't know about s390x will not return ENOSYS in r2 but
  instead will return the syscall number. This breaks userspace all over
  the place. The following program compiled on s390x will output 500
  instead of -ENOSYS:

  root@test:~# cat test.c
  #define _GNU_SOURCE
  #include <libgen.h>
  #include <errno.h>
  #include <fcntl.h>
  #include <limits.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/stat.h>
  #include <sys/syscall.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <unistd.h>

  static inline int dummy_inline_asm(void)
  {
          register long r1 asm("r1") = 500;
          register long r2 asm("r2") = -1;
          register long r3 asm("r3") = -1;
          register long r4 asm("r4") = -1;
          register long r5 asm("r5") = -1;
          register long __res_r2 asm("r2");
          asm volatile(
              "svc 0\n\t"
               : "=d"(__res_r2)
               : "d"(r1), "0"(r2), "d"(r3), "d"(r4), "d"(r5)
               : "memory");
          return (int) __res_r2;
  }

  static inline int dummy_syscall(void)
  {
          return syscall(500, -1, -1, -1, -1);
  }

  int main(int argc, char *argv[])
  {
          printf("Uhm: %d\n", dummy_inline_asm());
          printf("Uhm: %d\n", dummy_syscall());

          exit(EXIT_SUCCESS);
  }

  This breaks LXD on s390x currently completely as well as strace.

  Fix: Backport
  commit cd29fa798001075a554b978df3a64e6656c25794
  Author: Sven Schnelle <sv...@linux.ibm.com>
  Date:   Fri Mar 6 13:18:31 2020 +0100

      s390/ptrace: return -ENOSYS when invalid syscall is supplied

      The current code returns the syscall number which an invalid
      syscall number is supplied and tracing is enabled. This makes
      the strace testsuite fail.

      Signed-off-by: Sven Schnelle <sv...@linux.ibm.com>
      Signed-off-by: Vasily Gorbik <g...@linux.ibm.com>

  which got released with 5.8. The commit missed to Cc stable and
  although I've asked Sven to include it in stable I'm not sure when or
  if it will show up there.

  Regression Potential: Limited to s390x.

  Test Case: The reproducer given above needs to output -ENOSYS instead
  of 500.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1895132/+subscriptions

-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : kernel-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to