Package: src:linux
Version: 4.9.110-1
Severity: normal

Dear Maintainer,

The arm64 kernel allows one to run aarch32 processes on an aarch64
processor (if it has support for it), using the standard 32/64-bit
syscall compatibility. However this compat layer does not correctly
validate the arguments of the sigaltstack syscall.

arch/arm64/include/uapi/asm/signal.h defines SIGSTKSZ and MINSIGSTKSZ
as follow:
| #define MINSIGSTKSZ 5120
| #define SIGSTKSZ    16384

arch/arm/include/uapi/asm/signal.h defines SIGSTKSZ and MINSIGSTKSZ as
follow:
| #define MINSIGSTKSZ 2048
| #define SIGSTKSZ    8192

It seems to be the only 32/64-bit architecture for which those constants
differ. The do_compat_sigaltstack function in kernel/signal.c passes
ss.ss_size to do_sigaltstack unchanged, and the latter validates it
against the native MINSIGSTKSZ.

This causes the glibc test nptl/tst-signal6 to fail, but I guess it can
also affects other packages at runtime. This is also reproducible with
the following simple testcase:

| #include <signal.h>
| #include <stdlib.h>
| #include <stdio.h>
| 
| int main(int argc, char *argv[])
| {
|         stack_t ss;
| 
|         ss.ss_sp = malloc(MINSIGSTKSZ);
|         if (ss.ss_sp == NULL) {
|                 perror("malloc");
|                 exit(EXIT_FAILURE);
|         }
| 
|         ss.ss_size = MINSIGSTKSZ;
|         ss.ss_flags = 0;
|         if (sigaltstack(&ss, NULL)) {
|                 perror("sigaltstack");
|                 exit(EXIT_FAILURE);
|         }
| 
|         return 0;
| }

| $ ./sigaltstack 
| sigaltstack: Cannot allocate memory

| $ strace ./sigaltstack
| execve("./sigaltstack", ["./sigaltstack"], [/* 23 vars */]) = 0
| strace: [ Process PID=694 runs in 32 bit mode. ]
| uname({sysname="Linux", nodename="arm64", ...}) = 0
| brk(NULL)                               = 0x35d000
| brk(0x35dd00)                           = 0x35dd00
| set_tls(0x35d4c0, 0x78f7c, 0, 0x24, 0x78f6c) = 0
| readlink("/proc/self/exe", "/home/aurel32/sigaltstack", 4096) = 25
| brk(0x37ed00)                           = 0x37ed00
| brk(0x37f000)                           = 0x37f000
| access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or 
directory)
| sigaltstack({ss_sp=0x35e8b0, ss_flags=0x800 /* SS_??? */, ss_size=67191}, 
NULL) = -1 ENOMEM (Cannot allocate memory)
| dup(2)                                  = 3
| fcntl64(3, F_GETFL)                     = 0x20002 (flags O_RDWR|0x20000)
| fstat64(3, 0xff96bf28)                  = 0
| write(3, "sigaltstack: Cannot allocate mem"..., 36sigaltstack: Cannot 
allocate memory
| ) = 36
| close(3)                                = 0
| exit_group(1)                           = ?
| +++ exited with 1 +++

-- System Information:
Debian Release: 9.5
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: arm64 (aarch64)

Kernel: Linux 4.9.0-7-arm64 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), 
LANGUAGE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Reply via email to