Received: by 2002:a05:7412:bbc7:b0:fc:a2b0:25d7 with SMTP id kh7csp749177rdb; Fri, 2 Feb 2024 02:57:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IEkJ2ESzuIAfyOX4XTOwXV7jbcg2fV0NVjI1ejx044ufJMXUi+4qnFrDAZEIxuqUamwJjWO X-Received: by 2002:ac8:5c13:0:b0:42a:894d:8dd8 with SMTP id i19-20020ac85c13000000b0042a894d8dd8mr2568426qti.21.1706871448416; Fri, 02 Feb 2024 02:57:28 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706871448; cv=pass; d=google.com; s=arc-20160816; b=guACSG94vcpFqf1izTtAT5GnNw1Umu6uXkP2Hxd+98JvQCGuUi14qKWxiiqXEXvRmp G7yeUbiNLUJe/gpYB4dBrVj+5SOL3b6k7XAoVQYNEDGNzO8ZV7yp6LDjoOB33ihgwS21 r8ioxse3LUDUNXUltsCqyCKljURqPf3mJc/nUz8WcuLmIdCT0qpDGUwpUX1uCuIo06mx PBItaeu0++c4AJ3mSXaDG1lKoNyvAMHP1v6tnisUewiwNSKvuW40LZsv+4wwljlWzK27 5Kb+JgbQ38aZCcI+mqWy6MYdKLgUozpOLl8n6isSjXLFIEkQBHCzBY/fVintbpDJJLr3 aW9A== 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=N/cEy1eL/l/XNVoA+dLHaLRQMYmmdCYyUSwII431DqQ=; fh=mSUb5dihPV+zT//fM4GN/6kCxt3ZaAT2IuHHlu2ZyKQ=; b=c0LCZJ1DPqr8WKL//n63Xn7X1Am/OtAjlXEIK8q7eHskV/YCmUPT20XP7/wX38lx94 5xWkjVE+Po8og2IJSbml8PMHEpcI1buUGYAEWCZiHRjixTiGTN0eHPhRpAW4XPaRkIbN Wvs+Ts9Od6mKKXaf4TMBr9yKevot+eLIJwMcqm/Y62h5hczzNHVZIC50q61v+4WERcqb uQgXtmfyp9AbL20CrvjSmwDJfvb+gQDJlXcxMIpEx77PzIBJXLCt8yR35kdjIDU8acwG 1wVCnwQeiWOBBfsTWomHDrSHudA/5KAa/yier5wAxuxX/1oLIReZaNioaZvm0/ych3px dnVQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=qLqtGd5q; 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-49710-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49710-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWM8FeTWdmuvBx6IysLAyWiQIJjLuz7BlHOdRJv5cRDgb4aObIE21nLQvVqK1QGcGaPtbKiE/Jmb/c5WzPg1kyCQ/nlmVjA9DfKrWngZQ== Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id o8-20020a05622a138800b0042aa70b95c9si1697816qtk.489.2024.02.02.02.57.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 02:57:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49710-linux.lists.archive=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=qLqtGd5q; 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-49710-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49710-linux.lists.archive=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 29DE71C24972 for ; Fri, 2 Feb 2024 10:57:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 83254140762; Fri, 2 Feb 2024 10:56:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="qLqtGd5q" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 7B1E613EFED for ; Fri, 2 Feb 2024 10:56:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706871363; cv=none; b=l+noix3jPX+RRicvE+lGM2orXqyCnPKRTRZcF7Lq/LG00sG4mQxGr0rUO1dzRKdRD5XRkXOutmItryxOY/vZwZ+mksUIHZQdaXaa9dEyrZod5xuwvNaHPfQzmHCTA9VrcHoj6OV1qoqFF7qPREMUPDF44VHKWomkOQtLMejr/wA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706871363; c=relaxed/simple; bh=LAKcJY6R7fk8wuf3FdVFNOskSEsABniFk3E+zDxpTYA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=i8lc1lC3K3EeoodVuGSkebopMHXkHFlu9LW7zot1rW1yA42YGS5EZ31TqShVWu+UwGpBPajLO5ce9oar9i6jLB5a4Ra11p8cGL35waGiDkT8eniQvsN6JmeTJQVH68LHXSxhbqiwYOXa4aIa9L8xvKPtsMv6OutH9WmVAnJYN/A= 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=qLqtGd5q; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-60405c0c9b0so45297237b3.1 for ; Fri, 02 Feb 2024 02:56:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706871360; x=1707476160; 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=N/cEy1eL/l/XNVoA+dLHaLRQMYmmdCYyUSwII431DqQ=; b=qLqtGd5q+9Vt67M12OaNuLmEbjzVIx+CmdnnCfv/v6R9DdAv9OQPP7wLdPIWCCLAvX qk9HGMWDCasO1x9rNXwCCoTsXbdjN3azltQzbEJnI0d/4Fae+bOggIOGRt5NAnS+ifE2 5IJZ+lK4jRMTXFTUexjTSGyoC5FNYbMClpMl50gmy/jP0an1ZD9u01l3e4bowT6nJ2H6 nRhRc6gLJLHMiedm8j1VnDwF8k3XDWkYfoOOIHyAI6T5WtsexACJmA031LAwF1/cUpEa 4UUdgjoGchaODyr692Cdvcd6vwRdr6bCnZ2as5+NFicpiMzYdFS7iaO1shIrR1Jc/EPA naHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706871360; x=1707476160; 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=N/cEy1eL/l/XNVoA+dLHaLRQMYmmdCYyUSwII431DqQ=; b=iPK13OXlcOSUTk7SF6Y0W6xiPA0cS6NW5luMxQjjjJVuhLccEAkIn+OaU+dIfNR7Eo xpROdiAne1uIhIT6YSEWRE6ugLr1t0NOc7/P8o06fN9Z/8w2hDz6C8XdDujvWqWncoba GueDb9uicN/TBGsCJmFj0i0eWni55EAPLhxhnPY9YrEeumLG5zGDqeI4IGIv9vdmTL1I 5EoVhXMsWecrXFGEL9B1SjfOH/kytmKkAhe66j4qi3NTaLqMXvKJq8NyTypw+a7Me+LK wbB05oimKq5l+zPnfh/3j/JVWA7Vr+wgvExpsOytvvXIqkRlEThsbzbX2TqvvnqnGX9d AY6Q== X-Gm-Message-State: AOJu0YwqZupxyH/pn54U5RUE8DYh2GO/HNIgXOO5AWhFOE87OGDsLYP6 65pQMdB2+BYtCJaeZ6GmNyct3XJfl5io0D4vQF2m/chf/qc8oiqmfnITuJsDXUvxi0IuWpdjKfV NJds6zT86ykPyhw== X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a05:6902:108e:b0:dbd:b165:441 with SMTP id v14-20020a056902108e00b00dbdb1650441mr505685ybu.0.1706871360496; Fri, 02 Feb 2024 02:56:00 -0800 (PST) Date: Fri, 2 Feb 2024 10:55:39 +0000 In-Reply-To: <20240202-alice-file-v4-0-fc9c2080663b@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202-alice-file-v4-0-fc9c2080663b@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=6367; i=aliceryhl@google.com; h=from:subject:message-id; bh=LAKcJY6R7fk8wuf3FdVFNOskSEsABniFk3E+zDxpTYA=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBlvMjJDLWaBObEUkm/vJdm8vQJA/wX9vGKDjqW9 /at096sPU+JAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZbzIyQAKCRAEWL7uWMY5 Rou1EACWIY6SndO4eyAbK86sp6UNQjtZ8uyPav+PwM/ipkr9RAskcCYz2fIsoyiYlBEC3g39+BY cXPs5MvP4YA+vze3qBBnSfX6FBp3VB6p2FJpwEltRdhQ4/ryThht6Ji7UA0FyD2OtcvvD4+KJ8d GNjK4haBwvbTUS3ia8HSGmwaX85QiyR/YpUt683Y1vCd0eU/PlOrRYXgtPvKqdWibdUrRpfOt+c ciTN9lOgbgBvUCJWTKO4v64p1eAnoemMsU6jrAMp6AyCCjcdzs066y7gmAYqQE1Qh1iBl5Mt9OU 7Mt03V49vTV+4vPeKkq9wVefoXHrEZOvf/rADw89dqqd31VS30ldHS4BnWGWXVnM5XJXU7eycyW fydQ++WqeaOF2bMSvs92VxM3LSqyFf6AfnrVNooHAfASfsUIT3Jp8ajGXJXvfXmgUBaU5WXz7Il NmUTpwOJSGccHILnkzJI+dh/mXf/M8X1xb7/E7N8LHZndnJ0QOxgtKebuEWPKpm/0iDWok7tXGG 5dh7txZAq7ZRYgaVjRsg+BmElA/b5s865Ptz7EX10xPaVYpslbrfOE+3M3sQmO2zJ+ubLiE8WPD vQLys3PlDJxRvYWfFntquWD+FsnO3aBe32FszwqFGGRD4F0ZuNaWYu1yDXzsZd16RV1akKwSc2F o7onX77ur4pqzaQ== X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Message-ID: <20240202-alice-file-v4-5-fc9c2080663b@google.com> Subject: [PATCH v4 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=20Roy=20Baron?=" , Benno Lossin , Andreas Hindborg , Peter Zijlstra , Alexander Viro , Christian Brauner , Greg Kroah-Hartman , "=?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan , Dan Williams , Kees Cook , Matthew Wilcox , Thomas Gleixner Cc: Daniel Xu , Alice Ryhl , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Adds an abstraction for viewing the string representation of a security context. This is needed by Rust Binder because it has 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 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(+) create mode 100644 rust/kernel/security.rs 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 fabc50e48c9e..0640356a8c29 100644 --- a/rust/kernel/cred.rs +++ b/rust/kernel/cred.rs @@ -48,6 +48,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) }; + } +} -- 2.43.0.594.gd9cf4e227d-goog