From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752448AbcFTF6y (ORCPT ); Mon, 20 Jun 2016 01:58:54 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:54514 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752403AbcFTF6q (ORCPT ); Mon, 20 Jun 2016 01:58:46 -0400 X-IBM-Helo: d06dlp02.portsmouth.uk.ibm.com X-IBM-MailFrom: heiko.carstens@de.ibm.com X-IBM-RcptTo: linux-kernel@vger.kernel.org Date: Mon, 20 Jun 2016 07:58:36 +0200 From: Heiko Carstens To: Andy Lutomirski Cc: Nadav Amit , Kees Cook , Josh Poimboeuf , Borislav Petkov , X86 ML , "kernel-hardening@lists.openwall.com" , Brian Gerst , "linux-kernel@vger.kernel.org" , Linus Torvalds Subject: Re: [PATCH 00/13] Virtually mapped stacks with guard pages (x86, core) References: <20160616060538.GA3923@osiris> <20160617072737.GA3960@osiris> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062005-0032-0000-0000-000001DB6D15 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062005-0033-0000-0000-00001B70B52B Message-Id: <20160620055836.GA3266@osiris> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-06-20_03:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606200071 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jun 17, 2016 at 10:38:24AM -0700, Andy Lutomirski wrote: > > A disassembly looks like this (r15 is the stackpointer): > > > > 0000000000000670 : > > 670: eb 6f f0 48 00 24 stmg %r6,%r15,72(%r15) > > 676: c0 d0 00 00 00 00 larl %r13,676 > > 67c: a7 f1 3f 80 tmll %r15,16256 <--- test if enough space left > > 680: b9 04 00 ef lgr %r14,%r15 > > 684: a7 84 00 01 je 686 <--- branch to illegal op > > 688: e3 f0 ff 90 ff 71 lay %r15,-112(%r15) > > > > The branch jumps actually into the branch instruction itself since the 0001 > > part of the "je" instruction is an illegal instruction. > > > > This catches at least wild stack overflows because of two many functions > > being called. > > > > Of course it doesn't catch wild accesses outside the stack because e.g. the > > index into an array on the stack is wrong. > > > > The runtime overhead is within noise ratio, therefore we have this always > > enabled. > > > > Neat! What exactly does tmll do? I assume this works by checking the > low bits of the stack pointer. > > x86_64 would have to do: > > movl %esp, %r11d > shll %r11d, $18 > cmpl %r11d, > jg error > > Or similar. I think the cmpl could be eliminated if the threshold > were a power of two by simply testing the low bits of the stack > pointer. The tmll instruction tests if any of the higher bits within the 16k stackframe address are set. In this specific case that would be bits 7-15 (mask 0x3f80). If no bit would be set we know that only up to 128 bytes would be left on the stack, and thus trigger an exception. This check does of course only work if a 16k stack is also 16k aligned, which is always the case.