Received: by 2002:ab2:7b86:0:b0:1f7:5705:b850 with SMTP id q6csp937796lqh; Sun, 5 May 2024 08:25:22 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUgdtmmux34KjBdlSdbiIeM4DNThZF31ICMcJ/Gg2YPtg0kW5o8jawHSRQ54G85bZry9Jzo7ul3K3vsDPj0QVRtwxXm9lLfRMrqC6jZig== X-Google-Smtp-Source: AGHT+IGivlnctS8GRNoYEt0drL7YuKNFuwrD3W7DY/8FKI05zNdae+8dE9bkXHpAVQJ72yoYi40J X-Received: by 2002:a17:90b:2396:b0:2b1:fce5:f308 with SMTP id mr22-20020a17090b239600b002b1fce5f308mr6002497pjb.49.1714922721593; Sun, 05 May 2024 08:25:21 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714922721; cv=pass; d=google.com; s=arc-20160816; b=zmAA6RawtXU2Pj6ncdmxEx4m8EyEf+qcvhHf7Pn/GhAyTMYOOSib8R/M5FoIG9RIdw IFv6e0kbI3pGTj7U9RTplJhR1n2sbkBtE0rxXjojoBPGItUkSIPD5ht/b/8ntPXiHnTA b6nRJQL4DgqL7/P76gBuXlmE5nNVvSZP/ZvTPLJkyzA/vCRXx9/MurYmfVA54Xym/jPE 93dOdAdVoBisqL6Ou6W/l5m6ETEzUdT3WTiyB6iefYlajZFEVUB6FD+IeTWG8tP3otYV mSvL518yldA0xzV6UKz3S0cPIEn1VETTm1qQgNQ3sKLL8zins4sxgrRUepiKSquFQblY zTiw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature; bh=yMjNEPDv2xsuVDvmwEGk6roF3RPmf7R4LsU+11Mt7Pw=; fh=FQ91scAKEhXC7JXe+qS5NBNbUnVRtyWc8RdcpJvkIt8=; b=WrkCD+NE6enkd9lfEWuBhfRalOKXLrJfKx2XpkSpauz2oZCgeURKC0fetPZEDKNTBU i060wc5Q3SGiyayW+eMs6fe3k/2p7z8w0bPJKfHpDRTrtdqAnWq2rsas3VVKzevVEGPW eHXwb20PGt+pQKIwAWDI3fyVd/VrbL/Of1wOOGOk7bHqHYXzZ8AAhaJ0r1GhFjQ2bNgn wTQQw2y4BysRxXbD4lLYA0vVdKWBvsNOOGGrujZJxZRBTQyLmF/wY++dS7H5T6f9lL9g ZwzsmBUdMh/X9JNVR5sQQE/bt05AAO1hFkInml1KeYk8HYLM2W/n8M7SiRwEAyRgPABC tZVQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=IDnxK9HK; arc=pass (i=1 spf=pass spfdomain=wanadoo.fr dkim=pass dkdomain=wanadoo.fr dmarc=pass fromdomain=wanadoo.fr); spf=pass (google.com: domain of linux-kernel+bounces-169030-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-169030-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=wanadoo.fr Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id me1-20020a17090b17c100b002b32f2de11dsi9320433pjb.115.2024.05.05.08.25.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 May 2024 08:25:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-169030-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=IDnxK9HK; arc=pass (i=1 spf=pass spfdomain=wanadoo.fr dkim=pass dkdomain=wanadoo.fr dmarc=pass fromdomain=wanadoo.fr); spf=pass (google.com: domain of linux-kernel+bounces-169030-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-169030-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=wanadoo.fr Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 352B12819A6 for ; Sun, 5 May 2024 15:25:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AA8A8374F9; Sun, 5 May 2024 15:25:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=wanadoo.fr header.i=@wanadoo.fr header.b="IDnxK9HK" Received: from smtp.smtpout.orange.fr (smtp-20.smtpout.orange.fr [80.12.242.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DFDB747F; Sun, 5 May 2024 15:25:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.12.242.20 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714922712; cv=none; b=OTeJfZh0cOErxXg6HYDQM/MIHM7Ji90iehkkYYP22s5B2TK3uxeUymDmthOezdJgCdeAwsgUuesWj9ciTrAGaxaoxHax7WDbUCPtm8Om8atU5MfVRcPrmepnLi29YELV8Uekw81HJjRpDjdDQ660scbdajT/fMzsIXOpNpT7bsQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714922712; c=relaxed/simple; bh=h1GSfJkP+XpAGve4Yrrj47DZ5Mm63WGc/WQWxHSpP8E=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=uBx4vtJC1PxYm+0x3mXIjLEy3Viz2+BTmiHaPBGhSuq6L4FtFBfs6p15qMeBsTkVf8D2Sj/woYuCT9OwQ7xcaIAUenOXXlQ3SfDNfAH2Lg9JJzoKfKltgCizdX96Epodq4mYEXQJGmEzAoRsXnaKktJoyb/sJ+J4wVetzvUsZJc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wanadoo.fr; spf=pass smtp.mailfrom=wanadoo.fr; dkim=pass (2048-bit key) header.d=wanadoo.fr header.i=@wanadoo.fr header.b=IDnxK9HK; arc=none smtp.client-ip=80.12.242.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wanadoo.fr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wanadoo.fr Received: from [192.168.1.37] ([86.243.17.157]) by smtp.orange.fr with ESMTPA id 3djUsCqAriGtU3djUsiM9f; Sun, 05 May 2024 17:25:00 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wanadoo.fr; s=t20230301; t=1714922700; bh=yMjNEPDv2xsuVDvmwEGk6roF3RPmf7R4LsU+11Mt7Pw=; h=Message-ID:Date:MIME-Version:Subject:To:From; b=IDnxK9HKNXMrDCOiRXDrSdpkHKN1iGS7Yjn0Iz67xruJmVxfgXOaVghYwqxKPMETU Siszc0hH6MeY5bF6Z0mA8WyDCJgjQS7MfFtKc7g2JXkWLLEqGT0o1SclcrR2iZ4uqs HZDEupsiXqRYxY7pAZ2RUlROj+h1Y+LLXki/znkIBP9Z1zMVRJG9TJaGpwkdJ8UPcv jkBDiBqjiyqTS14QKVZ0MDo0SbGRnd/mgFlrVh7IS+opLPoBZvfBxZSbL3SBdMo01k Tx0hmXjl45QcY6Q2h7pJ/1Tv5qHpClln2vJtchNajqwmHFQV99VMQ+ZtMKbIvTaV5k TmFLp+kBFQviA== X-ME-Helo: [192.168.1.37] X-ME-Auth: Y2hyaXN0b3BoZS5qYWlsbGV0QHdhbmFkb28uZnI= X-ME-Date: Sun, 05 May 2024 17:25:00 +0200 X-ME-IP: 86.243.17.157 Message-ID: <51a49bae-bd91-428e-b476-f862711453a0@wanadoo.fr> Date: Sun, 5 May 2024 17:24:55 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] perf/ring_buffer: Prefer struct_size over open coded arithmetic To: Erick Archer , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , Kees Cook , "Gustavo A. R. Silva" , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, llvm@lists.linux.dev References: Content-Language: en-MW From: Christophe JAILLET In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Le 05/05/2024 à 16:15, Erick Archer a écrit : > This is an effort to get rid of all multiplications from allocation > functions in order to prevent integer overflows [1][2]. > > As the "rb" variable is a pointer to "struct perf_buffer" and this > structure ends in a flexible array: > > struct perf_buffer { > [...] > void *data_pages[]; > }; > > the preferred way in the kernel is to use the struct_size() helper to > do the arithmetic instead of the calculation "size + count * size" in > the kzalloc_node() functions. > > In the "rb_alloc" function defined in the else branch of the macro > > #ifndef CONFIG_PERF_USE_VMALLOC > > the count in the struct_size helper is the literal "1" since only one > pointer to void is allocated. Also, remove the "size" variable as it > is no longer needed. > > At the same time, prepare for the coming implementation by GCC and Clang > of the __counted_by attribute. Flexible array members annotated with > __counted_by can have their accesses bounds-checked at run-time via > CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for > strcpy/memcpy-family functions). In this case, it is important to note > that the logic needs a little refactoring to ensure that the "nr_pages" > member is initialized before the first access to the flex array. > > In one case, it is only necessary to move the assignment before the > array-writing loop while in the other case the assignment needs to be > added. > > This way, the code is more safer. > > This code was detected with the help of Coccinelle, and audited and > modified manually. > > Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1] > Link: https://github.com/KSPP/linux/issues/160 [2] > Signed-off-by: Erick Archer > --- > Changes in v2: > - Annotate "struct perf_buffer" with __counted_by() attribute (Kees Cook). > - Refactor the logic to gain __counted_by() coverage (Kees Cook). > > Previous versions: > v1 -> https://lore.kernel.org/linux-hardening/AS8PR02MB72372AB065EA8340D960CCC48B1B2@AS8PR02MB7237.eurprd02.prod.outlook.com/ > > Hi Peter, > > I know that you detest the struct_size() helper, however, as Kees > explained in v1, this change improves the robustness of the code. > Also, we will gain __counted_by() coverage. > > I hope this patch can be applied this time. > > Regards, > Erick > --- > kernel/events/internal.h | 2 +- > kernel/events/ring_buffer.c | 14 ++++---------- > 2 files changed, 5 insertions(+), 11 deletions(-) > > diff --git a/kernel/events/internal.h b/kernel/events/internal.h > index 5150d5f84c03..dc8d39b01adb 100644 > --- a/kernel/events/internal.h > +++ b/kernel/events/internal.h > @@ -55,7 +55,7 @@ struct perf_buffer { > void *aux_priv; > > struct perf_event_mmap_page *user_page; > - void *data_pages[]; > + void *data_pages[] __counted_by(nr_pages); > }; > > extern void rb_free(struct perf_buffer *rb); > diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c > index 4013408ce012..080537eff69f 100644 > --- a/kernel/events/ring_buffer.c > +++ b/kernel/events/ring_buffer.c > @@ -822,9 +822,7 @@ struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags) > unsigned long size; Hi, Should size be size_t? > int i, node; > > - size = sizeof(struct perf_buffer); > - size += nr_pages * sizeof(void *); > - > + size = struct_size(rb, data_pages, nr_pages); > if (order_base_2(size) > PAGE_SHIFT+MAX_PAGE_ORDER) > goto fail; > > @@ -833,6 +831,7 @@ struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags) > if (!rb) > goto fail; > > + rb->nr_pages = nr_pages; > rb->user_page = perf_mmap_alloc_page(cpu); > if (!rb->user_page) > goto fail_user_page; > @@ -843,8 +842,6 @@ struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags) > goto fail_data_pages; > } > > - rb->nr_pages = nr_pages; > - > ring_buffer_init(rb, watermark, flags); > > return rb; > @@ -916,18 +913,15 @@ void rb_free(struct perf_buffer *rb) > struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags) > { > struct perf_buffer *rb; > - unsigned long size; > void *all_buf; > int node; > > - size = sizeof(struct perf_buffer); > - size += sizeof(void *); > - > node = (cpu == -1) ? cpu : cpu_to_node(cpu); > - rb = kzalloc_node(size, GFP_KERNEL, node); > + rb = kzalloc_node(struct_size(rb, data_pages, 1), GFP_KERNEL, node); > if (!rb) > goto fail; > > + rb->nr_pages = nr_pages; I don't think this is correct. There is already a logic in place about it a few lines below: all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE); if (!all_buf) goto fail_all_buf; rb->user_page = all_buf; rb->data_pages[0] = all_buf + PAGE_SIZE; if (nr_pages) { <--- here rb->nr_pages = 1; <--- rb->page_order = ilog2(nr_pages); } I think that what is needed is to move this block just 2 lines above, (before rb->data_pages[0] = ...) I'm also wondering what should be done if nr_pages = 0. CJ > INIT_WORK(&rb->work, rb_free_work); > > all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE);