Received: by 2002:ab2:69cc:0:b0:1f4:be93:e15a with SMTP id n12csp1861807lqp; Mon, 15 Apr 2024 22:53:44 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCV9GtoVJTHVL/U8TtJy9+TvBWEDOMa7CUuFnsFFugeY2qjNznD2Rh/w4kPxOqEfWJoJ7uvHXW/07o9CDC2uTwaJ2gLAGDDFZjpg6nCeoA== X-Google-Smtp-Source: AGHT+IFjR02V90PFEDkCkWaJIrETvSXNDxe85SAteDFUwbs4hOT77vcryPOq+W15wyDjS9cXJYCP X-Received: by 2002:a05:6a20:8427:b0:1a5:6be8:2d70 with SMTP id c39-20020a056a20842700b001a56be82d70mr1545521pzd.21.1713246823887; Mon, 15 Apr 2024 22:53:43 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713246823; cv=pass; d=google.com; s=arc-20160816; b=gRzMlUg4p1ukfi1plHIHV7OUGPCpndyftt9+YzNa85pLx/L536DHDnQ2sE/R6/dgsE akHDHJy0f8v02nUqXISXK0ehhIoPfxBKHDGXSx15T+wLUNN7vSq6zeh1vCrARz5FZo80 vPWnn2YAhZtwfiT1+O95Su8xV+BkX4i26zNZwwoYAie/UOcBZpj6/uscib7Xl7Cf1egv r5xYqo1dRZsyS4vVpj26ejeJzWZbSd4ASHmRHb+eYKgkQcwL2XvKLGHDe7d9c+9jxiGw rfB2cK0t29eizfWCvDnOSPYl6bv/8zyUmX20ruGPgd5U+56F2EaVoLTxBcGQdHE6g5Ak z34A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:list-unsubscribe:list-subscribe :list-id:precedence:dkim-signature; bh=fOqlvnKucywUEZPZVlRG+mSpGLeAjqCUUNbMfAp62nk=; fh=N0Glh0TO24nrIe3Ugyq2/nkas2gyYtVr2kcITTR+df4=; b=sPpC2wUtqwBeJFJczVW9G7jIHd4citmR29wanhxhGRMSpX4RcA1V0OqLHGH+4GDKUz 25xPpLs7igUUwGtRt3H65NXccedIsGvSCxE0f2hzdWBy3ggY49kb3zKbXiKrhVBmIKKI 5/cXN+xO+Tz+mEXacWQSGq7JuGZn2/cXb580VWbOdcn6gfOi0xNIXHgcBre60bTrBw6P Q6hzD4iDkm0KCuOVvaCzuOAD+49QDRhysbvdSvbsBpMNbbTwUz60HdvkvVY9j6a97oKp 8OtMn/e5vi/R5Q4Kkt2nEKE8dvFj8hTIavyips2d8llJ/6iS3XESf4d3RKLKXSTDARfz 23KA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@umich.edu header.s=google-2016-06-03 header.b=IQiSqnAT; arc=pass (i=1 spf=pass spfdomain=umich.edu dkim=pass dkdomain=umich.edu dmarc=pass fromdomain=umich.edu); spf=pass (google.com: domain of linux-kernel+bounces-146290-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-146290-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=umich.edu Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id lb26-20020a056a004f1a00b006ece3da5268si9065847pfb.391.2024.04.15.22.53.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Apr 2024 22:53:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-146290-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@umich.edu header.s=google-2016-06-03 header.b=IQiSqnAT; arc=pass (i=1 spf=pass spfdomain=umich.edu dkim=pass dkdomain=umich.edu dmarc=pass fromdomain=umich.edu); spf=pass (google.com: domain of linux-kernel+bounces-146290-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-146290-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=umich.edu 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 93B5A283CE5 for ; Tue, 16 Apr 2024 05:53:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 97DEA3BBC9; Tue, 16 Apr 2024 05:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=umich.edu header.i=@umich.edu header.b="IQiSqnAT" Received: from mail-yb1-f176.google.com (mail-yb1-f176.google.com [209.85.219.176]) (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 B4502539C for ; Tue, 16 Apr 2024 05:53:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713246816; cv=none; b=ZqPbpZz/r2QHLjo/4RP9o3pMpDz4j+bKvgChssO7MTAv8rCuw3GbowEmsLS/SlYZ0851VnEtbFVisnzmk9SK9gJn7g+G41hAEB/4oGtilA8Ge/6Y0FZzPgbZTrliEOqZPWOZmvGi3T520Me/OeNR5MRwsEdwDt4Ky3c4XHJlqd8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713246816; c=relaxed/simple; bh=YHXTxo+dMZMqRkcn1P10yAEdeONTVjYOCpBdu90ZcBo=; h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject: To:Cc:Content-Type; b=oY1oP6z/gmRmI2r3G2KwrQwbjffYnkofS4R1bl+D7gwodr3/Hg4Ti3SmeKaHNp/ZfPiemzosBXwuEviXZNLxX3LkQGZAeuEadl4O0QIO38oWHKaEAli0JYZdXZ9gV26nFCbZkyKm4AOoCYhZt26i0/iY6/gSLo5ER5YglzCVhLo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=umich.edu; spf=pass smtp.mailfrom=umich.edu; dkim=pass (2048-bit key) header.d=umich.edu header.i=@umich.edu header.b=IQiSqnAT; arc=none smtp.client-ip=209.85.219.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=umich.edu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=umich.edu Received: by mail-yb1-f176.google.com with SMTP id 3f1490d57ef6-dc25e12cc63so4657717276.0 for ; Mon, 15 Apr 2024 22:53:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=umich.edu; s=google-2016-06-03; t=1713246813; x=1713851613; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=fOqlvnKucywUEZPZVlRG+mSpGLeAjqCUUNbMfAp62nk=; b=IQiSqnATipRUDpTjkbms8g6PFOyCeg4j7QSq4Eer6O59AsqcTxOVyHzN66yo4+sb1d /P4njxSPo8oFD/Szwh07keyJzjk5eCUaPStRK2QhL+FkL5GAQIKbKeQb6ogU6PnPJB48 6aQshPfvRgp9w7W9xqT822hoIeI/V8ErcoRSchdPiYaqzkgaAPNFPmmGo+zmScmR57p9 rfnuTd5j9OHZy+Ln2r05qAfNZ+NdBcEMg7T4KAU26UV1Kv70nRSs8VXORxa2kdWBJEuH X/KymTWhgCaw0dOODuhUfiIgPb7ASimr8kIuB34jOmXVG8yPlErCq7JC9y8wpjzJLXD3 wULw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713246813; x=1713851613; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fOqlvnKucywUEZPZVlRG+mSpGLeAjqCUUNbMfAp62nk=; b=uJtPRjBCOS/rbYSfi+0ca1An7Qc0c3ZRdepRuu9f569554kwWzc8BPxZ4gt0l+hGhX wsIn9pBLtuXC0RvbA+BBwGcTzx7GssxhEwXnX/aeyylJz9Ta5U899vTHLpJbPqCKrzqp 1QfBK8Cq9zf851VZi9GCPxvfl+VhHQiuySP16/q1Xo2VGu2y6wsvzMjCw5ZbOIyAlzt7 2EsmYgAUHw/riEZFPBcF9IKQ1fhjCJefIAONCmiija2WYDlYm4TgNc0ZRctTeWfts4Jm NN/z7mDqr5YadO7ynk+NBr1OU57KGlgZNmbwYMuuc2zXsoIlmjL9bSyyyTaA5aqSZcr4 X9XQ== X-Forwarded-Encrypted: i=1; AJvYcCWmKWvwsLSa0KF0vrr0YVHm5GTRqBvEAnjWVC7uYtBNW0GU/3fatbJy+rQT05Ok7zAJDzMFiBETcvillixAbqs5FMtZ2L8M+GCch2sN X-Gm-Message-State: AOJu0YyStjKEaDcJSVq5XfJEEsxKp/NMlBrKqs64ytdiG9YX7HOhka9q S3UNPZG4/JnZgFNgNgjkfGcdFD1RZpKc6epG41JKm7bUVxoW2aPEMjVnK6mvzXZsVDRkPu8B052 wQKwHBCKJRm2BvL2MU3UGZ80rV7VAw2dh5Hr1JQ== X-Received: by 2002:a25:1fd6:0:b0:dc6:de93:7929 with SMTP id f205-20020a251fd6000000b00dc6de937929mr1415768ybf.26.1713246812640; Mon, 15 Apr 2024 22:53:32 -0700 (PDT) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 References: <20240415-alice-mm-v5-0-6f55e4d8ef51@google.com> <20240415-alice-mm-v5-3-6f55e4d8ef51@google.com> In-Reply-To: <20240415-alice-mm-v5-3-6f55e4d8ef51@google.com> From: Trevor Gross Date: Tue, 16 Apr 2024 01:53:21 -0400 Message-ID: Subject: Re: [PATCH v5 3/4] rust: uaccess: add typed accessors for userspace pointers To: Alice Ryhl Cc: Miguel Ojeda , Matthew Wilcox , Al Viro , Andrew Morton , Kees Cook , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?UTF-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Greg Kroah-Hartman , =?UTF-8?B?QXJ2ZSBIasO4bm5ldsOlZw==?= , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan , Arnd Bergmann , linux-mm@kvack.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Christian Brauner Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Apr 15, 2024 at 3:15=E2=80=AFAM Alice Ryhl w= rote: > > Add safe methods for reading and writing Rust values to and from > userspace pointers. > > The C methods for copying to/from userspace use a function called > `check_object_size` to verify that the kernel pointer is not dangling. > However, this check is skipped when the length is a compile-time > constant, with the assumption that such cases trivially have a correct > kernel pointer. > > In this patch, we apply the same optimization to the typed accessors. > For both methods, the size of the operation is known at compile time to > be size_of of the type being read or written. Since the C side doesn't > provide a variant that skips only this check, we create custom helpers > for this purpose. > > The majority of reads and writes to userspace pointers in the Rust > Binder driver uses these accessor methods. Benchmarking has found that > skipping the `check_object_size` check makes a big difference for the > cases being skipped here. (And that the check doesn't make a difference > for the cases that use the raw read/write methods.) > > This code is based on something that was originally written by Wedson on > the old rust branch. It was modified by Alice to skip the > `check_object_size` check, and to update various comments, including the > notes about kernel pointers in `WritableToBytes`. > > Co-developed-by: Wedson Almeida Filho > Signed-off-by: Wedson Almeida Filho > Reviewed-by: Benno Lossin > Reviewed-by: Boqun Feng > Signed-off-by: Alice Ryhl Couple of docs nits but this looks good to me. Reviewed-by: Trevor Gross > +/// Types for which any bit pattern is valid. > +/// > +/// Not all types are valid for all values. For example, a `bool` must b= e either zero or one, so > +/// reading arbitrary bytes into something that contains a `bool` is not= okay. > +/// > +/// It's okay for the type to have padding, as initializing those bytes = has no effect. > +/// > +/// # Safety > +/// > +/// All bit-patterns must be valid for this type. > +pub unsafe trait FromBytes {} No `UnsafeCell` is also a requirement in zerocopy/bytemuck > +/// Types that can be viewed as an immutable slice of initialized bytes. > +/// > +/// If a struct implements this trait, then it is okay to copy it byte-f= or-byte to userspace. This > +/// means that it should not have any padding, as padding bytes are unin= itialized. Reading > +/// uninitialized memory is not just undefined behavior, it may even lea= d to leaking sensitive > +/// information on the stack to userspace. > +/// > +/// The struct should also not hold kernel pointers, as kernel pointer a= ddresses are also considered > +/// sensitive. However, leaking kernel pointers is not considered undefi= ned behavior by Rust, so > +/// this is a correctness requirement, but not a safety requirement. I don't think mentions of userspace are relevant here since the trait is more general. Maybe a `# Interfacing with userspace` section if there is enough relevant information. > +/// # Safety > +/// > +/// Values of this type may not contain any uninitialized bytes. No UnsafeCell > +pub unsafe trait AsBytes {} > diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs > index c97029cdeba1..e3953eec61a3 100644 > --- a/rust/kernel/uaccess.rs > +++ b/rust/kernel/uaccess.rs > @@ -4,10 +4,15 @@ > //! > //! C header: [`include/linux/uaccess.h`](srctree/include/linux/uaccess.= h) > > -use crate::{bindings, error::code::*, error::Result}; > +use crate::{ > + bindings, > + error::code::*, > + error::Result, > + types::{AsBytes, FromBytes}, > +}; > use alloc::vec::Vec; > use core::ffi::{c_ulong, c_void}; > -use core::mem::MaybeUninit; > +use core::mem::{size_of, MaybeUninit}; > > /// A pointer to an area in userspace memory, which can be either read-o= nly or read-write. > /// > @@ -238,6 +243,38 @@ pub fn read_slice(&mut self, out: &mut [u8]) -> Resu= lt { > self.read_raw(out) > } > > + /// Reads a value of the specified type. > + /// > + /// Fails with `EFAULT` if the read encounters a page fault. > + pub fn read(&mut self) -> Result { > [...] > + /// Writes the provided Rust value to this userspace pointer. > + /// > + /// Fails with `EFAULT` if the write encounters a page fault. > + pub fn write(&mut self, value: &T) -> Result { Read & write could use an example if you are up for it