Received: by 10.192.165.148 with SMTP id m20csp211581imm; Fri, 4 May 2018 09:05:30 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrQ4H5bAOzHVTeG1GTS5311ncoev6uFUzCMIDEq+Z4V17YKCQ4BKFy0+ztmJujXIM23hhjU X-Received: by 2002:a63:6196:: with SMTP id v144-v6mr23224294pgb.264.1525449930206; Fri, 04 May 2018 09:05:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525449930; cv=none; d=google.com; s=arc-20160816; b=CETKuYoCylsLCoDYs6shDaPI+NpXn+nZRx6EeUKPHoc35SUK/xfCqrRhkHhClxtSh4 OMXlFRA/gP/bzs3iw+B5+n0sbaE3Y757V9EMINnyeMZZaONApMB4xhgjQJOg3jgNAbx1 tETYMbVN+X2gGWTdh4G0bySaBTBvkJ/6UJiwX4JzrlMPFYzGjOSaWXsZZ5TqsZI8rTLJ f0vVe8OXFxlfb/9ECQVi675w7Qrzg7mrZWUlA80IanP0rK0ZeS6a1docZTzVUOKH+jW3 8p+Fei8pUlP0c6ih9NXM/VOp0iFz8bNTKgRRaXA5JpCTWru4ABudrCNwPdTUKGikwVef j+eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature:dkim-signature :arc-authentication-results; bh=OPd5wmZ/M1RtKLsNdMpNP3/3WEXktRrlA+OvvLIUOr0=; b=AjZlop1r/CVi9+7eRTtUSWPE1zZnifiBR71DT7vY+TWfKwsVMfxiIuF2HJzoamTe6Q rVx1XvDCQcTgk1soD2J9u8fyftFzv9SEvZMY7nkQQr+DlKxxmrihJOb44dwExdEmgQCI uO5b3adKb7r3tg9DtL1e4sSBtKSTMdgPCU8d3ZxgdH9NA1X4rQ6mLy4VMvX89oTOgqFZ /rIvVeu6U6aNxuaTLlhPmkFEYpi5sZJ4atSnzI+PCyRS/MM+AMD3EAb9ndWfT7RirFxt Mtyen5g+pimTdN1I2Mrqr407AX6CJ9ODWbNyy6tzQ2V9LcgBuANpFsTANQZaFVPYkxrY ChLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=akTkVl2R; dkim=fail header.i=@chromium.org header.s=google header.b=RCGY5hpn; 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=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m13-v6si1501066pgu.237.2018.05.04.09.05.15; Fri, 04 May 2018 09:05:30 -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=fail header.i=@google.com header.s=20161025 header.b=akTkVl2R; dkim=fail header.i=@chromium.org header.s=google header.b=RCGY5hpn; 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=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751622AbeEDQDv (ORCPT + 99 others); Fri, 4 May 2018 12:03:51 -0400 Received: from mail-vk0-f54.google.com ([209.85.213.54]:42639 "EHLO mail-vk0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751419AbeEDQDt (ORCPT ); Fri, 4 May 2018 12:03:49 -0400 Received: by mail-vk0-f54.google.com with SMTP id j7-v6so13533294vkc.9 for ; Fri, 04 May 2018 09:03:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=OPd5wmZ/M1RtKLsNdMpNP3/3WEXktRrlA+OvvLIUOr0=; b=akTkVl2RKP2sWHbNw/Cajrjl3hZD06l0PG22ljt4nuZgb/XV6s0YUJNOp4lMOqJA/v GQbm9YiJNkesDMFlDBzo7dSwXRfKFMzLd1bTC5ux0mvr7rQLcs5CN8fk6IKcYfmK6uju SuEZBlkpgCElvzFXuNXjwSMGv4W2KdVVasLxWy95PKZSH9kkj1+0FgBIjyVBfNkArFbM 7MV6YFZq6sM7v66/mmBui9QXyDgLB9DuNXoJj58mrCWG8NenqubLLITR6benMhDYzQxU xKpyfeKBFKgfPT29LCDRdopN7cBA/iphIgyuGITjK6nWMAb1BrxeLV/PPt63FXyG/GIH 5tVw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=OPd5wmZ/M1RtKLsNdMpNP3/3WEXktRrlA+OvvLIUOr0=; b=RCGY5hpnfU+UGl41eooM5Vd1gIsNympb2Sa68w6xpO56p6Kt9wz0k9AfJMw476HC1/ vGPwENOo8PIcPPv0UbigPEp7j1kXP39tvVZJ8j0pKodmYwH1J4kkDabc4wVzyAPCPRXC v0diG07rahX2rA6YeeoHPMJFlsvnm2+Q85z+s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=OPd5wmZ/M1RtKLsNdMpNP3/3WEXktRrlA+OvvLIUOr0=; b=RhBeHKYlI0AMaL54nShtpJxUFq0RtDpmyZrSZBDFKre1+/iZz+kG6iual/0KO/j2s8 +jZDFuA/rSU2vhHHwTjrZpYnN8dgwyJf162XzWPDyywUgTLjFAgDydYNmTcaQZcf39fg O8CcqUc5lyeNxfa0o+SrE8TIHlJ3JWZ+Lf7EfVLqzaNVJ6GQfsHwzlto9tqCqZEpJkoQ 21U9Y0Byw3VSCQRinayPdmCCtEdUCAPQpLGghvQsc0ra9m81LKTTcZUVXmI2htgXl2fx HCcADDd8ul6nY6/9NGSRwnGfbDmvdbzOqvMdNbSFXmyo1jNQL8hvwwkykLJbPUL2kdsD TpVA== X-Gm-Message-State: ALQs6tDcvGnHvBpv2OutyY3LGjh7VM/JgJR0B7mFnyMzorKkkicfk0XO S1nxC+nF/BFJjmM71pchS9vUq+YnExnwi9KYokxyug== X-Received: by 2002:a1f:824a:: with SMTP id e71-v6mr23988239vkd.7.1525449828028; Fri, 04 May 2018 09:03:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.31.11.209 with HTTP; Fri, 4 May 2018 09:03:46 -0700 (PDT) In-Reply-To: References: <20180214182618.14627-1-willy@infradead.org> <20180214182618.14627-3-willy@infradead.org> <20180504131441.GA24691@bombadil.infradead.org> From: Kees Cook Date: Fri, 4 May 2018 09:03:46 -0700 X-Google-Sender-Auth: xWZpey8uP6ICyCD3t5d8nDKFcto Message-ID: Subject: Re: [PATCH 2/2] mm: Add kvmalloc_ab_c and kvzalloc_struct To: Linus Torvalds Cc: Matthew Wilcox , Andrew Morton , Matthew Wilcox , linux-mm , Linux Kernel Mailing List , Kernel Hardening Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 4, 2018 at 8:35 AM, Linus Torvalds wrote: > On Fri, May 4, 2018 at 3:14 AM Matthew Wilcox wrote: > >> > In fact, the conversion I saw was buggy. You can *not* convert a > GFP_ATOMIC >> > user of kmalloc() to use kvmalloc. > >> Not sure which conversion you're referring to; not one of mine, I hope? > > I was thinking of the coccinelle patch in this thread, but just realized > that that actually only did it for GFP_KERNEL, so I guess it would work, > apart from the "oops, now it doesn't enforce the kmalloc limits any more" > issue. Just to be clear: the Coccinelle scripts I'm building aren't doing a kmalloc -> kvmalloc conversion. I'm just removing all the 2-factor multiplication and replacing it with the appropriate calls to the allocator family's *calloc or *alloc_array(). This will get us to the place where we can do all the sanity-checking in the allocator functions (whatever that checking ends up being). As it turns out, though, we have kind of a lot of allocator families. Some are wrappers, like devm_*alloc(), etc. All that said, the overwhelming majority of *alloc() multiplications are just "count * sizeof()". It really feels like everything should just be using a new *alloc_struct() which can do the type checking, etc, etc, but we can get there. The remaining "count * size" are a minority and could be dealt with some other way. >> > - that divide is really really expensive on many architectures. > >> 'c' and 'size' are _supposed_ to be constant and get evaluated at >> compile-time. ie you should get something like this on x86: > > I guess that willalways be true of the 'kvzalloc_struct() version that > will always use a sizeof(). I was more thinking of any bare kvalloc_ab_c() > cases, but maybe we'd discourage that to ever be used as such? Yeah, bare *alloc_ab_c() is not great. Perhaps a leading "__" can hint to that? > Because we definitely have things like that, ie a quick grep finds > > f = kmalloc (sizeof (*f) + size*num, GFP_KERNEL); > > where 'size' is not obviously a constant. There may be others, but I didn't > really try to grep any further. > > Maybe they aren't common, and maybe the occasional divide doesn't matter, > but particularly if we use scripting to then catch and convert users, I > really hate the idea of "let's introduce something that is potentially much > more expensive than it needs to be". Yup: I'm not after that either. I just want to be able to get at the multiplication factors before they're multiplied. :) > (And the automated coccinelle scripting it's also something where we must > very much avoid then subtly lifting allocation size limits) Agreed. I think most cases are already getting lifted to size_t due to the sizeof(). It's the "two variables" cases I want to double-check. Another completely insane idea would be to have a macro that did type size checking and would DTRT, but with all the alloc families, it looks nasty. This is all RFC stage, as far as I'm concerned. Fun example: devm_kzalloc(dev, sizeof(...) * num, gfp...) $ git grep 'devm_kzalloc([^,]*, *sizeof([^,]*,' | egrep '\* *sizeof|\) *\*' | wc -l 88 some are constants: drivers/video/fbdev/au1100fb.c: devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL); but many aren't: sound/soc/generic/audio-graph-card.c: dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); While type-checking on the non-sizeof factor would let us know if it was safe, so would the division, and most of those could happen at compile time. It's the size_t variables that we want to catch. So, mainly I'm just trying to get the arguments reordered (for a compile-time division) into the correct helpers so the existing logic can do the right thing, and only for 2-factor products. After that, then I'm hoping to tackle the multi-factor products, of which the *alloc_struct() helper seems to cover the vast majority of the remaining cases. -Kees -- Kees Cook Pixel Security