From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757343AbcGZRH2 (ORCPT ); Tue, 26 Jul 2016 13:07:28 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:37353 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757062AbcGZRHZ (ORCPT ); Tue, 26 Jul 2016 13:07:25 -0400 MIME-Version: 1.0 In-Reply-To: <20160726170052.GI4541@io.lakedaemon.net> References: <1469471141-25669-1-git-send-email-william.c.roberts@intel.com> <20160726030201.6775-1-jason@lakedaemon.net> <20160726033032.GD4541@io.lakedaemon.net> <20160726170052.GI4541@io.lakedaemon.net> From: Kees Cook Date: Tue, 26 Jul 2016 10:07:22 -0700 X-Google-Sender-Auth: JiQt0K211ALhkjjki8yZnQcQNy4 Message-ID: Subject: Re: [RFC patch 1/6] random: Simplify API for random address requests To: Jason Cooper Cc: "Roberts, William C" , linux-mm@vger.kernel.org, LKML , "kernel-hardening@lists.openwall.com" , Russell King - ARM Linux , Andrew Morton , "Theodore Ts'o" , Arnd Bergmann , Greg KH , Catalin Marinas , Will Deacon , Ralf Baechle , "benh@kernel.crashing.org" , Paul Mackerras , Michael Ellerman , "David S. Miller" , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , "x86@kernel.org" , Al Viro , Nick Kralevich , Jeffrey Vander Stoep , alyzyn@android.com, Daniel Cashman 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 Tue, Jul 26, 2016 at 10:00 AM, Jason Cooper wrote: > Hi Kees, > > On Mon, Jul 25, 2016 at 09:39:58PM -0700, Kees Cook wrote: >> On Mon, Jul 25, 2016 at 8:30 PM, Jason Cooper wrote: >> > On Tue, Jul 26, 2016 at 03:01:55AM +0000, Jason Cooper wrote: >> >> To date, all callers of randomize_range() have set the length to 0, and >> >> check for a zero return value. For the current callers, the only way >> >> to get zero returned is if end <= start. Since they are all adding a >> >> constant to the start address, this is unnecessary. >> >> >> >> We can remove a bunch of needless checks by simplifying the API to do >> >> just what everyone wants, return an address between [start, start + >> >> range]. >> >> >> >> While we're here, s/get_random_int/get_random_long/. No current call >> >> site is adversely affected by get_random_int(), since all current range >> >> requests are < MAX_UINT. However, we should match caller expectations > > merf. UINT_MAX. > >> >> to avoid coming up short (ha!) in the future. >> >> >> >> Signed-off-by: Jason Cooper >> >> --- >> >> drivers/char/random.c | 17 ++++------------- >> >> include/linux/random.h | 2 +- >> >> 2 files changed, 5 insertions(+), 14 deletions(-) >> >> >> >> diff --git a/drivers/char/random.c b/drivers/char/random.c >> >> index 0158d3bff7e5..1251cb2cbab2 100644 >> >> --- a/drivers/char/random.c >> >> +++ b/drivers/char/random.c >> >> @@ -1822,22 +1822,13 @@ unsigned long get_random_long(void) >> >> EXPORT_SYMBOL(get_random_long); >> >> >> >> /* >> >> - * randomize_range() returns a start address such that >> >> - * >> >> - * [...... .....] >> >> - * start end >> >> - * >> >> - * a with size "len" starting at the return value is inside in the >> >> - * area defined by [start, end], but is otherwise randomized. >> >> + * randomize_addr() returns a page aligned address within [start, start + >> >> + * range] >> >> */ >> >> unsigned long >> >> -randomize_range(unsigned long start, unsigned long end, unsigned long len) >> >> +randomize_addr(unsigned long start, unsigned long range) >> >> { >> >> - unsigned long range = end - len - start; >> >> - >> >> - if (end <= start + len) >> >> - return 0; >> >> - return PAGE_ALIGN(get_random_int() % range + start); >> >> + return PAGE_ALIGN(get_random_long() % range + start); >> >> } >> > >> > bah! old patch file. This should have been: >> > >> > if (range == 0) >> > return start; >> > else >> > return PAGE_ALIGN(get_random_long() % range + start); >> >> I think range should be limited to start + range < UINTMAX, > > ULONG_MAX? I agree. Heh, I am plagued by misspelling these constants, and yes, sorry, ULONG_MAX. :) > if (range == 0 || ULONG_MAX - range < start) > return start; Should it "abort" like this? I was thinking just cap the range, something like: if (range > ULONG_MAX - start) range = ULONG_MAX - start > else > return PAGE_ALIGN(get_random_long() % range + start); > > ? > >> and it should be very clear if the range is inclusive or exclusive. > > Sorry, I was reading the original comment, '[start, end]' with square > brackets denoting inclusive. > > Regardless, the math in randomize_range() was just undoing the math at > each of the call sites. This proposed change to randomize_addr() > doesn't alter the current state of affairs wrt inclusive, exclusive. > >> start = 0, range = 4096. does this mean 1 page, or 2 pages possible? > > ooh, good spot. What we have right now is [start, start + range), which > is matching previous behavior. But does not match the old comment, > [start, end]. It should have been [start, end). > > So, you're correct, I need to clarify this in the comments. Okay, cool. Thanks! I'm glad to have this clean-up. :) -Kees > > thx, > > Jason. -- Kees Cook Chrome OS & Brillo Security