Received: by 10.192.165.148 with SMTP id m20csp239377imm; Wed, 9 May 2018 11:50:07 -0700 (PDT) X-Google-Smtp-Source: AB8JxZomg0hcVGpU0+2aT+mMpsO7w6cphexzDeMgMv5TE6CL+W3/85m/9w5mX0MaSdtCTMp+M/gM X-Received: by 2002:a63:744c:: with SMTP id e12-v6mr31859273pgn.4.1525891807394; Wed, 09 May 2018 11:50:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525891807; cv=none; d=google.com; s=arc-20160816; b=GEwHb4ulsC42is9cnvHT5CtBg6zfm3f6IyxUIOLTTwf8VzJshIqa+ZnPJTVHqtrkSw tC/IzGQ3XwXwIcyctdawsu6W5rsWLBWgPli/9iGm4cjTshKYUymxF7UkM02udyqVfA46 a6mv5S14b7NsgjaGo76qPp5sL8F/PKVvje3B9ydKENcYfB6wUxvsd9tpbQeX9Txvfyhu h2CRwqkCVxLQXNf9gsEnRjNPv2v9nEh0mvKgZfPPtJlDVHQ8U0aCpBdd5nfWSISYlGjg gbF9AkYfp2W8DYn2KqMRWe3isSnRh7YS0+53Yq7SluKLrGPtqu+qXyIQfBr5dVpA5GvJ tUuA== 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=3o91TLFFcQN8pasVJVNf+QKPShbmn6rReI0DsiCSojg=; b=V4D9ojmHnh2JPqjHOdw9T0qNb6XxP9fM7yiN7Vbicu+Bzv1AyjBkAGKe+u/qr1kP3v VBTvM9KzG8eP8Z28TFn7R0vm47XPv88oBD/o1+mrLPzlO3PwScAA7iGKmkWnhAoiuYQn oqwTLAQ1nsGRn8lJaXu2ZNrqZ8nYPLufrtzegynzzqk5cvq5Ywea12gaUDPT3YywDW36 2m8rB3x9qm9MC7i//+TOnkSyEAH5AqOEW1KtO5yKbrTL1tzTj5uMbPcElJauzDop8ZOP CjsQrzKBNCOzSRwnNfgt4bpdZvpWzi4Eda5B3JFe3v0R87oQwvDRVXKpG18NhkQLKG8c N8IQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=eTHptuT3; dkim=fail header.i=@chromium.org header.s=google header.b=d2FoLXl/; 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 h10-v6si26896672pll.425.2018.05.09.11.49.52; Wed, 09 May 2018 11:50:07 -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=eTHptuT3; dkim=fail header.i=@chromium.org header.s=google header.b=d2FoLXl/; 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 S964947AbeEISth (ORCPT + 99 others); Wed, 9 May 2018 14:49:37 -0400 Received: from mail-ua0-f194.google.com ([209.85.217.194]:33839 "EHLO mail-ua0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935467AbeEIStf (ORCPT ); Wed, 9 May 2018 14:49:35 -0400 Received: by mail-ua0-f194.google.com with SMTP id f22so23655686uam.1 for ; Wed, 09 May 2018 11:49:35 -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=3o91TLFFcQN8pasVJVNf+QKPShbmn6rReI0DsiCSojg=; b=eTHptuT3JzytuXcfuH8oI/3S2gKitSiEODuEMeXH+dB3nAtEy45S1Z38cilehiHiMh JoRD9BXWthfnksfwz1UHKmVe754IpU+p6CVBIQQ1npm8i14/ofUU6Yrj7N5T23q4XJV7 kyH3dYBcp5W3UjjN8UGTZUPdiqYXdVANL/fzheTS8Wj9u2gLiN0BYHNCO70NVi3zwq5B umDFP93+o2Mr/wiozQuE2PYdJLPo/B7hUZTUEuJ+g+yb2hUEszfk4BTJFrdrLq3QBzNV 6pom9Vu142xuKdjczsYTZTRhcD/RqYFYbfpmHEJM8+xRq5pXq1PJD3I4/z/y2xjRKnzW C0JQ== 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=3o91TLFFcQN8pasVJVNf+QKPShbmn6rReI0DsiCSojg=; b=d2FoLXl/DYCCupCZKWA0B6GE6j0sJhk4RSmxBsn/o8idnsMrOxMF7ZXHDUKu6Z65rT jt67QVQi55WLHvqW2xVGAV1jKGdpyY7vcLmSpr44GhCJnu8mbL7mPvhcq1bRrsRqSxQP Zgk8SMIuFwwlYo/WZlnFE/uF2GCaRn91FjGCc= 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=3o91TLFFcQN8pasVJVNf+QKPShbmn6rReI0DsiCSojg=; b=d5LOE+fEALuZU2QnZECoby1my/XcPgQCrdSc86cp7rDdgMy1E3MnQh7CBMhanq+UAe DTiX57tUF1llVRVVSq4CXaBIw+3nT0DBBD5NJHfv1PtdYrBSe3VkvatLlBiPxa6IUqeW 8ZmijDvkoTOdQ1pTZi+Jk+izXJ/N2PJELzVhWTCg0HSV8coxBfH1V+GwavjaM8ODqrGD +yBDKS5PD7TJcs2/WBzMTRM3ZUwZAyRBtXAPTaP7cQ4WeDSuynFjpT/fEw/ydHTgXxkN 68g/iEKR+2Jh+iMnODweJSVn0kH6BQnZW11fwN6w2murtSlSrTCMkpAPHVQPMe/3JHYD Ou1Q== X-Gm-Message-State: ALQs6tD1Ms3ZXAAw74S7W+12mU8nUZtTH0gp7uqopXDztZPYKakLyGnA sbSbg8buZatTeLohiFPf6KIIJ6QP/+QeAC+a59WvUg== X-Received: by 10.176.84.78 with SMTP id o14mr38896557uaa.164.1525891774496; Wed, 09 May 2018 11:49:34 -0700 (PDT) MIME-Version: 1.0 Received: by 10.31.11.209 with HTTP; Wed, 9 May 2018 11:49:33 -0700 (PDT) In-Reply-To: References: <20180509004229.36341-1-keescook@chromium.org> <20180509004229.36341-4-keescook@chromium.org> From: Kees Cook Date: Wed, 9 May 2018 11:49:33 -0700 X-Google-Sender-Auth: 2Q_dtZqgC8JhnTyC66QDL_Tfv0w Message-ID: Subject: Re: [PATCH 03/13] overflow.h: Add allocation size calculation helpers To: Rasmus Villemoes Cc: Matthew Wilcox , LKML , Linux-MM , 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 Wed, May 9, 2018 at 11:27 AM, Rasmus Villemoes wrote: > On 2018-05-09 02:42, Kees Cook wrote: >> In preparation for replacing unchecked overflows for memory allocations, >> this creates helpers for the 3 most common calculations: >> >> array_size(a, b): 2-dimensional array >> array3_size(a, b, c): 2-dimensional array > > yeah... complete confusion... > >> +/** >> + * array_size() - Calculate size of 2-dimensional array. >> + * >> + * @a: dimension one >> + * @b: dimension two >> + * >> + * Calculates size of 2-dimensional array: @a * @b. >> + * >> + * Returns: number of bytes needed to represent the array or SIZE_MAX on >> + * overflow. >> + */ >> +static inline __must_check size_t array_size(size_t a, size_t b) >> +{ >> + size_t bytes; >> + >> + if (check_mul_overflow(a, b, &bytes)) >> + return SIZE_MAX; >> + >> + return bytes; >> +} >> + >> +/** >> + * array3_size() - Calculate size of 3-dimensional array. >> + * > > ...IDGI. array_size is/will most often be used to calculate the size of > a one-dimensional array, count*elemsize, accessed as foo[i]. Won't a > three-factor product usually be dim1*dim2*elemsize, i.e. 2-dimensional, > accessed (because C is lame) as foo[i*dim2 + j]? I was thinking of byte addressing, not object addressing. I can rewrite this to be less confusing. >> +/** >> + * struct_size() - Calculate size of structure with trailing array. >> + * @p: Pointer to the structure. >> + * @member: Name of the array member. >> + * @n: Number of elements in the array. >> + * >> + * Calculates size of memory needed for structure @p followed by an >> + * array of @n @member elements. >> + * >> + * Return: number of bytes needed or SIZE_MAX on overflow. >> + */ >> +#define struct_size(p, member, n) \ >> + __ab_c_size(n, \ >> + sizeof(*(p)->member) + __must_be_array((p)->member),\ >> + offsetof(typeof(*(p)), member)) >> + >> + > > struct s { int a; char b; char c[]; } has sizeof > offsetof(c), so for > small enough n, we end up allocating less than sizeof(struct s). And the > caller might reasonably do memset(s, 0, sizeof(*s)) to initialize all > members before c. In practice our allocators round up to a multiple of > 8, so I don't think it's a big problem, but some sanitizer might > complain. But I do think you should make that addend sizeof() instead of > offsetof(). Erg. Yeah, I think we'd best "round up". Besides the "< sizeof()" vs memset() case you mention, another pattern I've seen is doing stuff like: array = (array_type *)(thing + 1); So if padding somehow caused us to under-allocate, we'll get it wrong there too. I'll change this to be strictly sizeof(*(p)). (Though it might be nice to enforce that "member" is at the end of the structure, though, otherwise this could be misused for struct s { int a; char c[2]; char b[]; } ... ) -Kees -- Kees Cook Pixel Security