Received: by 10.192.165.148 with SMTP id m20csp194350imm; Wed, 9 May 2018 11:01:18 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqIm4sfBTcf+cdOy00Ce47zCUAttl/5d2nJlPANAzAMYjf9Hl755xkv/SadX2/UdrRkckAk X-Received: by 2002:a17:902:f44:: with SMTP id 62-v6mr46779705ply.318.1525888878102; Wed, 09 May 2018 11:01:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525888878; cv=none; d=google.com; s=arc-20160816; b=TkX+7559GlilLarK7MPtGTGH6gWJJjpwUDA8R26WKOC4e8VmTO94kXTsNE1y/Z+PMN fDfjF/Neol6CIdRM0vLi5g4MJYi9vmqFVv3rm+bii+AFAoG1U2yOBf3ozeNMWcOMX/Rz JzpuY17PfjyKJ3fYqF675G6YUJ2kyeynAK6fwJl2Scm28rnjz/1GfsuTBPGbR2CYH6gp tSi3HAB0D/hGuMkDkw+F099gIReP4KjpxtXSmrp3ee9p7J6yW6scgHvn/0lipjRuvHDe DtmHtYJ3+I4UIXbBPdX8O4Jg6/7duQ6ggCQQA28ryq10wrH7sDvhzVM9x7VA3Vy5rc/Y J7ew== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=m0TfTdDRMd5r1JXLiucbBtRh+J/z/Gw1zuhOxk2DEZU=; b=sSfwCJlmZaSpwLLb7lrjz/6MAcYvR+qsp8yTldjukwzjMHzK3zUVlo/NyGKa4d55cH DcM1FhTWNs88HGbOByaph4Rpf4OUuuJto0QodX1iLXKg+C2qz9NpZRH7jXip1WmZhxfU gKykmCoVYTwbltmr+6wvJONF3NA7/s2v/AFxHuM8dP2WbSFYFy5lFq4qXgqg5g6k8V5z J1hkHcg/qSjCKU8/WnNjSMxaHBs4bV2uhzVL6Xitf2fRKrcZHKv9YDUNV6MEdtUSYGp5 GW5z8lEG87DgiaF2J9AtjQuyQIRPKEJE0FN0h2el0ky5akXqPRPM7Rmlji+1k6Vu0CaQ 0jAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@rasmusvillemoes.dk header.s=google header.b=aLNE3mua; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a15-v6si13417027pgd.531.2018.05.09.11.01.02; Wed, 09 May 2018 11:01:18 -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=@rasmusvillemoes.dk header.s=google header.b=aLNE3mua; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935331AbeEISAf (ORCPT + 99 others); Wed, 9 May 2018 14:00:35 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:40503 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935049AbeEISAe (ORCPT ); Wed, 9 May 2018 14:00:34 -0400 Received: by mail-wm0-f65.google.com with SMTP id j5-v6so29523469wme.5 for ; Wed, 09 May 2018 11:00:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=m0TfTdDRMd5r1JXLiucbBtRh+J/z/Gw1zuhOxk2DEZU=; b=aLNE3muahyBWBGlKsjXw6863hwQaScyq3uyAegcdEC4VepF4iXvoLuuYqzB/Ox5t6P HL6wewRbszGJDZpUtACzes2tgKkZropDSm4Iuy7a/eKpsBxi67j5KcLhm6iqc2bFXsjD +ZRajkIBMDDom+7yB16sLnKWYzHIthSYVZeww= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=m0TfTdDRMd5r1JXLiucbBtRh+J/z/Gw1zuhOxk2DEZU=; b=rEIlCDIn6g/mFq+qyUkSh9FCIb5K2NAu1mUMlQdma28YMTSZ6iQIuWMeQkQQxB2Bb2 DqN2xH20o0HJ0Zz55Ehi9myIdiXVWwomhVrXL/kz5SEDKKlLoCYLm9KP+6qmMJxJu3dC DlHD2JVK1Eiop9bjRaVe8LHcpNW7YZOUrKHBobMwf7Kxqr6BwmpoZWS3PLgwSflA4VAx 6kmnqV9uhTtucPItNdgDNROJAEbOG0B23jSlmvj18VrMynAgsmI9D6P2G20VACuTT3Rc gQTuaojXAMIlR6pPjix8396IdfYfyJs4oWt4L51pPAit2iEX2s+RWWrhwPuxgpM1NZba EtIg== X-Gm-Message-State: ALQs6tBE5ePuhWuxyJt+qb4ziG7DNh+RPCxo1XQnqi4ZImyAcGLJMBxy B2XtkkVRomY/cqQDISiOlV4JRQ== X-Received: by 2002:a50:b1e2:: with SMTP id n31-v6mr62433019edd.197.1525888833242; Wed, 09 May 2018 11:00:33 -0700 (PDT) Received: from [192.168.0.189] (dhcp-5-186-126-104.cgn.ip.fibianet.dk. [5.186.126.104]) by smtp.gmail.com with ESMTPSA id j2-v6sm15882903edp.22.2018.05.09.11.00.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 May 2018 11:00:32 -0700 (PDT) Subject: Re: [PATCH 04/13] mm: Use array_size() helpers for kmalloc() To: Matthew Wilcox , Kees Cook Cc: Matthew Wilcox , linux-kernel@vger.kernel.org, linux-mm@kvack.org, kernel-hardening@lists.openwall.com References: <20180509004229.36341-1-keescook@chromium.org> <20180509004229.36341-5-keescook@chromium.org> <20180509113446.GA18549@bombadil.infradead.org> From: Rasmus Villemoes Message-ID: Date: Wed, 9 May 2018 20:00:28 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: <20180509113446.GA18549@bombadil.infradead.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2018-05-09 13:34, Matthew Wilcox wrote: > On Tue, May 08, 2018 at 05:42:20PM -0700, Kees Cook wrote: >> @@ -499,6 +500,8 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) >> */ >> static __always_inline void *kmalloc(size_t size, gfp_t flags) >> { >> + if (size == SIZE_MAX) >> + return NULL; >> if (__builtin_constant_p(size)) { >> if (size > KMALLOC_MAX_CACHE_SIZE) >> return kmalloc_large(size, flags); > > I don't like the add-checking-to-every-call-site part of this patch. > Fine, the compiler will optimise it away if it can calculate it at compile > time, but there are a lot of situations where it can't. You aren't > adding any safety by doing this; trying to allocate SIZE_MAX bytes is > guaranteed to fail, and it doesn't need to fail quickly. Yeah, agree that we don't want to add a size check to all callers, including those where the size doesn't even come from one of the new *_size helpers; that just adds bloat. It's true that the overflow case does not have to fail quickly, but I was worried that the saturating helpers would end up making gcc emit a cmov instruction, thus stalling the regular path. But it seems that it actually ends up doing a forward jump, sets %rdi to SIZE_MAX, then jumps back to the call of __kmalloc, so it should be ok. With __builtin_constant_p(size) && size == SIZE_MAX, gcc could be smart enough to elide those two instructions and have the jo go directly to the caller's error handling, but at least gcc 5.4 doesn't seem to be that smart. So let's just omit that part for now. But in case of the kmalloc_array functions, with a direct call of __builtin_mul_overflow(), gcc does combine the "return NULL" with the callers error handling, thus avoiding the six byte "%rdi = -1; jmp back;" thunk. That, along with the churn factor, might be an argument for leaving the current callers of *_array alone. But if we are going to keep those longer-term, we might as well convert kmalloc(a, b) into kmalloc_array(a, b) instead of kmalloc(array_size(a, b)). In any case, I do see the usefulness of the struct_size helper, and agree that we definitely should not introduce a new *_struct variant that needs to be implemented in all families. >> @@ -624,11 +629,13 @@ int memcg_update_all_caches(int num_memcgs); >> */ >> static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) >> { >> - if (size != 0 && n > SIZE_MAX / size) >> + size_t bytes = array_size(n, size); >> + >> + if (bytes == SIZE_MAX) >> return NULL; >> if (__builtin_constant_p(n) && __builtin_constant_p(size)) >> - return kmalloc(n * size, flags); >> - return __kmalloc(n * size, flags); >> + return kmalloc(bytes, flags); >> + return __kmalloc(bytes, flags); >> } >> >> /** >> @@ -639,7 +646,9 @@ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) >> */ >> static inline void *kcalloc(size_t n, size_t size, gfp_t flags) >> { >> - return kmalloc_array(n, size, flags | __GFP_ZERO); >> + size_t bytes = array_size(n, size); >> + >> + return kmalloc(bytes, flags | __GFP_ZERO); >> } > > Hmm. I wonder why we have the kmalloc/__kmalloc "optimisation" > in kmalloc_array, but not kcalloc. Bet we don't really need it in > kmalloc_array. I'll do some testing. > Huh? Because kcalloc is implemented in terms of kmalloc_array? And can't we just keep it that way? Rasmus