From patchwork Wed Jan 3 21:29:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rolf Eike Beer X-Patchwork-Id: 855247 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=sparclinux-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zBkbz1KX9z9s7G for ; Thu, 4 Jan 2018 08:30:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751319AbeACVaF (ORCPT ); Wed, 3 Jan 2018 16:30:05 -0500 Received: from mail.sf-mail.de ([78.47.74.12]:60139 "EHLO mail.sf-mail.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751233AbeACVaE (ORCPT ); Wed, 3 Jan 2018 16:30:04 -0500 Received: (qmail 15697 invoked from network); 3 Jan 2018 21:30:02 -0000 Received: from dslb-092-076-171-216.092.076.pools.vodafone-ip.de ([::ffff:92.76.171.216]:43488 HELO eto.sf-tec.de) (auth=eike@sf-mail.de) by mail.sf-mail.de (Qsmtpd 0.34dev) with (DHE-RSA-AES256-SHA encrypted) ESMTPSA for ; Wed, 03 Jan 2018 22:30:02 +0100 From: Rolf Eike Beer To: sparclinux@vger.kernel.org, "Eric W. Biederman" Subject: sending SIGFPE via kill() returns wrong values in si_pid and si_uid Date: Wed, 03 Jan 2018 22:29:55 +0100 Message-ID: <1942316.IfptgDaGPd@eto> User-Agent: KMail/4.14.10 (Linux/4.14.6-2.g9248b63-default; KDE/4.14.25; x86_64; ; ) MIME-Version: 1.0 Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org This originally came up as a failure in the testsuite of strace on Gentoo (T5120, 64 bit kernel, 32 bit userspace) and was reported here: https://bugs.gentoo.org/643060. This was then reported upstream here: https://github.com/strace/strace/issues/21 . I'll paste the relevant parts of those bugs here. The test program is as follows (done by Dmitry V. Levin): #include #include #include #include static void handler(int sig, siginfo_t *info, void *ucontext) { fprintf(stderr, "sig=%d, si_signo=%d, si_pid=%d, si_uid=%d\n", sig, info->si_signo, info->si_pid, info->si_uid); } static void setup(int sig, sigset_t *mask) { static const struct sigaction act = { .sa_sigaction = handler, .sa_flags = SA_SIGINFO }; assert(!sigaction(sig, &act, NULL)); assert(!sigaddset(mask, sig)); } static void test(int sig) { assert(!raise(sig)); assert(!kill(getpid(), sig)); } int main(void) { sigset_t mask; assert(!sigemptyset(&mask)); setup(SIGFPE, &mask); setup(SIGTERM, &mask); assert(!sigprocmask(SIG_UNBLOCK, &mask, NULL)); test(SIGFPE); test(SIGTERM); return 0; } Running this on sparc64 userspace works fine: sig=8, si_signo=8, si_pid=135186, si_uid=1008 sig=8, si_signo=8, si_pid=135186, si_uid=1008 sig=15, si_signo=15, si_pid=135186, si_uid=1008 sig=15, si_signo=15, si_pid=135186, si_uid=1008 However, on sparc32 things go wrong: sig=8, si_signo=8, si_pid=135192, si_uid=1008 sig=8, si_signo=8, si_pid=1008, si_uid=0 sig=15, si_signo=15, si_pid=135192, si_uid=1008 sig=15, si_signo=15, si_pid=135192, si_uid=1008 When digging the code up and down I came up with this patch, which fixes the issue for me: I suspect it was broken by cc731525f26af85a1c3537da41e0abd1d35e0bdb as it is reported that it worked in 4.5.0. Looking at that commit other archs (at least arm64, mips, parisc, powerpc, s390, tile, x86) have the same code, but different default-cases. From a quick glance arm64, parisc, and x86 do not have a default case anymore since that commit, while the others do not seem to have changed their default case. However it could be that siginfo_layout() behaves slightly different than the mask code used before in the switch statements. I'm currently building a 4.14.9 kernel for my HP C8000, will report the test results once that is done. Eike diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 54a6159b9cd8..a05e271e0924 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -87,7 +87,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); err |= __put_user(from->si_code, &to->si_code); - if (from->si_code < 0) + if (SI_FROMUSER(from)) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { switch (siginfo_layout(from->si_signo, from->si_code)) {