From patchwork Fri Feb 9 11:18:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 198820 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp780365dyd; Fri, 9 Feb 2024 03:21:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IGEWwGVqBEGx7rbjI1o51dOseBPmWMg9LF4fdancbQgMKr3BjmVdYmNJk0ELv+E/5juXNLp X-Received: by 2002:a0c:e144:0:b0:68c:ae2d:a3c with SMTP id c4-20020a0ce144000000b0068cae2d0a3cmr1193583qvl.5.1707477709001; Fri, 09 Feb 2024 03:21:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707477708; cv=pass; d=google.com; s=arc-20160816; b=K6Ea8GK59AfWpgKQnqRee2/pMsDZ73KgiyF2JIJQVof2vZ13GjAUC0fjyLMK4+21pm 6unA9HLKm2YHfAMKJbgAjZlRpErzbIKneSTdDCkKNTEKrfCe3gr5dy/ItK9wlL3Lf5PG b7SGwqCcxbokzzsZDT7AvDnfAFi2GKdPVJOOeyLJIfP6n2Bk5I1cxvr8nrOcW/Lajr33 flnlhq2tk+o425dP+Tmhr4eIv8nEKg3ZvMDBRQxdxqhNAuONL7+XheYJvXsIHzD3R5nh v4VVnjVUZVA/ajg4BXC9LuP6e37pclNUEwbIXYefDFj3gGqyRoJNjfKNfgYNk3rl9/IG Byww== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :dkim-signature; bh=N6zYzDocV9Qhlicntw8rLmKyg1TDcaEgd7JNHcXSwhg=; fh=xgCmI2WPkhK8nS+y8wc+2YdSyD9+69Fj5a1HuVqxPLQ=; b=lPf8VgON3cBnV2c0DPDMTykvsDi+pkI5nyCxdy2NQrEY9ZXd9TCrg0IJARf9qbeTra 93/G+NMuhVyT5kBO7yZKYRnyCy1gPFoTkUCxTMNpHK+PduWfWbm+U0+VRIJG/ejoyXtV MHPHZ1tRyZVDy8p+CYWIEWnvWQYJpoCKF7qFpqrj1TaGoQk6N/89CkyL3raokTCM2W3z LbuuV34u5YoV/K1dv2zF0tI0hX0aRidCySR4jfYM/SvpTy0nIhs3MYsVVZ+n396kRQtQ 6BNuxd2sArrRFtGJRtM15mPvhGP9NdwKE3zZkYjdv/zhk8XGZootbZ95OHythw1nPE2l GRWg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=g6OIXAg3; arc=pass (i=1 spf=pass spfdomain=flex--aliceryhl.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-59283-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59283-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=2; AJvYcCWIIPw1dScn1hrEgnoggoH8d9kg0FkylavjKAgPUzcxwkR+U+H9CSVySqpseuW41YKo/3CMlpxInyeCWD3UYIKcvTZMdQ== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id t5-20020a0562140c6500b0068cc7eea8a4si1591563qvj.587.2024.02.09.03.21.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Feb 2024 03:21:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-59283-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=g6OIXAg3; arc=pass (i=1 spf=pass spfdomain=flex--aliceryhl.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-59283-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59283-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com 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 ny.mirrors.kernel.org (Postfix) with ESMTPS id A67B81C245E2 for ; Fri, 9 Feb 2024 11:21:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9392A3C46A; Fri, 9 Feb 2024 11:19:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="g6OIXAg3" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (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 4B20D2E401 for ; Fri, 9 Feb 2024 11:19:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707477546; cv=none; b=YPnq5mPdZ/3XuKLdaP6Ra2dI32lZJRyQrAkhm2uUyrFmiKM5cFwwvWLM2l9bHp+BxmEeeyEq2E5pCdv+8MwikSS2rS3Llifc7MiZMq2wqDe1np8XfGdXe3xo+vuEse5f9/v3ivPpqQRFRNzqZlru1ankT7H4BpjxSq6YKLm3aQk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707477546; c=relaxed/simple; bh=JMsIaHhJXFHUUWu3yyeKAXmjMagByT5pUYTSUjzRo54=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kzClETc1W8Wn9R5F1R7CZWGU+RJu+L1bP3R0ccvanZTq/THPgPAfN7EkpsPSvkooVn5rVt7QE2TRszxKyomlPZH16EfNEL4vkE1XLRbJVmPMfikxL6BR5QdCk5x/vFmyl7Tq0enucAIjdo7EGK40Kd5iF1duSQ3s0mey0SeQlVg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=g6OIXAg3; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc6b26783b4so1236883276.0 for ; Fri, 09 Feb 2024 03:19:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707477543; x=1708082343; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=N6zYzDocV9Qhlicntw8rLmKyg1TDcaEgd7JNHcXSwhg=; b=g6OIXAg3wHu/7YUa1U/CGpqVfac34vYbBOtMiVPZDPG06iMKKesqy3W7vEMQdO753P OWzG1HqZ0ddUUIPyG7kSir6bHDzB2cwiCWqp75rodl45VDZFT4gOaXMnVaDXvte/CK9b ayRGlfnoAeZheW9vy/neNodNUektYmDP8NO/j+iWXlzIuwasSITn0+NptCO5Ys/52Bk2 JD7+ExngMcelYPETWAAmQEgNLzNoDjzLKvrl/sCkbrLmGssT1oQUBFdVkYUCfxkdVyTs KzmUw9gJmZgQQibUvaXmKCek6zNDzaqn5FHdHKK6I5mXaxmjeRLnQRd0bqQoa+cfVj42 Ya5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707477543; x=1708082343; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=N6zYzDocV9Qhlicntw8rLmKyg1TDcaEgd7JNHcXSwhg=; b=oOiEKcPZQo6dfZsfjBn/dlEa0s38rTsKPekUlGqtX4zfYgVnR6r39CrcoqiMtCKo/s ZKa7/W/+In+HoohefqrsWRcPzXQuUJMJWpu4slzdZj0SojT58bv8jaKPDXiOx8lT5s+0 OnBe5P031SuSfsx5kOwbT1xXmc+T7kN97z51b9jrY9pC3FuxuqL9LSvmNq+JU2m7oMbn Gl+xEyG0S9XxTuW3+iN9hITljnzQw67CeiMu0fnYVg/j5sMFKNVTBX+bDFasomit9DZA rwxvQnCS0NcIdoXgbnFChTdb/j/1looLbzp+fHEMbv48MG1e/8+R11QrTnr67zYphVyr j32w== X-Gm-Message-State: AOJu0YyXitNmSgnSG0w4pbhhaKBspGwBfuO5DDrEdLFQic63DQWDFSW9 W2FtF5ieFcXShdfuWzz2isIy6RxfgdJ+N9cxacsc9y+UF9XOotRBTEZFpb/RvPpMx0cei5gCnTF 1bt5K1CXSpyIO5w== X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a05:6902:1004:b0:dc7:3189:4e75 with SMTP id w4-20020a056902100400b00dc731894e75mr18645ybt.3.1707477543307; Fri, 09 Feb 2024 03:19:03 -0800 (PST) Date: Fri, 09 Feb 2024 11:18:18 +0000 In-Reply-To: <20240209-alice-file-v5-0-a37886783025@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240209-alice-file-v5-0-a37886783025@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=6444; i=aliceryhl@google.com; h=from:subject:message-id; bh=JMsIaHhJXFHUUWu3yyeKAXmjMagByT5pUYTSUjzRo54=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBlxgoS6Bl6o/Gc13YOU7SZw4BO7f0q+SLSNyZw2 c03VNDoUq+JAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZcYKEgAKCRAEWL7uWMY5 RtbXD/9SpVOukf20wD3Lw87sf+QOlVl4wKCvVksht02nEFck15Jq9lBGWB85P/VDxzNwvNYVFjm Y5DNk9Gjo38nqA2ISJBdUn5PRONTd6c/6D/sxwmSsWwwYMyW/1DfrEyniql9ATz7twTo5SDG0qv olUGwCmGJzenMA7rqUBkkI2cmsFnZmTV+HrcN3z89Qq2Ftwdu9Nd8wwkitOQizW0P5TDH7ZlHvt Jw1Tmc57E9Me7k2F2oPlnEzaXKBXHm6dm7RQX8tnDI4tr2ohz81lGXjZjWVJR40ZTfv9XtvK3N2 8o7YD3uFWrW0Facera6I6wmZQcCPBnBHfEpQpxLuNNrgjOkgm5HaRUKMjKk3r67B7n1VhD58LEU qMS8DHGngzMFLTpMVLt1O14hdR/6dJiZFKIIwC0VK6lttv6lSVIFMdpjgwMi19YeYIblP9Z5WDJ HBf2LdD4rFr7a3GH3Y6FRocdQ5/8cjVQa2C76C8XFQYBemIDAbRM0nS1Xg4aSYEbFpN1mvohDDs 062FJ7Ao7kbGM1rtND9HXnrhpo3quUnyP15jdL+a4hJpks6w0fxOaOpiKPles1qgVVU5pcIfh8l pQFm418ktkJhnNrd6KthgBv70AlbiEBQjGF4KUEfhhxBTJu/Mxrp67/ED6Bg1YtoHwSL6lUT28C mcih4vpjTnWaIOQ== X-Mailer: b4 0.13-dev-26615 Message-ID: <20240209-alice-file-v5-5-a37886783025@google.com> Subject: [PATCH v5 5/9] rust: security: add abstraction for secctx From: Alice Ryhl To: Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Peter Zijlstra , Alexander Viro , Christian Brauner , Greg Kroah-Hartman , " =?utf-8?q?Arve_Hj=C3=B8n?= =?utf-8?q?nev=C3=A5g?= " , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan Cc: Dan Williams , Kees Cook , Matthew Wilcox , Thomas Gleixner , Daniel Xu , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alice Ryhl , Martin Rodriguez Reboredo , Trevor Gross X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790420146466741002 X-GMAIL-MSGID: 1790420146466741002 Add an abstraction for viewing the string representation of a security context. This is needed by Rust Binder because it has a feature where a process can view the string representation of the security context for incoming transactions. The process can use that to authenticate incoming transactions, and since the feature is provided by the kernel, the process can trust that the security context is legitimate. Reviewed-by: Benno Lossin Reviewed-by: Martin Rodriguez Reboredo Reviewed-by: Trevor Gross Signed-off-by: Alice Ryhl --- rust/bindings/bindings_helper.h | 1 + rust/helpers.c | 21 ++++++++++++ rust/kernel/cred.rs | 8 +++++ rust/kernel/lib.rs | 1 + rust/kernel/security.rs | 72 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index 84a56e8b6b67..5ca497d786f0 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers.c b/rust/helpers.c index 10ed69f76424..fd633d9db79a 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -177,6 +178,26 @@ void rust_helper_put_cred(const struct cred *cred) } EXPORT_SYMBOL_GPL(rust_helper_put_cred); +#ifndef CONFIG_SECURITY +void rust_helper_security_cred_getsecid(const struct cred *c, u32 *secid) +{ + security_cred_getsecid(c, secid); +} +EXPORT_SYMBOL_GPL(rust_helper_security_cred_getsecid); + +int rust_helper_security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +{ + return security_secid_to_secctx(secid, secdata, seclen); +} +EXPORT_SYMBOL_GPL(rust_helper_security_secid_to_secctx); + +void rust_helper_security_release_secctx(char *secdata, u32 seclen) +{ + security_release_secctx(secdata, seclen); +} +EXPORT_SYMBOL_GPL(rust_helper_security_release_secctx); +#endif + /* * `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can * use it in contexts where Rust expects a `usize` like slice (array) indices. diff --git a/rust/kernel/cred.rs b/rust/kernel/cred.rs index 360d6fdbe5e7..fdd899040098 100644 --- a/rust/kernel/cred.rs +++ b/rust/kernel/cred.rs @@ -50,6 +50,14 @@ pub unsafe fn from_ptr<'a>(ptr: *const bindings::cred) -> &'a Credential { unsafe { &*ptr.cast() } } + /// Get the id for this security context. + pub fn get_secid(&self) -> u32 { + let mut secid = 0; + // SAFETY: The invariants of this type ensures that the pointer is valid. + unsafe { bindings::security_cred_getsecid(self.0.get(), &mut secid) }; + secid + } + /// Returns the effective UID of the given credential. pub fn euid(&self) -> bindings::kuid_t { // SAFETY: By the type invariant, we know that `self.0` is valid. Furthermore, the `euid` diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index f65e5978f807..d55d065642f0 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -44,6 +44,7 @@ pub mod net; pub mod prelude; pub mod print; +pub mod security; mod static_assert; #[doc(hidden)] pub mod std_vendor; diff --git a/rust/kernel/security.rs b/rust/kernel/security.rs new file mode 100644 index 000000000000..ee2ef0385bae --- /dev/null +++ b/rust/kernel/security.rs @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Linux Security Modules (LSM). +//! +//! C header: [`include/linux/security.h`](srctree/include/linux/security.h). + +use crate::{ + bindings, + error::{to_result, Result}, +}; + +/// A security context string. +/// +/// # Invariants +/// +/// The `secdata` and `seclen` fields correspond to a valid security context as returned by a +/// successful call to `security_secid_to_secctx`, that has not yet been destroyed by calling +/// `security_release_secctx`. +pub struct SecurityCtx { + secdata: *mut core::ffi::c_char, + seclen: usize, +} + +impl SecurityCtx { + /// Get the security context given its id. + pub fn from_secid(secid: u32) -> Result { + let mut secdata = core::ptr::null_mut(); + let mut seclen = 0u32; + // SAFETY: Just a C FFI call. The pointers are valid for writes. + to_result(unsafe { bindings::security_secid_to_secctx(secid, &mut secdata, &mut seclen) })?; + + // INVARIANT: If the above call did not fail, then we have a valid security context. + Ok(Self { + secdata, + seclen: seclen as usize, + }) + } + + /// Returns whether the security context is empty. + pub fn is_empty(&self) -> bool { + self.seclen == 0 + } + + /// Returns the length of this security context. + pub fn len(&self) -> usize { + self.seclen + } + + /// Returns the bytes for this security context. + pub fn as_bytes(&self) -> &[u8] { + let ptr = self.secdata; + if ptr.is_null() { + debug_assert_eq!(self.seclen, 0); + // We can't pass a null pointer to `slice::from_raw_parts` even if the length is zero. + return &[]; + } + + // SAFETY: The call to `security_secid_to_secctx` guarantees that the pointer is valid for + // `seclen` bytes. Furthermore, if the length is zero, then we have ensured that the + // pointer is not null. + unsafe { core::slice::from_raw_parts(ptr.cast(), self.seclen) } + } +} + +impl Drop for SecurityCtx { + fn drop(&mut self) { + // SAFETY: By the invariant of `Self`, this frees a pointer that came from a successful + // call to `security_secid_to_secctx` and has not yet been destroyed by + // `security_release_secctx`. + unsafe { bindings::security_release_secctx(self.secdata, self.seclen as u32) }; + } +}