From patchwork Mon Jan 20 07:43:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 11341187 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2542114B7 for ; Mon, 20 Jan 2020 07:43:56 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id DA14F2073D for ; Mon, 20 Jan 2020 07:43:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=axtens.net header.i=@axtens.net header.b="QrJVXlru" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DA14F2073D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axtens.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 224DC6B05BC; Mon, 20 Jan 2020 02:43:55 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 186B76B05BD; Mon, 20 Jan 2020 02:43:55 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0750A6B05BE; Mon, 20 Jan 2020 02:43:55 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0023.hostedemail.com [216.40.44.23]) by kanga.kvack.org (Postfix) with ESMTP id DFC1E6B05BC for ; Mon, 20 Jan 2020 02:43:54 -0500 (EST) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 9CE692C1E for ; Mon, 20 Jan 2020 07:43:54 +0000 (UTC) X-FDA: 76397223588.17.table00_22131e61dc109 X-Spam-Summary: 2,0,0,6e032832debafaeb,d41d8cd98f00b204,dja@axtens.net,:kernel-hardening@lists.openwall.com::keescook@chromium.org:linux-kernel@vger.kernel.org:akpm@linux-foundation.org:dja@axtens.net:liplianin@netup.ru,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1359:1437:1515:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:1801:2393:2559:2562:3138:3139:3140:3141:3142:3354:3865:3866:3867:3868:3870:3871:3874:4117:4250:4321:4605:5007:6119:6261:6653:7903:8603:8660:9207:10004:10400:11026:11658:11914:12043:12296:12297:12517:12519:12555:12895:12986:13148:13161:13229:13230:13894:14181:14394:14659:14721:21080:21444:21451:21627:21990:30012:30046:30054:30079,0,RBL:209.85.216.66:@axtens.net:.lbl8.mailshell.net-62.2.0.100 66.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: table00_22131e61dc109 X-Filterd-Recvd-Size: 6005 Received: from mail-pj1-f66.google.com (mail-pj1-f66.google.com [209.85.216.66]) by imf46.hostedemail.com (Postfix) with ESMTP for ; Mon, 20 Jan 2020 07:43:54 +0000 (UTC) Received: by mail-pj1-f66.google.com with SMTP id m13so6770579pjb.2 for ; Sun, 19 Jan 2020 23:43:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vGzxV+LL88B+fATt6abbCjZqtOsySmjlch7DJWcKIik=; b=QrJVXlruig0d5ecXvvbWcbKMcaX9f7bSq3DARYQAlfFXIYLoHZhe0LbKsZiw+/Pkhb Kqwn/mlr4ATbaCYDIVX2mYktnHVp6zNt5h0WTR1eNoomrO8vtOC5bN9V61quVFzBdmns X1eaQxmScrIri3kpRg8MH1wtaFeo3eYnH+fA0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vGzxV+LL88B+fATt6abbCjZqtOsySmjlch7DJWcKIik=; b=kWG/SC6wRO6cGBf6asebX4PjbWKKa9zt3xDp9rYZde1Lm35aQG7hS42jZpgFKYrr4O USEiFJ+EhKFAeAH7uHwwLuf3PWwICS7pzVaR98c9Uv1p3YA+2myQrcAYuTvD/XYTzp0Z AIxUKNn6Tg8a1EWj7FvJ7txwxFjq+gGlEit0rAeBkjK+ESC8hF4cQU/yiBOgmv/9gNCH njwbHql2wbSuZJc75nZdph0FTSbQXpj93PvS/0oAGWABEKoFt0jAWtiCnzXE1kIoy02A EmtDRxOvgebjauN+FjkHGpF+Rw4z+tlQm3nkO27gqHam6XFiGRhxftX0E5yJHBj25S1N OWcg== X-Gm-Message-State: APjAAAVz/FANkuDrkiRG7HnPxb0NTcpo9gmJbxXXENBMHs/fYK0JCsIM N7R8jXPU5oKJ0bGrGyYjbANJYw== X-Google-Smtp-Source: APXvYqxRl1/EQDPVjdeMlWwspz86l1VCWkYGZLCYqdRqVMW2QddfAJWpVwh0yCdA65+wQtpZK0Lc5g== X-Received: by 2002:a17:90a:c385:: with SMTP id h5mr21966359pjt.122.1579506233119; Sun, 19 Jan 2020 23:43:53 -0800 (PST) Received: from localhost (2001-44b8-1113-6700-4064-d910-a710-f29a.static.ipv6.internode.on.net. [2001:44b8:1113:6700:4064:d910:a710:f29a]) by smtp.gmail.com with ESMTPSA id a23sm39832941pfg.82.2020.01.19.23.43.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 23:43:52 -0800 (PST) From: Daniel Axtens To: kernel-hardening@lists.openwall.com, linux-mm@kvack.org, keescook@chromium.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Daniel Axtens , "Igor M. Liplianin" Subject: [PATCH 1/5] altera-stapl: altera_get_note: prevent write beyond end of 'key' Date: Mon, 20 Jan 2020 18:43:40 +1100 Message-Id: <20200120074344.504-2-dja@axtens.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200120074344.504-1-dja@axtens.net> References: <20200120074344.504-1-dja@axtens.net> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: altera_get_note is called from altera_init, where key is kzalloc(33). When the allocation functions are annotated to allow the compiler to see the sizes of objects, and with FORTIFY_SOURCE, we see: In file included from drivers/misc/altera-stapl/altera.c:14:0: In function ‘strlcpy’, inlined from ‘altera_init’ at drivers/misc/altera-stapl/altera.c:2189:5: include/linux/string.h:378:4: error: call to ‘__write_overflow’ declared with attribute error: detected write beyond size of object passed as 1st parameter __write_overflow(); ^~~~~~~~~~~~~~~~~~ That refers to this code in altera_get_note: if (key != NULL) strlcpy(key, &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i)])], length); The error triggers because the length of 'key' is 33, but the copy uses length supplied as the 'length' parameter, which is always 256. Split the size parameter into key_len and val_len, and use the appropriate length depending on what is being copied. Detected by compiler error, only compile-tested. Cc: "Igor M. Liplianin" Signed-off-by: Daniel Axtens --- drivers/misc/altera-stapl/altera.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index 25e5f24b3fec..5bdf57472314 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -2112,8 +2112,8 @@ static int altera_execute(struct altera_state *astate, return status; } -static int altera_get_note(u8 *p, s32 program_size, - s32 *offset, char *key, char *value, int length) +static int altera_get_note(u8 *p, s32 program_size, s32 *offset, + char *key, char *value, int keylen, int vallen) /* * Gets key and value of NOTE fields in the JBC file. * Can be called in two modes: if offset pointer is NULL, @@ -2170,7 +2170,7 @@ static int altera_get_note(u8 *p, s32 program_size, &p[note_table + (8 * i) + 4])]; if (value != NULL) - strlcpy(value, value_ptr, length); + strlcpy(value, value_ptr, vallen); } } @@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size, strlcpy(key, &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i)])], - length); + keylen); if (value != NULL) strlcpy(value, &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i) + 4])], - length); + vallen); *offset = i + 1; } @@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) __func__, (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); while (altera_get_note((u8 *)fw->data, fw->size, - &offset, key, value, 256) == 0) + &offset, key, value, 32, 256) == 0) printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n", __func__, key, value); } From patchwork Mon Jan 20 07:43:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 11341189 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3974C14B7 for ; Mon, 20 Jan 2020 07:44:00 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id ED4482073D for ; Mon, 20 Jan 2020 07:43:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=axtens.net header.i=@axtens.net header.b="dqvOmH1r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED4482073D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axtens.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 2711D6B05BE; Mon, 20 Jan 2020 02:43:59 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1FAE76B05BF; Mon, 20 Jan 2020 02:43:59 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0C3CA6B05C0; Mon, 20 Jan 2020 02:43:59 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0114.hostedemail.com [216.40.44.114]) by kanga.kvack.org (Postfix) with ESMTP id E375F6B05BE for ; Mon, 20 Jan 2020 02:43:58 -0500 (EST) Received: from smtpin04.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 9B60240C3 for ; Mon, 20 Jan 2020 07:43:58 +0000 (UTC) X-FDA: 76397223756.04.brush72_22a7148886353 X-Spam-Summary: 2,0,0,50bc93ac83fec1e2,d41d8cd98f00b204,dja@axtens.net,:kernel-hardening@lists.openwall.com::keescook@chromium.org:linux-kernel@vger.kernel.org:akpm@linux-foundation.org:dja@axtens.net,RULES_HIT:2:41:69:355:379:541:800:960:966:973:988:989:1260:1311:1314:1345:1359:1431:1437:1515:1535:1605:1730:1747:1777:1792:2196:2199:2393:2559:2562:2693:2901:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3874:4049:4120:4321:4385:5007:6119:6261:6653:7903:8603:10004:11026:11473:11658:11914:12043:12291:12297:12438:12517:12519:12555:12683:12895:13161:13229:13894:14394:21063:21080:21324:21444:21451:21627:21796:21990:30030:30036:30054:30056:30070,0,RBL:209.85.214.193:@axtens.net:.lbl8.mailshell.net-62.2.0.100 66.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:29,LUA_SUMMARY:none X-HE-Tag: brush72_22a7148886353 X-Filterd-Recvd-Size: 9081 Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) by imf19.hostedemail.com (Postfix) with ESMTP for ; Mon, 20 Jan 2020 07:43:58 +0000 (UTC) Received: by mail-pl1-f193.google.com with SMTP id s21so12815389plr.7 for ; Sun, 19 Jan 2020 23:43:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fVOHfWbnRfkMY9jVKGHgxhKH0IzU9LE8hgU/UaJj8Ts=; b=dqvOmH1r2nvUztCLA58ZwbEuJf7BOGi+nZoxmmYCNHHyGcka7PTp2lV5p6ZS1/syCe KGS/EcJNbw/j4Z4sxeSfhlGblfD0W0Kl34q6Wz3cxhLYeasgrOxerzhI9prk2Jp7fNE/ 6lhEH19aqm26US6aZi+UqHy4F0TaJV+BsT8DI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fVOHfWbnRfkMY9jVKGHgxhKH0IzU9LE8hgU/UaJj8Ts=; b=YaZ+yzlEMGDYQgEVgzkiVbPnPLbOr8Nl9izhGk0G7IlZuBs4smhY48Z5mJH1xIh7AN 65WhTnr9olL1JsmNFDoewhOLL1rEV+t2cSnbW/YVXhBqROj7bfhGdqGyWlS+qZ+0ccj4 hcvk5vy0XM5scYwsUZCMwAsyL3z6hRSeHdhSzTPJcMmdFx5P/rMdKf3cxSWiQMZT3gI6 vBZO4MNSNKvVUwvCwQNA3md3VhVftvmKfWELjo6kw8tnjkXkb/tbYXXETokiTLh+04ZC hkb9FiCg1M8ZJJtTPhMI3uG3+UIPTnAv5qEbryRPhfD1gUIIxbQgvrShYZ3xaapw6iG9 5TSg== X-Gm-Message-State: APjAAAWEKnCAFijDd/DdZoM08PRDGjz2+WAQcxB1m2Io9Mcn4amjFbjz 5M/XoIH89r/6QloEhvwlkpqYEA== X-Google-Smtp-Source: APXvYqyZLyymGztJ/CNSEFtCTqcFFyQ8FVKljy9JVWAOg7npJe8SkBB6mSUg0KCA7RntzezXIRgmJg== X-Received: by 2002:a17:902:8303:: with SMTP id bd3mr13940869plb.171.1579506237050; Sun, 19 Jan 2020 23:43:57 -0800 (PST) Received: from localhost (2001-44b8-1113-6700-4064-d910-a710-f29a.static.ipv6.internode.on.net. [2001:44b8:1113:6700:4064:d910:a710:f29a]) by smtp.gmail.com with ESMTPSA id b126sm5161111pga.19.2020.01.19.23.43.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 23:43:56 -0800 (PST) From: Daniel Axtens To: kernel-hardening@lists.openwall.com, linux-mm@kvack.org, keescook@chromium.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Daniel Axtens Subject: [PATCH 2/5] [RFC] kasan: kasan_test: hide allocation sizes from the compiler Date: Mon, 20 Jan 2020 18:43:41 +1100 Message-Id: <20200120074344.504-3-dja@axtens.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200120074344.504-1-dja@axtens.net> References: <20200120074344.504-1-dja@axtens.net> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: We're about to annotate the allocation functions so that the complier will know the sizes of the allocated objects. This is then caught at compile time by both the testing in copy_to/from_user, and the testing in fortify. The simplest way I can find to obscure the size is to pass the memory through a WRITE_ONCE/READ_ONCE pair. Create a macro to obscure an object's size, and a kmalloc wrapper to return an object with an obscured size. Using these is sufficient to compile without error. Signed-off-by: Daniel Axtens --- lib/test_kasan.c | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/test_kasan.c b/lib/test_kasan.c index 328d33beae36..dbbecd75f1e3 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -20,9 +20,28 @@ #include #include #include +#include #include +/* + * obscure origin of a pointer, so we can test things that check + * the size of the underlying object + */ +#define OBSCURE_ORIGINAL_OBJECT(x) { \ + void *bounce; \ + WRITE_ONCE(bounce, x); \ + x = READ_ONCE(bounce); \ + } + +static inline void *obscured_kmalloc(size_t size, gfp_t flags) +{ + void *result, *bounce; + result = kmalloc(size, flags); + WRITE_ONCE(bounce, result); + return READ_ONCE(bounce); +} + /* * Note: test functions are marked noinline so that their names appear in * reports. @@ -34,7 +53,7 @@ static noinline void __init kmalloc_oob_right(void) size_t size = 123; pr_info("out-of-bounds to right\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -50,7 +69,7 @@ static noinline void __init kmalloc_oob_left(void) size_t size = 15; pr_info("out-of-bounds to left\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -67,6 +86,7 @@ static noinline void __init kmalloc_node_oob_right(void) pr_info("kmalloc_node(): out-of-bounds to right\n"); ptr = kmalloc_node(size, GFP_KERNEL, 0); + OBSCURE_ORIGINAL_OBJECT(ptr); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -86,7 +106,7 @@ static noinline void __init kmalloc_pagealloc_oob_right(void) * the page allocator fallback. */ pr_info("kmalloc pagealloc allocation: out-of-bounds to right\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -136,7 +156,7 @@ static noinline void __init kmalloc_large_oob_right(void) * and does not trigger the page allocator fallback in SLUB. */ pr_info("kmalloc large allocation: out-of-bounds to right\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -155,6 +175,7 @@ static noinline void __init kmalloc_oob_krealloc_more(void) pr_info("out-of-bounds after krealloc more\n"); ptr1 = kmalloc(size1, GFP_KERNEL); ptr2 = krealloc(ptr1, size2, GFP_KERNEL); + OBSCURE_ORIGINAL_OBJECT(ptr2); if (!ptr1 || !ptr2) { pr_err("Allocation failed\n"); kfree(ptr1); @@ -174,6 +195,7 @@ static noinline void __init kmalloc_oob_krealloc_less(void) pr_info("out-of-bounds after krealloc less\n"); ptr1 = kmalloc(size1, GFP_KERNEL); ptr2 = krealloc(ptr1, size2, GFP_KERNEL); + OBSCURE_ORIGINAL_OBJECT(ptr2); if (!ptr1 || !ptr2) { pr_err("Allocation failed\n"); kfree(ptr1); @@ -190,7 +212,7 @@ static noinline void __init kmalloc_oob_16(void) } *ptr1, *ptr2; pr_info("kmalloc out-of-bounds for 16-bytes access\n"); - ptr1 = kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL); + ptr1 = obscured_kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL); ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); if (!ptr1 || !ptr2) { pr_err("Allocation failed\n"); @@ -209,7 +231,7 @@ static noinline void __init kmalloc_oob_memset_2(void) size_t size = 8; pr_info("out-of-bounds in memset2\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -225,7 +247,7 @@ static noinline void __init kmalloc_oob_memset_4(void) size_t size = 8; pr_info("out-of-bounds in memset4\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -242,7 +264,7 @@ static noinline void __init kmalloc_oob_memset_8(void) size_t size = 8; pr_info("out-of-bounds in memset8\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -258,7 +280,7 @@ static noinline void __init kmalloc_oob_memset_16(void) size_t size = 16; pr_info("out-of-bounds in memset16\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -274,7 +296,7 @@ static noinline void __init kmalloc_oob_in_memset(void) size_t size = 666; pr_info("out-of-bounds in memset\n"); - ptr = kmalloc(size, GFP_KERNEL); + ptr = obscured_kmalloc(size, GFP_KERNEL); if (!ptr) { pr_err("Allocation failed\n"); return; @@ -479,7 +501,7 @@ static noinline void __init copy_user_test(void) size_t size = 10; int unused; - kmem = kmalloc(size, GFP_KERNEL); + kmem = obscured_kmalloc(size, GFP_KERNEL); if (!kmem) return; @@ -599,7 +621,7 @@ static noinline void __init kasan_memchr(void) size_t size = 24; pr_info("out-of-bounds in memchr\n"); - ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); + ptr = obscured_kmalloc(size, GFP_KERNEL | __GFP_ZERO); if (!ptr) return; @@ -614,7 +636,7 @@ static noinline void __init kasan_memcmp(void) int arr[9]; pr_info("out-of-bounds in memcmp\n"); - ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); + ptr = obscured_kmalloc(size, GFP_KERNEL | __GFP_ZERO); if (!ptr) return; From patchwork Mon Jan 20 07:43:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 11341191 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2166D921 for ; Mon, 20 Jan 2020 07:44:04 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id D97032073D for ; Mon, 20 Jan 2020 07:44:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=axtens.net header.i=@axtens.net header.b="VuL5LjlK" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D97032073D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axtens.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 0EBA96B05C0; Mon, 20 Jan 2020 02:44:03 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 0752E6B05C1; Mon, 20 Jan 2020 02:44:03 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EA54B6B05C2; Mon, 20 Jan 2020 02:44:02 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0084.hostedemail.com [216.40.44.84]) by kanga.kvack.org (Postfix) with ESMTP id CD1B36B05C0 for ; Mon, 20 Jan 2020 02:44:02 -0500 (EST) Received: from smtpin16.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 8863A2C33 for ; Mon, 20 Jan 2020 07:44:02 +0000 (UTC) X-FDA: 76397223924.16.rest95_233ab0f8c6210 X-Spam-Summary: 2,0,0,082632d6cc3f2a0d,d41d8cd98f00b204,dja@axtens.net,:kernel-hardening@lists.openwall.com::keescook@chromium.org:linux-kernel@vger.kernel.org:akpm@linux-foundation.org:dja@axtens.net,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1359:1437:1515:1516:1518:1535:1542:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:2693:3138:3139:3140:3141:3142:3354:3865:3867:3868:3870:3871:3872:3874:4321:4605:5007:6119:6261:6653:6691:7903:8603:10004:10400:11026:11658:11914:12043:12296:12297:12438:12517:12519:12555:12683:12895:12986:13153:13161:13208:13228:13229:13894:13972:14096:14097:14181:14394:14659:14721:21067:21080:21444:21451:21627:21990:30034:30054:30070,0,RBL:209.85.210.193:@axtens.net:.lbl8.mailshell.net-62.2.0.100 66.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: rest95_233ab0f8c6210 X-Filterd-Recvd-Size: 5439 Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by imf18.hostedemail.com (Postfix) with ESMTP for ; Mon, 20 Jan 2020 07:44:01 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id 2so15415326pfg.12 for ; Sun, 19 Jan 2020 23:44:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cgbwx4pPrUton+YWvUC8+XEHkB4TEyRZFBvrMu0o0Xs=; b=VuL5LjlKzy5In5eNW/F5iZwG9YFS55bxJ5qNflJfa7xgPiL5jeyn4MVx6HIXtqakdc mlWSi8vEjgA+5iEwRXltmyveZnSvqffSizU8pgqORRZe+7ND4OEjm3+oEkOTSUgm/shH tDykiKnwoifmqkjgslih0ocm9GPAeGNHcGHQE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cgbwx4pPrUton+YWvUC8+XEHkB4TEyRZFBvrMu0o0Xs=; b=MrNBg+nru7G/Md6w2f8L0Q7fmcylcIz/j0nTWXjcxyhrwLvVWT19JI30ti/HQKSza1 hTgrhL77kkDRMpkoeOItT/I3XcjlpKRmaNhzzSvi561vAm5hZOzjd0vZJ3YmUQhEP1Le KN1e/Xw4LPxa+Qr68tjAtfEfnAVTbsfdiSXXGTayyfPzROLB7hkyPPWcePPOobq5BRSH /vVHVy+b1bwMC3cfwIUGq57MU4aWT1Fsf0VYAAWiS8y1rTrMptx2Q9/8MBlWMVOC6Zmx aebmt00EbwqaIEMkQSiE+WvmIS1liKhgd6OG6SNgtW5MKon9JBTdWIiKsSZqrC3h4imY XGMw== X-Gm-Message-State: APjAAAXdlwIaxoZLeWO396YJTNcl0E1y2lECi82hW37E1dDMpWkVCX4t vW2j7gx+HvtZmHpvRIa6oBg/Og== X-Google-Smtp-Source: APXvYqyZlAaoK52ybK4EBOzspAzOfrFduSZoB1YaLPW36ZGZBdpEQmZVkbWxdL3Re8WEtuUuz3FE4Q== X-Received: by 2002:aa7:9ec9:: with SMTP id r9mr15945385pfq.85.1579506240797; Sun, 19 Jan 2020 23:44:00 -0800 (PST) Received: from localhost (2001-44b8-1113-6700-4064-d910-a710-f29a.static.ipv6.internode.on.net. [2001:44b8:1113:6700:4064:d910:a710:f29a]) by smtp.gmail.com with ESMTPSA id w5sm35841490pgb.78.2020.01.19.23.43.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 23:44:00 -0800 (PST) From: Daniel Axtens To: kernel-hardening@lists.openwall.com, linux-mm@kvack.org, keescook@chromium.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Daniel Axtens Subject: [PATCH 3/5] [RFC] staging: rts5208: make len a u16 in rtsx_write_cfg_seq Date: Mon, 20 Jan 2020 18:43:42 +1100 Message-Id: <20200120074344.504-4-dja@axtens.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200120074344.504-1-dja@axtens.net> References: <20200120074344.504-1-dja@axtens.net> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: A warning occurs when vzalloc is annotated in a subsequent patch to tell the compiler that its parameter is an allocation size: drivers/staging/rts5208/rtsx_chip.c: In function ‘rtsx_write_cfg_seq’: drivers/staging/rts5208/rtsx_chip.c:1453:7: warning: argument 1 value ‘18446744073709551615’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=] data = vzalloc(array_size(dw_len, 4)); ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This occurs because len and dw_len are signed integers and the parameter to array_size is a size_t. If dw_len is a negative integer, it will become a very large positive number when cast to size_t. This could cause an overflow, so array_size(), will return SIZE_MAX _at compile time_. gcc then notices that this value is too large for an allocation and throws a warning. rtsx_write_cfg_seq is only called from write_cfg_byte in rtsx_scsi.c. There, len is a u16. So make len a u16 in rtsx_write_cfg_seq too. This means dw_len can never be negative, avoiding the potential overflow and the warning. This should not cause a functional change, but was compile tested only. Signed-off-by: Daniel Axtens --- drivers/staging/rts5208/rtsx_chip.c | 2 +- drivers/staging/rts5208/rtsx_chip.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 17c4131f5f62..4a8cbf7362f7 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -1432,7 +1432,7 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) } int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) + u16 len) { u32 *data, *mask; u16 offset = addr % 4; diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h index bac65784d4a1..9b0024557b7e 100644 --- a/drivers/staging/rts5208/rtsx_chip.h +++ b/drivers/staging/rts5208/rtsx_chip.h @@ -963,7 +963,7 @@ int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val); int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); int rtsx_write_cfg_seq(struct rtsx_chip *chip, - u8 func, u16 addr, u8 *buf, int len); + u8 func, u16 addr, u8 *buf, u16 len); int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len); int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); From patchwork Mon Jan 20 07:43:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 11341195 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0658314B7 for ; Mon, 20 Jan 2020 07:44:08 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id B074B2073D for ; Mon, 20 Jan 2020 07:44:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=axtens.net header.i=@axtens.net header.b="IsVuaMki" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B074B2073D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axtens.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id C5D196B05C2; Mon, 20 Jan 2020 02:44:06 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id BE6B56B05C3; Mon, 20 Jan 2020 02:44:06 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AAE586B05C4; Mon, 20 Jan 2020 02:44:06 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0019.hostedemail.com [216.40.44.19]) by kanga.kvack.org (Postfix) with ESMTP id 8DF786B05C2 for ; Mon, 20 Jan 2020 02:44:06 -0500 (EST) Received: from smtpin16.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id 3C8BB181AC9C6 for ; Mon, 20 Jan 2020 07:44:06 +0000 (UTC) X-FDA: 76397224092.16.bean75_23c3378fca41b X-Spam-Summary: 2,0,0,b9c814fd8a1f1e97,d41d8cd98f00b204,dja@axtens.net,:kernel-hardening@lists.openwall.com::keescook@chromium.org:linux-kernel@vger.kernel.org:akpm@linux-foundation.org:dja@axtens.net,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1359:1437:1515:1516:1518:1535:1543:1593:1594:1605:1711:1730:1747:1777:1792:2194:2198:2199:2200:2393:2553:2559:2562:2689:2693:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3874:4117:4250:4321:5007:6119:6261:6653:7875:7903:8603:8660:8784:9108:10004:10400:11026:11473:11658:11914:12043:12296:12297:12438:12517:12519:12555:12895:12986:13148:13160:13229:13230:13894:14096:14097:14181:14394:14659:14721:21080:21444:21451:21627:21972:21990:30034:30054:30070:30090:30091,0,RBL:209.85.210.196:@axtens.net:.lbl8.mailshell.net-62.2.0.100 66.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: bean75_23c3378fca41b X-Filterd-Recvd-Size: 6445 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by imf26.hostedemail.com (Postfix) with ESMTP for ; Mon, 20 Jan 2020 07:44:05 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id z16so15433827pfk.0 for ; Sun, 19 Jan 2020 23:44:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4ceV5dzkz6HqCMW6fBoym4ypC/m9xh1QjTBMfyGPn8o=; b=IsVuaMkiPafyhTmbUmmKKq2zQ2knSaijf8xt11NZ6XL9Q4Hm1Cfdm8CztrO01x5ltK VnhPQHcNW2slNw6gRk8rL5iIUAbKO40Kuwiaqw1t/4WmuKa+tf45OOD70HBQ71fF1tLO +5Vv23deCqiMdkkxkLo3lvuCj1D8aE7yy6hs4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4ceV5dzkz6HqCMW6fBoym4ypC/m9xh1QjTBMfyGPn8o=; b=LlKkEk7H82GWfe9c8kkRmzniaqj6ygJzStEj/EB8td2PJ1CDYv+AeYEUCm0+m7oxcL cfvP1G2cf/pdKn5kXPyJ2Bk8y/yCZ/HYkOqZ4TBd/sCq/CfaKgrNgYMBf5ZWCZoRNUGB CqGi1CXH9m3rjJWW0KbpSpiSZ8yelGCNnwe/oZEd6erIyLmn+Jo2V28ISKthNXwTcOds uB326RU8Bss8v3Ood0ntw9DZiGomL9Ml/gnRI26HSb7Tj5OJ+SetiT5EULT+wOxwBB3J V9NMKcWCVljfUTYpoGS4btgLj2TT/kF29tdvpPeKYj42FYQ1Ld1zuI694H+ydHGPojtM nRVQ== X-Gm-Message-State: APjAAAW+mG8/xNZb90tEtKun3RrDoKTbrJIZ7f//1bkUE2rB2HMPwqzs 69BypaqJaPHyFOp3hj/eIk/Uwg== X-Google-Smtp-Source: APXvYqxpn7k/Ufr5n0ApK06TsYbJxU+ior64MbZ5pNsKbxSZFpNAZBslVxeMWsQFy8/9nF92ZyhObQ== X-Received: by 2002:a63:cc4a:: with SMTP id q10mr58040093pgi.241.1579506244663; Sun, 19 Jan 2020 23:44:04 -0800 (PST) Received: from localhost (2001-44b8-1113-6700-4064-d910-a710-f29a.static.ipv6.internode.on.net. [2001:44b8:1113:6700:4064:d910:a710:f29a]) by smtp.gmail.com with ESMTPSA id y62sm40131883pfg.45.2020.01.19.23.44.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 23:44:04 -0800 (PST) From: Daniel Axtens To: kernel-hardening@lists.openwall.com, linux-mm@kvack.org, keescook@chromium.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Daniel Axtens Subject: [PATCH 4/5] [VERY RFC] mm: kmalloc(_node): return NULL immediately for SIZE_MAX Date: Mon, 20 Jan 2020 18:43:43 +1100 Message-Id: <20200120074344.504-5-dja@axtens.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200120074344.504-1-dja@axtens.net> References: <20200120074344.504-1-dja@axtens.net> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: kmalloc is sometimes compiled with an size that at compile time may be equal to SIZE_MAX. For example, struct_size(struct, array member, array elements) returns the size of a structure that has an array as the last element, containing a given number of elements, or SIZE_MAX on overflow. However, struct_size operates in (arguably) unintuitive ways at compile time. Consider the following snippet: struct foo { int a; int b[0]; }; struct foo *alloc_foo(int elems) { struct foo *result; size_t size = struct_size(result, b, elems); if (__builtin_constant_p(size)) { BUILD_BUG_ON(size == SIZE_MAX); } result = kmalloc(size, GFP_KERNEL); return result; } I expected that size would only be constant if alloc_foo() was called within that translation unit with a constant number of elements, and the compiler had decided to inline it. I'd therefore expect that 'size' is only SIZE_MAX if the constant provided was a huge number. However, instead, this function hits the BUILD_BUG_ON, even if never called. include/linux/compiler.h:394:38: error: call to ‘__compiletime_assert_32’ declared with attribute error: BUILD_BUG_ON failed: size == SIZE_MAX This is with gcc 9.2.1, and I've also observed it with an gcc 8 series compiler. My best explanation of this is: - elems is a signed int, so a small negative number will become a very large unsigned number when cast to a size_t, leading to overflow. - Then, the only way in which size can be a constant is if we hit the overflow case, in which 'size' will be 'SIZE_MAX'. - So the compiler takes that value into the body of the if statement and blows up. But I could be totally wrong. Anyway, this is relevant to slab.h because kmalloc() and kmalloc_node() check if the supplied size is a constant and take a faster path if so. A number of callers of those functions use struct_size to determine the size of a memory allocation. Therefore, at compile time, those functions will go down the constant path, specialising for the overflow case. When my next patch is applied, gcc will then throw a warning any time kmalloc_large could be called with a SIZE_MAX size, as gcc deems SIZE_MAX to be too big an allocation. So, make functions that check __builtin_constant_p check also against SIZE_MAX in the constant path, and immediately return NULL if we hit it. This brings kmalloc() and kmalloc_node() into line with the array functions kmalloc_array() and kmalloc_array_node() for the overflow case. The overall compiled size change per bloat-o-meter is in the noise (a reduction of <0.01%). Signed-off-by: Daniel Axtens --- include/linux/slab.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/slab.h b/include/linux/slab.h index 03a389358562..8141c6b1882a 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -544,6 +544,9 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) #ifndef CONFIG_SLOB unsigned int index; #endif + if (unlikely(size == SIZE_MAX)) + return NULL; + if (size > KMALLOC_MAX_CACHE_SIZE) return kmalloc_large(size, flags); #ifndef CONFIG_SLOB @@ -562,6 +565,9 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { + if (__builtin_constant_p(size) && size == SIZE_MAX) + return NULL; + #ifndef CONFIG_SLOB if (__builtin_constant_p(size) && size <= KMALLOC_MAX_CACHE_SIZE) { From patchwork Mon Jan 20 07:43:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 11341199 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C56114B7 for ; Mon, 20 Jan 2020 07:44:12 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id B384E2073D for ; Mon, 20 Jan 2020 07:44:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=axtens.net header.i=@axtens.net header.b="NenyvpxA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B384E2073D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axtens.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B72016B05C4; Mon, 20 Jan 2020 02:44:10 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id AFA476B05C5; Mon, 20 Jan 2020 02:44:10 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9EB166B05C6; Mon, 20 Jan 2020 02:44:10 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 7DAC76B05C4 for ; Mon, 20 Jan 2020 02:44:10 -0500 (EST) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id 2F842181AC9C6 for ; Mon, 20 Jan 2020 07:44:10 +0000 (UTC) X-FDA: 76397224260.12.pen17_2450f6c360720 X-Spam-Summary: 2,0,0,4f2d20b293ba524e,d41d8cd98f00b204,dja@axtens.net,:kernel-hardening@lists.openwall.com::keescook@chromium.org:linux-kernel@vger.kernel.org:akpm@linux-foundation.org:dja@axtens.net:danielmicay@gmail.com,RULES_HIT:1:41:69:355:379:541:800:960:966:967:973:988:989:1260:1311:1314:1345:1437:1515:1605:1730:1747:1777:1792:1801:2194:2196:2198:2199:2200:2201:2393:2525:2553:2559:2567:2570:2637:2682:2685:2703:2731:2743:2859:2892:2933:2937:2939:2942:2945:2947:2951:2954:3022:3865:3866:3867:3868:3870:3871:3872:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4321:4385:4605:5007:6119:6261:7514:7903:8603:8957:9025:10004:11658:13141:13146:13149:13161:13229:13230,0,RBL:error,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:23,LUA_SUMMARY:none X-HE-Tag: pen17_2450f6c360720 X-Filterd-Recvd-Size: 14735 Received: from mail-pj1-f68.google.com (mail-pj1-f68.google.com [209.85.216.68]) by imf46.hostedemail.com (Postfix) with ESMTP for ; Mon, 20 Jan 2020 07:44:09 +0000 (UTC) Received: by mail-pj1-f68.google.com with SMTP id kx11so6378346pjb.4 for ; Sun, 19 Jan 2020 23:44:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Q9naSqUxzHPFtc57EHQL2H0oZQeWzVS7OaqvwD1FRfU=; b=NenyvpxABKd6hOcqPhh83eoyF/gaiZOh+OeEvInZfRRI5Zokd3GFOAIlA2nobLePtG Xd9NwHEJBKVJ9xd7+v9ystKIqbw060Bco8cqIiqjgcjmjMwqC7nvTxi6xupNsuzZeTMs E4s3sqs4MNeEmMD9aR2ToUAC/zQCLo1LKVqWU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Q9naSqUxzHPFtc57EHQL2H0oZQeWzVS7OaqvwD1FRfU=; b=qLH8aFqkXDXvUHQjdlnkj+2WTNMU/KfEPTDg5KKkCfaWrVI3MNQI933vZSnDwk4Lf9 8XRoDT495xmUkYmHYFhn95CUFh7GmdVQdQ/EBnPix50GZEWuNrc1Uezpf/q78uzdv/6e IyWUuaE8MYW4zj8B7RkJPMCMg1lQyI5JbHtd0SKbEM0fsss5LA4cxIy1q2dVJSLcNXkQ F2aXJ0UnT//2mDHFQpdqMwNpH8m9QBAuZLwxGKuMWrT/CcLKYubxGlUdHXvZm+A55chL +ePKHTjE/MHfxQqzTHtyNKtD093fw0QxTR8oa0FaWeYRds97Xa6b7ODIvfrZhhDHj7Yg waTA== X-Gm-Message-State: APjAAAXriGiRFjCV97b0aka9ZbJSDr9uKbGcPrt1SrBLYKEkFIBjYQRU 5EqiR7C14LkgWkv4UlHD5zEAlw== X-Google-Smtp-Source: APXvYqxLeiWwe5nyCHjHlUvo/yCR2up/7I6JYzI4pzU3HwwuWU199gXkrFBh0vomggtFROnkeJlIXA== X-Received: by 2002:a17:902:8f94:: with SMTP id z20mr13991205plo.62.1579506248432; Sun, 19 Jan 2020 23:44:08 -0800 (PST) Received: from localhost (2001-44b8-1113-6700-4064-d910-a710-f29a.static.ipv6.internode.on.net. [2001:44b8:1113:6700:4064:d910:a710:f29a]) by smtp.gmail.com with ESMTPSA id j9sm36914783pff.6.2020.01.19.23.44.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 23:44:07 -0800 (PST) From: Daniel Axtens To: kernel-hardening@lists.openwall.com, linux-mm@kvack.org, keescook@chromium.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Daniel Axtens , Daniel Micay Subject: [PATCH 5/5] [RFC] mm: annotate memory allocation functions with their sizes Date: Mon, 20 Jan 2020 18:43:44 +1100 Message-Id: <20200120074344.504-6-dja@axtens.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200120074344.504-1-dja@axtens.net> References: <20200120074344.504-1-dja@axtens.net> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: gcc and clang support the alloc_size attribute. Quoting : alloc_size (position) alloc_size (position-1, position-2) The alloc_size attribute may be applied to a function that returns a pointer and takes at least one argument of an integer or enumerated type. It indicates that the returned pointer points to memory whose size is given by the function argument at position-1, or by the product of the arguments at position-1 and position-2. Meaningful sizes are positive values less than PTRDIFF_MAX. GCC uses this information to improve the results of __builtin_object_size. gcc supports this back to at least 4.3.6 [1], and clang has supported it since December 2016 [2]. I think this is sufficent to make it always-on. Annotate the kmalloc and vmalloc family: where a memory allocation has a size knowable at compile time, allow the compiler to use that for __builtin_object_size() calculations. There are a couple of limitations: * only functions that return a single pointer can be directly annotated * only functions that take the size as a parameter (or as the product of two parameters) can be directly annotated. These could possibly be addressed in future with some hackery. This is useful for two things: * __builtin_object_size() is used in fortify and copy_to/from_user to find bugs at compile time and run time. * knowing the size allows the compiler to inline things when using __builtin_* functions. With my config with FORTIFY_SOURCE enabled I see a number of strlcpys being converted into a strlen and inline memcpy. This leads to an overall size increase of 0.04% (per bloat-o-meter) when compiled with -O2. [1]: https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Function-Attributes.html#Function-Attributes [2]: https://reviews.llvm.org/D14274 Cc: Kees Cook Cc: Daniel Micay Signed-off-by: Daniel Axtens --- include/linux/compiler_attributes.h | 6 +++++ include/linux/kasan.h | 12 ++++----- include/linux/slab.h | 38 ++++++++++++++++++----------- include/linux/vmalloc.h | 26 ++++++++++---------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index cdf016596659..ccacbb2f2c56 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -56,6 +56,12 @@ #define __aligned(x) __attribute__((__aligned__(x))) #define __aligned_largest __attribute__((__aligned__)) +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#alloc-size + */ +#define __alloc_size(a, ...) __attribute__((alloc_size(a, ## __VA_ARGS__))) + /* * Note: users of __always_inline currently do not write "inline" themselves, * which seems to be required by gcc to apply the attribute according diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 5cde9e7c2664..a8da784c98ad 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -53,13 +53,13 @@ void * __must_check kasan_init_slab_obj(struct kmem_cache *cache, const void *object); void * __must_check kasan_kmalloc_large(const void *ptr, size_t size, - gfp_t flags); + gfp_t flags) __alloc_size(2); void kasan_kfree_large(void *ptr, unsigned long ip); void kasan_poison_kfree(void *ptr, unsigned long ip); void * __must_check kasan_kmalloc(struct kmem_cache *s, const void *object, - size_t size, gfp_t flags); + size_t size, gfp_t flags) __alloc_size(3); void * __must_check kasan_krealloc(const void *object, size_t new_size, - gfp_t flags); + gfp_t flags) __alloc_size(2); void * __must_check kasan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags); @@ -124,18 +124,18 @@ static inline void *kasan_init_slab_obj(struct kmem_cache *cache, return (void *)object; } -static inline void *kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) +static inline __alloc_size(2) void *kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) { return ptr; } static inline void kasan_kfree_large(void *ptr, unsigned long ip) {} static inline void kasan_poison_kfree(void *ptr, unsigned long ip) {} -static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, +static inline __alloc_size(3) void *kasan_kmalloc(struct kmem_cache *s, const void *object, size_t size, gfp_t flags) { return (void *)object; } -static inline void *kasan_krealloc(const void *object, size_t new_size, +static inline __alloc_size(2) void *kasan_krealloc(const void *object, size_t new_size, gfp_t flags) { return (void *)object; diff --git a/include/linux/slab.h b/include/linux/slab.h index 8141c6b1882a..fbfc81f37374 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -184,7 +184,7 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *, struct mem_cgroup *); /* * Common kmalloc functions provided by all allocators */ -void * __must_check krealloc(const void *, size_t, gfp_t); +void * __must_check krealloc(const void *, size_t, gfp_t) __alloc_size(2); void kfree(const void *); void kzfree(const void *); size_t __ksize(const void *); @@ -389,7 +389,9 @@ static __always_inline unsigned int kmalloc_index(size_t size) } #endif /* !CONFIG_SLOB */ -void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc; +__assume_kmalloc_alignment __malloc __alloc_size(1) void * +__kmalloc(size_t size, gfp_t flags); + void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment __malloc; void kmem_cache_free(struct kmem_cache *, void *); @@ -413,8 +415,11 @@ static __always_inline void kfree_bulk(size_t size, void **p) } #ifdef CONFIG_NUMA -void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc; -void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) __assume_slab_alignment __malloc; +__assume_kmalloc_alignment __malloc __alloc_size(1) void * +__kmalloc_node(size_t size, gfp_t flags, int node); + +__assume_slab_alignment __malloc void * +kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #else static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node) { @@ -428,12 +433,14 @@ static __always_inline void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t f #endif #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t) __assume_slab_alignment __malloc; +extern __alloc_size(3) void * +kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t); #ifdef CONFIG_NUMA -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, - gfp_t gfpflags, - int node, size_t size) __assume_slab_alignment __malloc; +extern __assume_slab_alignment __malloc __alloc_size(4) void * +kmem_cache_alloc_node_trace(struct kmem_cache *s, + gfp_t gfpflags, + int node, size_t size); #else static __always_inline void * kmem_cache_alloc_node_trace(struct kmem_cache *s, @@ -445,8 +452,8 @@ kmem_cache_alloc_node_trace(struct kmem_cache *s, #endif /* CONFIG_NUMA */ #else /* CONFIG_TRACING */ -static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, - gfp_t flags, size_t size) +static __always_inline __alloc_size(3) void * +kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t flags, size_t size) { void *ret = kmem_cache_alloc(s, flags); @@ -454,7 +461,7 @@ static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, return ret; } -static __always_inline void * +static __always_inline __alloc_size(4) void * kmem_cache_alloc_node_trace(struct kmem_cache *s, gfp_t gfpflags, int node, size_t size) @@ -466,10 +473,12 @@ kmem_cache_alloc_node_trace(struct kmem_cache *s, } #endif /* CONFIG_TRACING */ -extern void *kmalloc_order(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment __malloc; +extern __assume_page_alignment __malloc __alloc_size(1) void * +kmalloc_order(size_t size, gfp_t flags, unsigned int order); #ifdef CONFIG_TRACING -extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment __malloc; +extern __assume_page_alignment __malloc __alloc_size(1) void * +kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order); #else static __always_inline void * kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) @@ -645,7 +654,8 @@ static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int node) #ifdef CONFIG_NUMA -extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long); +extern __alloc_size(1) void * +__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long); #define kmalloc_node_track_caller(size, flags, node) \ __kmalloc_node_track_caller(size, flags, node, \ _RET_IP_) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 0507a162ccd0..a3651bcc62a3 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -102,22 +102,22 @@ static inline void vmalloc_init(void) static inline unsigned long vmalloc_nr_pages(void) { return 0; } #endif -extern void *vmalloc(unsigned long size); -extern void *vzalloc(unsigned long size); -extern void *vmalloc_user(unsigned long size); -extern void *vmalloc_node(unsigned long size, int node); -extern void *vzalloc_node(unsigned long size, int node); -extern void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags); -extern void *vmalloc_exec(unsigned long size); -extern void *vmalloc_32(unsigned long size); -extern void *vmalloc_32_user(unsigned long size); -extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot); +extern void *vmalloc(unsigned long size) __alloc_size(1); +extern void *vzalloc(unsigned long size) __alloc_size(1); +extern void *vmalloc_user(unsigned long size) __alloc_size(1); +extern void *vmalloc_node(unsigned long size, int node) __alloc_size(1); +extern void *vzalloc_node(unsigned long size, int node) __alloc_size(1); +extern void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags) __alloc_size(1); +extern void *vmalloc_exec(unsigned long size) __alloc_size(1); +extern void *vmalloc_32(unsigned long size) __alloc_size(1); +extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); +extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) __alloc_size(1); extern void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long start, unsigned long end, gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags, int node, - const void *caller); + const void *caller) __alloc_size(1); #ifndef CONFIG_MMU -extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags); +extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags) __alloc_size(1); static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags, void *caller) { @@ -125,7 +125,7 @@ static inline void *__vmalloc_node_flags_caller(unsigned long size, int node, } #else extern void *__vmalloc_node_flags_caller(unsigned long size, - int node, gfp_t flags, void *caller); + int node, gfp_t flags, void *caller) __alloc_size(1); #endif extern void vfree(const void *addr);