From patchwork Fri Feb 2 10:55:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 195798 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp344603dyc; Fri, 2 Feb 2024 02:57:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IF8vMBvA3Ka7FHVibr/e38JG3rZsE2BTxj6sKeNbkOJbdQjikpLhCSPO1mG8y+DDEqOAmdm X-Received: by 2002:aa7:df0f:0:b0:55e:ed35:ffce with SMTP id c15-20020aa7df0f000000b0055eed35ffcemr980978edy.37.1706871470170; Fri, 02 Feb 2024 02:57:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706871470; cv=pass; d=google.com; s=arc-20160816; b=Atg+UuhIxJfsPxls2LCO3zet7EDSoohZrSD2EG2pkxkyWPIzFZtsdKp3afxBA8q779 nUOMq8jIT5ljxiwr2AtEhUl6oskCfiz3DiitSaqAKBATGKPJQZ/4rkKaXQkhjNSo6IaP qfeb0SQQ7XF9QY0OriMPkrL7G2D1UcgRJarCgonh3ou9BOzHWzxYBRo8PM6Qb1IaslsY jjA0G29SCacT/HDCblyt9zk8jZ+bYvPsLO3+XLw+ApOZjT7CDK8ZVW3N6VDOURWauQ5N PFz2Jx75SF8F209Nhy41unIYDmP1J2Q2OKNVQhuuq4bgOXXzqG925xw+E5ULCQ7id1T2 tApA== 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=j/7kyGGpKcEwHQdz9v5HdILBox+yyfhBXM6E90EM950=; b=Nom1XR20rY5HT5IBLLZUlNTCJpMYYglqaVy2DoHFDajr7cTlM1TZ/zvpfkN9yMikSC 2WWmeGVtKKLM0eSCemW1zTZ32wB78v71G3/brl2ujTE1uNtfvJRcei09fup08UtYDut4 DGa9I6lVKif+ygu9szoEYLl+gIrIHJKuTX5FF1j1qJcpAl2CcEvHty3epJUw5wDgLxjD CKIhkLAK/LG0rO2slK2lJP7AzoayG+/N1zNqHw7X5NBqOYB+jBSiKpHTCDmCdRD9pjLk v2XPAysQJtt7rN1DQUWj1EofXqvL/FJHv4WJeMjoXUD/4pEAIA01QHrMI0OLtV85RvaL zTxQ==; 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-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49710-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCU3l5u93/Hcj8V1gDCSGMAaKr+EgoldC4H0E1T3F4KoyGLAHA8m7UXcFjVFP5KOQNlZMtHxJkKkPxL3Cj7pXPKYa19YXA== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id cf13-20020a0564020b8d00b0055d0a061ef7si709112edb.523.2024.02.02.02.57.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 02:57:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49710-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; 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-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49710-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 9ADF71F21934 for ; Fri, 2 Feb 2024 10:57:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 868CD14078F; Fri, 2 Feb 2024 10:56:07 +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_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 , 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789784458939992779 X-GMAIL-MSGID: 1789784458939992779 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 Reviewed-by: Trevor Gross Reviewed-by: Martin Rodriguez Reboredo --- 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) }; + } +}