Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp6762721pxu; Thu, 24 Dec 2020 11:46:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJwKzv8qGE5rpHiK2TaNLcLG+6fOLRiZDMC5+IHaeFXep+CYjKQuW4f5bvCC/7Rrmkp33W7d X-Received: by 2002:a17:906:2e16:: with SMTP id n22mr29877600eji.477.1608839211736; Thu, 24 Dec 2020 11:46:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608839211; cv=none; d=google.com; s=arc-20160816; b=mmg5LvE8TGDIMKzw7sLILUd/i9+VTqIq3YkxNQ8+XliBww8gnffwDwp+mAONOCt3NQ mSlEo9GhsZ5IqcloQbN9YbQf24hN7jnvmBVvngIWbH0VWMaywyxLvXhnTzgIoYJvpGBo 8HujvyMeb3B6Pb354DCLTOiJ/caYPlkb+JkM4LBBWNWwcRL9KbWGcpi96iKmAoAR1BDd KaJO7bysx3gYH8YeykGIQkPJR/GYt6AxnTNaR/Hmdj3gJZsEppsp7yPDLskvd1vyo4A8 2yI7eTqRKfzJJBAxOB89TD4j+qiEUpm2RS5IaXyKQHpKX5v6NxB97BLqmd0zAs7KXw0/ +K1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=RopeGsNIQMRQWe/ZG7P9Hca9jRxC3BoTFk8KgF+WYaQ=; b=jnW680CagJnrX7wFcKIsOV2y2JCmy8SRxpHXHgoWUcWstbKkJ7+EyGXJcjZVOPUXU/ LJQm5VXb658VhSkXwnoDwKa3LznWiijiflODNV9093LFiEQDmryyhIWzi6SOxpupfF8L kxqBEzMjXOD8z0TuiV4ODTkilVODh0ubPStQ7ZL34VKPEU0HhW0LkWBl7JnaEu1EkyvY AEiRYvklK/LQViGNoWLAt6ZJIz6WDdkDtZb18+0r4mccUwVPu4/QqOcBKIXjEoPM8MDC 6J7DJPgs+chk1txlFkicAReHNLv+D3L7+Ugn3L2MqA0jsHqG4y3tWzLqJMyxcyaH5rXW v8+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o1si13203208eje.226.2020.12.24.11.46.27; Thu, 24 Dec 2020 11:46:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728843AbgLXTpr (ORCPT + 99 others); Thu, 24 Dec 2020 14:45:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728266AbgLXTpq (ORCPT ); Thu, 24 Dec 2020 14:45:46 -0500 Received: from ZenIV.linux.org.uk (zeniv.linux.org.uk [IPv6:2002:c35c:fd02::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B394C061573; Thu, 24 Dec 2020 11:45:02 -0800 (PST) Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92.3 #3 (Red Hat Linux)) id 1ksWXP-003sWr-0X; Thu, 24 Dec 2020 19:44:39 +0000 Date: Thu, 24 Dec 2020 19:44:38 +0000 From: Al Viro To: "Maciej W. Rozycki" Cc: Linus Torvalds , Thomas Bogendoerfer , Linux Kernel Mailing List , the arch/x86 maintainers , linux-mips@vger.kernel.org, Randy Dunlap , Denys Vlasenko Subject: [RFC][PATCH] NT_FILE/NT_SIGINFO breakage on mips compat coredumps Message-ID: <20201224194438.GY3579531@ZenIV.linux.org.uk> References: <20201203214529.GB3579531@ZenIV.linux.org.uk> <20201203230336.GC3579531@ZenIV.linux.org.uk> <20201216030154.GL3579531@ZenIV.linux.org.uk> <20201223070320.GW3579531@ZenIV.linux.org.uk> <20201223071213.GX3579531@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20201223071213.GX3579531@ZenIV.linux.org.uk> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Dec 23, 2020 at 07:12:13AM +0000, Al Viro wrote: > On Wed, Dec 23, 2020 at 07:03:20AM +0000, Al Viro wrote: > > Argh.... Wrong commit blamed - the parent of the correct one. > It's actually 2aa362c49c31 ("coredump: extend core dump note section to > contain file names of mapped files"). My apologies - fat-fingered > cut'n'paste... > > siginfo commit does suffer the same problem, but it becomes an issue > only for 32bit processes under mips64 big-endian kernel (there it yields > e.g. zero .__sigfault.si_addr in $_siginfo when using gdb with a coredump > of 32bit process, whatever the actual faulting address had been). And > b-e mips64 is rather uncommon, so that's less of an issue. FWIW, here's debian/mips image (stretch) booted with qemu-system-mips64 -M malta -cpu 5KEc: root@mips:~# uname -a Linux mips 4.9.0-13-5kc-malta #1 Debian 4.9.228-1 (2020-07-05) mips64 GNU/Linux root@mips:~# cat a.c main() { *(char *)0x0123 = 0; } root@mips:~# gcc a.c a.c:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int] main() ^~~~ root@mips:~# ulimit -c unlimited root@mips:~# ./a.out [ 519.744983] do_page_fault(): sending SIGSEGV to a.out for invalid write access to 0000000000000123 [ 519.746735] epc = 00000000558477c0 in a.out[55847000+1000] [ 519.747758] ra = 000000007792f4a8 in libc-2.24.so[77916000+16a000] Segmentation fault (core dumped) root@mips:~# gdb a.out core GNU gdb (Debian 7.12-6) 7.12.0.20161007-git Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "mips-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from a.out...(no debugging symbols found)...done. [New LWP 1202] Core was generated by `./a.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x55dde7c0 in main () (gdb) print $_siginfo $1 = {si_signo = 11, si_errno = 1, si_code = 0, _sifields = {_pad = {0, 0, 291, 0 }, _kill = {si_pid = 0, si_uid = 0}, _timer = { si_tid = 0, si_overrun = 0, si_sigval = {sival_int = 291, sival_ptr = 0x123}}, _rt = {si_pid = 0, si_uid = 0, si_sigval = { sival_int = 291, sival_ptr = 0x123}}, _sigchld = {si_pid = 0, si_uid = 0, si_status = 291, si_utime = 0, si_stime = 0}, _sigfault = { si_addr = 0x0}, _sigpoll = {si_band = 0, si_fd = 0}}} (gdb) quit Note the wrong value in _sigfault.si_addr - it should've been 0x123, not 0. root@mips:~# readelf -n core Displaying notes found at file offset 0x00000234 with length 0x000005f4: Owner Data size Description CORE 0x00000100 NT_PRSTATUS (prstatus structure) CORE 0x00000080 NT_PRPSINFO (prpsinfo structure) CORE 0x00000080 NT_SIGINFO (siginfo_t data) CORE 0x00000090 NT_AUXV (auxiliary vector) CORE 0x000001e1 NT_FILE (mapped files) Page size: 9 Start End Page Offset CORE 0x00000108 NT_FPREGSET (floating point registers) For comparison, exact same image booted with qemu-system-mips -M malta: root@mips:~# uname -a Linux mips 4.9.0-13-4kc-malta #1 Debian 4.9.228-1 (2020-07-05) mips GNU/Linux root@mips:~# ulimit -c unlimited root@mips:~# ./a.out [ 83.380870] do_page_fault(): sending SIGSEGV to a.out for invalid write access to 00000123 [ 83.390678] epc = 55e0e7c0 in a.out[55e0e000+1000] [ 83.391525] ra = 76f644a8 in libc-2.24.so[76f4b000+16a000] Segmentation fault (core dumped) root@mips:~# gdb a.out core GNU gdb (Debian 7.12-6) 7.12.0.20161007-git Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "mips-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from a.out...(no debugging symbols found)...done. [New LWP 1184] Core was generated by `./a.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x55e0e7c0 in main () (gdb) print $_siginfo $1 = {si_signo = 11, si_errno = 1, si_code = 0, _sifields = {_pad = {291, 0 }, _kill = {si_pid = 291, si_uid = 0}, _timer = { si_tid = 291, si_overrun = 0, si_sigval = {sival_int = 0, sival_ptr = 0x0}}, _rt = {si_pid = 291, si_uid = 0, si_sigval = { sival_int = 0, sival_ptr = 0x0}}, _sigchld = {si_pid = 291, si_uid = 0, si_status = 0, si_utime = 0, si_stime = 0}, _sigfault = { si_addr = 0x123}, _sigpoll = {si_band = 291, si_fd = 0}}} (gdb) quit root@mips:~# readelf -n core Displaying notes found at file offset 0x00000234 with length 0x00000580: Owner Data size Description CORE 0x00000100 NT_PRSTATUS (prstatus structure) CORE 0x00000080 NT_PRPSINFO (prpsinfo structure) CORE 0x00000080 NT_SIGINFO (siginfo_t data) CORE 0x00000090 NT_AUXV (auxiliary vector) CORE 0x0000016d NT_FILE (mapped files) Page size: 4096 Start End Page Offset 0x55e0e000 0x55e0f000 0x00000000 /root/a.out 0x55e1e000 0x55e1f000 0x00000000 /root/a.out 0x76f4b000 0x770b5000 0x00000000 /lib/mips-linux-gnu/libc-2.24.so 0x770b5000 0x770c5000 0x0000016a /lib/mips-linux-gnu/libc-2.24.so 0x770c5000 0x770c8000 0x0000016a /lib/mips-linux-gnu/libc-2.24.so 0x770c8000 0x770cb000 0x0000016d /lib/mips-linux-gnu/libc-2.24.so 0x770cd000 0x770f0000 0x00000000 /lib/mips-linux-gnu/ld-2.24.so 0x770ff000 0x77100000 0x00000022 /lib/mips-linux-gnu/ld-2.24.so 0x77100000 0x77101000 0x00000023 /lib/mips-linux-gnu/ld-2.24.so CORE 0x00000108 NT_FPREGSET (floating point registers) So that's not so theoretical - big-endian mips64 userland is unsupported, but booting the big-endian mips32 userland on mips64 hardware is clearly meant to work - they even ship a 64bit kernel built for that. IOW, both O32 and N32 coredumps in 64bit mips kernels have broken NT_FILE and NT_SIGINFO. And while NT_SIGINFO breakage is really visible only on b-e, NT_FILE one is common to b-e and l-e. One of the effects of the latter is that current gdb fails to work with threaded coredumps of 32bit processes produced on boxen with 64bit kernels. Coredumps generated by gcore(1) are fine... I think the following ought to be applied. Comments? [mips] fix malformed NT_FILE and NT_SIGINFO in 32bit coredumps Patches that introduced NT_FILE and NT_SIGINFO notes back in 2012 had taken care of native (fs/binfmt_elf.c) and compat (fs/compat_binfmt_elf.c) coredumps; unfortunately, compat on mips (which does not go through the usual compat_binfmt_elf.c) had not been noticed. As the result, both N32 and O32 coredumps on 64bit mips kernels have those sections malformed enough to confuse the living hell out of all gdb and readelf versions (up to and including the tip of binutils-gdb.git). Longer term solution is to make both O32 and N32 compat use the regular compat_binfmt_elf.c, but that's too much for backports. The minimal solution is to do in arch/mips/kernel/binfmt_elf[on]32.c the same thing those patches have done in fs/compat_binfmt_elf.c Cc: stable@kernel.org # v3.7+ Signed-off-by: Al Viro --- diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 6ee3f7218c67..c4441416e96b 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -103,4 +103,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) #undef ns_to_kernel_old_timeval #define ns_to_kernel_old_timeval ns_to_old_timeval32 +/* + * Some data types as stored in coredump. + */ +#define user_long_t compat_long_t +#define user_siginfo_t compat_siginfo_t +#define copy_siginfo_to_external copy_siginfo_to_external32 + #include "../../../fs/binfmt_elf.c" diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 6dd103d3cebb..7b2a23f48c1a 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -106,4 +106,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) #undef ns_to_kernel_old_timeval #define ns_to_kernel_old_timeval ns_to_old_timeval32 +/* + * Some data types as stored in coredump. + */ +#define user_long_t compat_long_t +#define user_siginfo_t compat_siginfo_t +#define copy_siginfo_to_external copy_siginfo_to_external32 + #include "../../../fs/binfmt_elf.c"