From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (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 DB8371C8FD0 for ; Fri, 28 Jun 2024 14:58:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719586684; cv=none; b=V9xHbJJUj8+yQ483wNUPBivfLcJE+52xHX93yftXIskdJzjml1vk3w2J5o2O92hjhqviy+CNor9lvoRQVZOm3Ce1zebHLhBcU+tXMZ1qTEGsSYd72Hh/ZzVpCMvEeXsQPjuUAIZ4kX8ieAK1jmgkBYvW39j37BihNOofYTydFCw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719586684; c=relaxed/simple; bh=SlqFSzKTXlCLM45RuGs1D6n4w52ysnBrvxDdEN5nqf0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=L1fPJzBXZvtAj6er/edZWRQjs9ihQXkj42GDwibjKTHR6SZvCFnfOMxTMudGTKnXweehS0z7se2ODDw104ycbGiuEiILKNKox31X6LLunsqaUGxQBKQ/vJ8Vg/gKnXIHMKCr75ckD1+MiDn+b/T/5u3sF8UlscIXlrm7K8B5dfk= 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=nsHVRy40; arc=none smtp.client-ip=209.85.219.202 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nsHVRy40" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dfeff072f65so1207164276.3 for ; Fri, 28 Jun 2024 07:58:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1719586681; x=1720191481; 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=SINMfHecFZOdGH/mJM+WIc9fBNelCPSpkZcr54GiFHk=; b=nsHVRy40lyq02cVTaPt3mtBmJJbuc8W7IltZmrr5COZjhsIlpx95eNUitFjsB4d5S+ W1sbRMBWuz9d+lYVmU5A3IbaOFyc4VT0WJxxaE4ppP2FHPCXCi3h5RnIfsiKRznWCQKx +IFWZZgIQQG7ixDAXFO/x1JLxUAsWHxszk8+Y0CdeAvvRSNCzSwVHuRxTDLiSKVc/1g8 kRsJCWBoi4UXbeQlNsPTqxGz/qol9G+WXp4J9Xg1MrQ/A1fopQgCzMct2tUk/YIcpjKg 5pGVtRRrGfJTAd0b5oLn+EveIpwqKhvWoZz3fLoGwqfDS77XHN3S89p6EERUz0nonogJ RXXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719586681; x=1720191481; 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=SINMfHecFZOdGH/mJM+WIc9fBNelCPSpkZcr54GiFHk=; b=m0ayFOmhApW2bK4mqOXfDc3nc5yufVZlR1uWYAsqzdgTP7p/R9/73hfrLbUnb/7QyB IZSIM3Oh8wUen6mb+sxpRCMRYePqF6/sh0L3lWvYngDaAcR87z+FbGDDTgLY8KtltkYw E98QFNg4lkQAYzUE+Oqxfr4/REp5gKMBZRiADuD3S3Tu+NhZdHYu1OOC4vgN81/0Znv2 QbOJD3ng0UlyNDz3IANpiPaIEp8y4czBbNH2ObSFrGseY5rJ9KvLx0jE1OLjTYNazyk3 ncw/qJ5mecMQqfImXjvMgyFL4LMY/ZtxXMaHhP/EbkXRUvngbT9HD9SOeo/H1fRfjxgT ecog== X-Forwarded-Encrypted: i=1; AJvYcCV6UCs5rp59O13H5X+p149FDjnqfRCZXhEdsbE8LD4AAwoAr42DOtcFrEPWt/7NOQeFX/CoA5Mu2761O/NSKsv9AnIOwQGiPhHlq44KCxM= X-Gm-Message-State: AOJu0YwWQkJV1DHj8+o9jbJiOHgHIIjrYgBEGfMlNYA6mbMvjHfTS3sW F704mikQ3vPGplRoj6jza1u1fX98WrKj3jzrGM0oMfhoun0oXLLVgtBH1549ZoxUrw4N27nltkg w1wcopzSimbUzWg== X-Google-Smtp-Source: AGHT+IG+viwqvXgSUt+FssvIzHj7/WggEatwMQjYCGulrBuqUMFYPHMjqAKPBzF/8zxtfjTW6dmdz6QTkqKrZGU= X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a05:6902:c05:b0:e03:2f8e:9d81 with SMTP id 3f1490d57ef6-e032f8ea024mr18312276.0.1719586680992; Fri, 28 Jun 2024 07:58:00 -0700 (PDT) Date: Fri, 28 Jun 2024 14:57:18 +0000 In-Reply-To: <20240628-alice-file-v7-0-4d701f6335f3@google.com> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240628-alice-file-v7-0-4d701f6335f3@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=6442; i=aliceryhl@google.com; h=from:subject:message-id; bh=SlqFSzKTXlCLM45RuGs1D6n4w52ysnBrvxDdEN5nqf0=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBmfs9lqtDNb30DUajglMzWAG1mWxG06cE1X4H13 p9Lb0dhc/qJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZn7PZQAKCRAEWL7uWMY5 RnuZD/48E542L6X6hKdqsfcNV0bFqiV99n+9ZpxONN2UcoPlAQhtWTLvwM2Sc2w96ZQ7wvzoNzs ZABVdIaC8mpa1l+kdZznU7U35bafOW6ojwbgQXAs8i6+kuQXLshf8c7GOiXTUZp4f0hyNBCthSC zbhWLECDIFWR4pB5NGUUsbCiKEwWXRp5Jy+IOA2wZCJ2o7HOKkIx/gH3cGRgXbeponkQIOA7iYZ v/EAUKoJF4xd9hP7rZtK8mn94GW2/W1ULv9zfPqUjOCb7U1NMjM60g081lg2FaAoXqo5NTFDJtX N7MOJbUJtR5fTdb/qFLGfoE6rcClCYohr9YetTHb4hWdwm0LcMbjT/MkmU2sCB5BJPf7KTyDTJl g88BJVZciec9AWX+fIsr4d2K4dUvC5A2TGDFiPtP6QIRRqxAABvSQ2f4jOj1Vpl1wi+DC25vx20 YSl7h5zywXyestJth966QWwi1UyPLwnfxAt/9PVUvyFIgQTGp2bsq/7uwqZtIFQXNACOFWaMC1h ZTHLbkQ6zXWTAelAyIcoAA2tdKdk+CcORDIDtMBnfnetP/LxpXKUKPgrwI50rm/RQnxkCe3EeaJ oBUNBC87QTBMGSYXYkSYO0TnpVLEyY42D7jqPWaWAhWoWRN/Q0mmB8XabZ1yVkH3Ipj8LC8MkqH 2X+R0aj3fT50t0w== X-Mailer: b4 0.13-dev-26615 Message-ID: <20240628-alice-file-v7-5-4d701f6335f3@google.com> Subject: [PATCH v7 5/8] 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=B8nnev=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 Content-Type: text/plain; charset="utf-8" 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 94091cb337e9..cd2aaaaf9214 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers.c b/rust/helpers.c index 9cf25e5324a4..bd540a14c16a 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,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 ea7d07f0e83d..d331ab8a65a1 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -39,6 +39,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) }; + } +} -- 2.45.2.803.g4e1b14247a-goog