From patchwork Tue Feb 22 20:30:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Wolf X-Patchwork-Id: 84003 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bilbo.ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 167D1B73F8 for ; Wed, 23 Feb 2011 07:31:16 +1100 (EST) Received: by ozlabs.org (Postfix) id 9BCE3B70A4; Wed, 23 Feb 2011 07:30:59 +1100 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e36.co.us.ibm.com", Issuer "Equifax" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id 34ED6B6F12 for ; Wed, 23 Feb 2011 07:30:59 +1100 (EST) Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e36.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p1MKPeXG013540 for ; Tue, 22 Feb 2011 13:25:40 -0700 Received: from d03av05.boulder.ibm.com (d03av05.boulder.ibm.com [9.17.195.85]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p1MKUlps117564 for ; Tue, 22 Feb 2011 13:30:47 -0700 Received: from d03av05.boulder.ibm.com (loopback [127.0.0.1]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p1MKUlM4020686 for ; Tue, 22 Feb 2011 13:30:47 -0700 Received: from [9.12.227.101] ([9.12.227.101]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p1MKUkPe020649; Tue, 22 Feb 2011 13:30:47 -0700 Subject: powerpc/ptrace: Fix bug in signal handling From: Michael Wolf To: linuxppc-dev@ozlabs.org Organization: IBM Date: Tue, 22 Feb 2011 14:30:45 -0600 Message-ID: <1298406645.9824.3.camel@w500> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 Cc: anton@samba.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: mjw@us.ibm.com List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org In some cases during a threaded core dump not all the threads will have a full register set. This will cause problems when the sigkill is sent to the thread Signed-off-by: Mike Wolf ------- --- ptrace-signal.orig/arch/powerpc/kernel/ptrace.c 2011-02-20 12:15:57.000000000 -0600 +++ ptrace-signal/arch/powerpc/kernel/ptrace.c 2011-02-21 12:39:17.000000000 -0600 @@ -234,11 +234,23 @@ if (target->thread.regs == NULL) return -EIO; - CHECK_FULL_REGS(target->thread.regs); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - target->thread.regs, - 0, offsetof(struct pt_regs, msr)); + if (!FULL_REGS(target->thread.regs)) { + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + target->thread.regs, + 0, sizeof(long)*PT_R14); + if (!ret) + ret = user_regset_copyout_poison(&pos, &count, &kbuf, &ubuf, + sizeof(long)*PT_R14, offsetof(struct pt_regs, nip)); + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + target->thread.regs, + offsetof(struct pt_regs, nip), offsetof(struct pt_regs, msr)); + + } else + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + target->thread.regs, + 0, offsetof(struct pt_regs, msr)); if (!ret) { unsigned long msr = get_user_msr(target); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, @@ -645,11 +657,24 @@ if (target->thread.regs == NULL) return -EIO; - CHECK_FULL_REGS(target->thread.regs); - pos /= sizeof(reg); count /= sizeof(reg); + if(!FULL_REGS(target->thread.regs)) { + if (kbuf) { + for (; count > 0 && pos < PT_R14; --count) + *k++ = regs[pos++]; + for (; count > 0 && pos < PT_R31; --count,pos++) + *k++ = 0xdeadbeef; + } else { + for (; count > 0 && pos < PT_R14; --count) + if (__put_user((compat_ulong_t) regs[pos++], u++)) + return -EFAULT; + for (; count > 0 && pos < PT_R31; --count,pos++) + if (__put_user((compat_ulong_t) 0xdeadbeef, u++)) + return -EFAULT; + } + } if (kbuf) for (; count > 0 && pos < PT_MSR; --count) *k++ = regs[pos++]; --- ptrace-signal.orig/include/linux/regset.h 2011-02-20 12:15:57.000000000 -0600 +++ ptrace-signal/include/linux/regset.h 2011-02-21 12:39:17.000000000 -0600 @@ -240,6 +240,32 @@ } return 0; } +static inline int user_regset_copyout_poison(unsigned int *pos, + unsigned int *count, + void **kbuf, void __user **ubuf, + const int start_pos, + const int end_pos) +{ + long poison_data[17] = { [0 ... 16] = 0xdeadbeefdeadbeefUL }; + + if (*count == 0) + return 0; + BUG_ON(*pos < start_pos); + if (end_pos < 0 || *pos < end_pos) { + unsigned int copy = (end_pos < 0 ? *count + : min(*count, end_pos - *pos)); + if (*kbuf) { + memset(*kbuf, 0xdeadbeef, copy); + *kbuf += copy; + } else if (__copy_to_user(*ubuf,poison_data, copy)) + return -EFAULT; + else + *ubuf += copy; + *pos += copy; + *count -= copy; + } + return 0; +} static inline int user_regset_copyin(unsigned int *pos, unsigned int *count, const void **kbuf,