From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751586AbcGNVij (ORCPT ); Thu, 14 Jul 2016 17:38:39 -0400 Received: from mail-wm0-f46.google.com ([74.125.82.46]:38466 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750876AbcGNVig (ORCPT ); Thu, 14 Jul 2016 17:38:36 -0400 MIME-Version: 1.0 In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> From: Kees Cook Date: Thu, 14 Jul 2016 14:38:33 -0700 X-Google-Sender-Auth: ULAFpC4R6AHxGPSkFrVHgeKoeaM Message-ID: Subject: Re: [PATCH v2 01/11] mm: Implement stack frame object validation To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski , Borislav Petkov , Mathias Krause , Jan Kara , Vitaly Wool , Andrea Arcangeli , Dmitry Vyukov , Laura Abbott , "linux-arm-kernel@lists.infradead.org" , "linux-ia64@vger.kernel.org" , "linuxppc-dev@lists.ozlabs.org" , sparclinux , linux-arch , "linux-mm@kvack.org" , "kernel-hardening@lists.openwall.com" Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kees Cook Subject: Re: [PATCH v2 01/11] mm: Implement stack frame object validation Date: Thu, 14 Jul 2016 14:38:33 -0700 Message-ID: References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Return-path: In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> Sender: owner-linux-mm@kvack.org To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski Borislav Petkov List-Id: linux-arch.vger.kernel.org On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f47.google.com ([74.125.82.47]:38466 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751453AbcGNVig (ORCPT ); Thu, 14 Jul 2016 17:38:36 -0400 Received: by mail-wm0-f47.google.com with SMTP id o80so5155442wme.1 for ; Thu, 14 Jul 2016 14:38:35 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> From: Kees Cook Date: Thu, 14 Jul 2016 14:38:33 -0700 Message-ID: Subject: Re: [PATCH v2 01/11] mm: Implement stack frame object validation Content-Type: text/plain; charset=UTF-8 Sender: linux-arch-owner@vger.kernel.org List-ID: To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski , Borislav Petkov , Mathias Krause , Jan Kara , Vitaly Wool , Andrea Arcangeli , Dmitry Vyukov , Laura Abbott , "linux-arm-kernel@lists.infradead.org" , "linux-ia64@vger.kernel.org" , "linuxppc-dev@lists.ozlabs.org" , sparclinux , linux-arch , "linux-mm@kvack.org" , "kernel-hardening@lists.openwall.com" Message-ID: <20160714213833.E83TgbvPVOFj8Ufy7sDVGZa_qemxEQpDuwYrtczmEoI@z> On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kees Cook Date: Thu, 14 Jul 2016 21:38:33 +0000 Subject: Re: [PATCH v2 01/11] mm: Implement stack frame object validation Message-Id: List-Id: References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski , Borislav Petkov , Mathias Krause , Jan Kara , Vitaly Wool , Andrea Arcangeli , Dmitry Vyukov , Laura Abbott , "linux-arm-kernel@lists.infradead.org" , "linux-ia64@vger.kernel.org" , "linuxppc-dev@lists.ozlabs.org" , sparclinux , linux-arch , "linux-mm@kvack.org" , "kernel-hardening@lists.openwall.com" On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf0-f72.google.com (mail-lf0-f72.google.com [209.85.215.72]) by kanga.kvack.org (Postfix) with ESMTP id 33C196B026D for ; Thu, 14 Jul 2016 17:38:36 -0400 (EDT) Received: by mail-lf0-f72.google.com with SMTP id l89so60679166lfi.3 for ; Thu, 14 Jul 2016 14:38:36 -0700 (PDT) Received: from mail-wm0-x232.google.com (mail-wm0-x232.google.com. [2a00:1450:400c:c09::232]) by mx.google.com with ESMTPS id g76si460794wmg.106.2016.07.14.14.38.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Jul 2016 14:38:34 -0700 (PDT) Received: by mail-wm0-x232.google.com with SMTP id f126so4413938wma.1 for ; Thu, 14 Jul 2016 14:38:34 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> From: Kees Cook Date: Thu, 14 Jul 2016 14:38:33 -0700 Message-ID: Subject: Re: [PATCH v2 01/11] mm: Implement stack frame object validation Content-Type: text/plain; charset=UTF-8 Sender: owner-linux-mm@kvack.org List-ID: To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski , Borislav Petkov , Mathias Krause , Jan Kara , Vitaly Wool , Andrea Arcangeli , Dmitry Vyukov , Laura Abbott , "linux-arm-kernel@lists.infradead.org" , "linux-ia64@vger.kernel.org" , "linuxppc-dev@lists.ozlabs.org" , sparclinux , linux-arch , "linux-mm@kvack.org" , "kernel-hardening@lists.openwall.com" On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 From: keescook@chromium.org (Kees Cook) Date: Thu, 14 Jul 2016 14:38:33 -0700 Subject: [PATCH v2 01/11] mm: Implement stack frame object validation In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe at redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security From mboxrd@z Thu Jan 1 00:00:00 1970 Reply-To: kernel-hardening@lists.openwall.com MIME-Version: 1.0 Sender: keescook@google.com In-Reply-To: <20160714192351.567fmaz2h4drrxrc@treble> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> <1468446964-22213-2-git-send-email-keescook@chromium.org> <20160714054842.6zal5rqawpgew26r@treble> <20160714192351.567fmaz2h4drrxrc@treble> From: Kees Cook Date: Thu, 14 Jul 2016 14:38:33 -0700 Message-ID: Content-Type: text/plain; charset=UTF-8 Subject: [kernel-hardening] Re: [PATCH v2 01/11] mm: Implement stack frame object validation To: Josh Poimboeuf Cc: Andy Lutomirski , "linux-kernel@vger.kernel.org" , Rik van Riel , Casey Schaufler , PaX Team , Brad Spengler , Russell King , Catalin Marinas , Will Deacon , Ard Biesheuvel , Benjamin Herrenschmidt , Michael Ellerman , Tony Luck , Fenghua Yu , "David S. Miller" , X86 ML , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Andy Lutomirski , Borislav Petkov , Mathias Krause , Jan Kara , Vitaly Wool , Andrea Arcangeli , Dmitry Vyukov , Laura Abbott , "linux-arm-kernel@lists.infradead.org" , "linux-ia64@vger.kernel.org" , "linuxppc-dev@lists.ozlabs.org" , sparclinux , linux-arch , "linux-mm@kvack.org" , "kernel-hardening@lists.openwall.com" List-ID: On Thu, Jul 14, 2016 at 12:23 PM, Josh Poimboeuf wrote: > On Thu, Jul 14, 2016 at 11:10:18AM -0700, Kees Cook wrote: >> On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf wrote: >> > On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote: >> >> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski wrote: >> >> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook wrote: >> >> >> This creates per-architecture function arch_within_stack_frames() that >> >> >> should validate if a given object is contained by a kernel stack frame. >> >> >> Initial implementation is on x86. >> >> >> >> >> >> This is based on code from PaX. >> >> >> >> >> > >> >> > This, along with Josh's livepatch work, are two examples of unwinders >> >> > that matter for correctness instead of just debugging. ISTM this >> >> > should just use Josh's code directly once it's been written. >> >> >> >> Do you have URL for Josh's code? I'd love to see what happening there. >> > >> > The code is actually going to be 100% different next time around, but >> > FWIW, here's the last attempt: >> > >> > https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@redhat.com >> > >> > In the meantime I've realized the need to rewrite the x86 core stack >> > walking code to something much more manageable so we don't need all >> > these unwinders everywhere. I'll probably post the patches in the next >> > week or so. I'll add you to the CC list. >> >> Awesome! >> >> > With the new interface I think you'll be able to do something like: >> > >> > struct unwind_state; >> > >> > unwind_start(&state, current, NULL, NULL); >> > unwind_next_frame(&state); >> > oldframe = unwind_get_stack_pointer(&state); >> > >> > unwind_next_frame(&state); >> > frame = unwind_get_stack_pointer(&state); >> > >> > do { >> > if (obj + len <= frame) >> > return blah; >> > oldframe = frame; >> > frame = unwind_get_stack_pointer(&state); >> > >> > } while (unwind_next_frame(&state); >> > >> > And then at the end there'll be some (still TBD) way to query whether it >> > reached the last syscall pt_regs frame, or if it instead encountered a >> > bogus frame pointer along the way and had to bail early. >> >> Sounds good to me. Will there be any frame size information available? >> Right now, the unwinder from PaX just drops 2 pointers (saved frame, >> saved ip) from the delta of frame address to find the size of the >> actual stack area used by the function. If I could shave things like >> padding and possible stack canaries off the size too, that would be >> great. > > For x86, stacks are aligned at long word boundaries, so there's no real > stack padding. Well, I guess I meant the possible padding between variables and the aligned pointers, but that's a really minor concern in my mind (as far as being a potential kernel memory exposure on a bad usercopy). > Also the CC_STACKPROTECTOR stack canaries are created by a gcc feature > which only affects certain functions (and thus certain frames) and I > don't know of any reliable way to find them. Okay, that's fine. I had a horrible idea to just have the unwinder look at the value stored in front of the saved ip, and if it matches the known canary (for current anyway), then reduce the frame size by another long word. ;) > So with frame pointers, I think the best you can do is just assume that > the frame data area is always two words smaller than the total frame > size. Yeah, that's what's happening here currently. Cool. >> Since I'm aiming the hardened usercopy series for 4.8, I figure I'll >> just leave this unwinder in for now, and once yours lands, I can rip >> it out again. > > Sure, sounds fine to me. If your code lands before I post mine, I can > convert it myself. Awesome, I'll keep you posted. Thanks! -Kees -- Kees Cook Chrome OS & Brillo Security