Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp3071584ybl; Mon, 19 Aug 2019 11:41:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqysh3iDd/HELhLJ0F1Vp9X8zCHGpc4TNgktNQyc+HTknw65r4T8/ACWohSHIDJ0ljfCR9S6 X-Received: by 2002:a63:6206:: with SMTP id w6mr21100771pgb.428.1566240107215; Mon, 19 Aug 2019 11:41:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566240107; cv=none; d=google.com; s=arc-20160816; b=laU6RGntlrBNB3xXK9aoXM5MF+sBHcK+l4aEaNuv6bHIpknxq6o4WEq5VgV5L94d14 EU5VvAMKcPFG/iuRB0UTpHF/IzlIXXRdjNsEvIfZA3iPa5GGPkxq9NPljXCnlJnsFGLZ YDGy/9qngvORTYzgmFE4J88fL+CeXDZgTnMrGvo7Chs180MAnt/B6rQvyS1cEoe/V4xM Ahl6XBLoVBstr1Wz4QeypKrh0DAkrflnSJRBPOv1a7DW5JWPuJ5PrXR1JW7rfvpmF/1U Sk3W7rtnQ7kEkLvEQrCXWQuBgPq7mu2qq+Q9oW3XOOQLhct0gJFAEG0Ah2ndRIaKCVVv G7iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:to:from:subject:message-id :dkim-signature; bh=xdL9I01Wyzr1jytnjjoTBGyvEzEJQA2seX7rzKT4CWs=; b=RoEtDEH/J7m7IbLjjHZ1z24gLBXC827o/wzliKCzNSVEoQZ/Rhwh9IILExkzD0rGBJ AKCx7Re8jJimrD40RFe+wLL5EFrkFXG5aUewYTeBdCS42rICJmalJdWDZtnYSBnM/dgb umfomqXM4+GhwGopZij73aiLSxdzDmF2FCctidnLwebp3CcOYngOpxYzVYB8l5um4cCu 4AW4eidQdRirtC11U1y5USL1oqRMcczHgm1hJwJuEMuUX8KULhEW87RQKv3nDz5fENTZ eT7NKh6vbdkr70Z6A2Ij7oQCZdZe3J4997bNEJhamFnZPRr1pHLjkNYp8MZzzOmh0GcC bg5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sam.st header.s=default header.b=Qvre6CMz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sam.st Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n59si10556056plb.191.2019.08.19.11.41.31; Mon, 19 Aug 2019 11:41:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@sam.st header.s=default header.b=Qvre6CMz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sam.st Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728311AbfHSSkO (ORCPT + 99 others); Mon, 19 Aug 2019 14:40:14 -0400 Received: from sam.st ([5.44.101.18]:44383 "EHLO mail.sam.st" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727957AbfHSSkM (ORCPT ); Mon, 19 Aug 2019 14:40:12 -0400 Received: from workstation-ibk (212-186-61-58.cable.dynamic.surfer.at [212.186.61.58]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.sam.st (Postfix) with ESMTPSA id 928EE300109; Mon, 19 Aug 2019 20:40:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sam.st; s=default; t=1566240008; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xdL9I01Wyzr1jytnjjoTBGyvEzEJQA2seX7rzKT4CWs=; b=Qvre6CMzceaiZaWQ6Z7Y7rEtaP5eY0nPJ36IyPnyLUS9UuLNahbZwA6bP7eXWnR+AFqj42 c47B4FFezAsU9SWeqMgoxWJ1XxvyUz4nyCR+Pzp7/ZiS5JaVXY7DuPWJYjHsjxBuOHkM3U tE17vdjS0OFdyveh0DmM2d5OyiaCh08= Message-ID: <2d8f1744136431b5eb0bda24ea767374d6fde4e5.camel@sam.st> Subject: Re: [PATCH] uprobes/x86: fix detection of 32-bit user mode From: Sebastian Mayr To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , x86@kernel.org, linux-kernel@vger.kernel.org Date: Mon, 19 Aug 2019 20:40:07 +0200 In-Reply-To: <20190728152617.7308-1-me@sam.st> References: <20190728152617.7308-1-me@sam.st> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.32.4 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, 2019-07-28 at 17:26 +0200, Sebastian Mayr wrote: > 32-bit processes running on a 64-bit kernel are not always detected > correctly, causing the process to crash when uretprobes are > installed. > The reason for the crash is that in_ia32_syscall() is used to > determine > the process's mode, which only works correctly when called from a > syscall. In the case of uretprobes, however, the function is called > from > a software interrupt and always returns 'false' (on a 64-bit kernel). > In > consequence this leads to corruption of the process's return address. > > This can be fixed by using user_64bit_mode(), which should always be > correct. > > Signed-off-by: Sebastian Mayr > --- > > Please note that I just stumbled over this bug and am not really > familiar with all the internals. So take the patch and, in > particular, > the commit message with a grain of salt. Thanks! > > arch/x86/kernel/uprobes.c | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c > index 918b5092a85f..d6e261202c6b 100644 > --- a/arch/x86/kernel/uprobes.c > +++ b/arch/x86/kernel/uprobes.c > @@ -508,9 +508,9 @@ struct uprobe_xol_ops { > void (*abort)(struct arch_uprobe *, struct pt_regs *); > }; > > -static inline int sizeof_long(void) > +static inline int sizeof_long(struct pt_regs *regs) > { > - return in_ia32_syscall() ? 4 : 8; > + return user_64bit_mode(regs) ? 8 : 4; > } > > static int default_pre_xol_op(struct arch_uprobe *auprobe, struct > pt_regs *regs) > @@ -521,9 +521,9 @@ static int default_pre_xol_op(struct arch_uprobe > *auprobe, struct pt_regs *regs) > > static int emulate_push_stack(struct pt_regs *regs, unsigned long > val) > { > - unsigned long new_sp = regs->sp - sizeof_long(); > + unsigned long new_sp = regs->sp - sizeof_long(regs); > > - if (copy_to_user((void __user *)new_sp, &val, sizeof_long())) > + if (copy_to_user((void __user *)new_sp, &val, > sizeof_long(regs))) > return -EFAULT; > > regs->sp = new_sp; > @@ -556,7 +556,7 @@ static int default_post_xol_op(struct arch_uprobe > *auprobe, struct pt_regs *regs > long correction = utask->vaddr - utask->xol_vaddr; > regs->ip += correction; > } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { > - regs->sp += sizeof_long(); /* Pop incorrect return > address */ > + regs->sp += sizeof_long(regs); /* Pop incorrect return > address */ > if (emulate_push_stack(regs, utask->vaddr + auprobe- > >defparam.ilen)) > return -ERESTART; > } > @@ -675,7 +675,7 @@ static int branch_post_xol_op(struct arch_uprobe > *auprobe, struct pt_regs *regs) > * "call" insn was executed out-of-line. Just restore ->sp and > restart. > * We could also restore ->ip and try to call > branch_emulate_op() again. > */ > - regs->sp += sizeof_long(); > + regs->sp += sizeof_long(regs); > return -ERESTART; > } > > @@ -1056,7 +1056,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe > *auprobe, struct pt_regs *regs) > unsigned long > arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, > struct pt_regs *regs) > { > - int rasize = sizeof_long(), nleft; > + int rasize = sizeof_long(regs), nleft; > unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit > apps */ > > if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, > rasize)) Any feedback on this patch would be greatly appreciated. Thanks, Sebastian