From nobody Thu Jan 16 18:08:16 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YYrSw6R2Nz5kkpt; Thu, 16 Jan 2025 18:08:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YYrSw3jq1z3RfY; Thu, 16 Jan 2025 18:08:16 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1737050896; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=AC2N3Fo7YF4gDnI73YdcDc+RGr/G/dr0h5vttmR+4CQ=; b=ZZqZ323a59Irzf+t0Se33pjnMZoWjKVJk3HMQUdKBxp1zLvZW0q9L7CdmjkoJTIVVBhUS1 OAbefX92YuXMwU1msnYLGr/+X18OGEdQKxDLiGd9e6yUR81BTYQbH1LFPUaqJAszZfJxRk NjdXmWBXgiYTQzb0QReZIcpwApDXdfYcAIPHEISHvk9PYfV+cJ6wMBoaN/vhxqibwSuuA7 LYLn8sAiPwKf4GF127CpWAxVBJbHi1rLTjKauuPBV2mdz5JCtQa0CVFO/RT0a3vS1IiLqa 7GzA87fS4RgSQZkWapS0cOaPQTVMv74O17BfGlBhYKNQGGkQMep69HDhHJeWuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1737050896; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=AC2N3Fo7YF4gDnI73YdcDc+RGr/G/dr0h5vttmR+4CQ=; b=UD/GvycrBP/f+qmuk8qc79SVi2jLnYstonfzlNPBOj41PL9XwPDsVZ5/Fpr7CUNwPh7NDF J4w5Voru1Z8hN+8tKD4CnTFKXsGJXN5gDq4EDE06cPlDOZoMHMG+rh359ZFwfISBFGp8/6 lHIU/g1YZ8C37STS59RarwTO6pmJVimPGxCvvE/uOTiFCjPXYWlzCxwEsPIe/mzl+uMp3i tMQBIRqX8F87iXO3HlTJolfMuFipXDDRm4xjQNr61FqRGzZ75r4AKFQKraEuys//3xGFn2 UDl5m2i6u/TvuH8PMLXxVfKWKTUf+YSqSlSbO5fiYnzbWfspVxSwmBCmprMQsg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1737050896; a=rsa-sha256; cv=none; b=GPsdTMCrP5LaTZAdrL0qnnz+6qJQBz/iAmIgxOuy4S4XupJBytKT7GI84mDTNo1YFSTkxp v2ddV1Fnq+W1cJE/CUMTteBzoyhQdPL6jbVhAH+DSJ9g5EL5Ca5PTsIfIfDa61Te8lTYwG MLKoaatOPtMK21CFFyrA8PCRgT9tiBumTK5RRM6Pf2IKLTC7O38/loNhQAxZ0rGggfnKxR O84kE2uh6kfrWxiCnFPkP1MuP+DyuPMCQBCTlYolr65pdPG86f5QNmwrJLVkCJ/aRNO53G 0gJmW3m6/hhUGZXTz58T3OuTP/fH4ulFT1FzBoYVS4ZpMZraKIbW4IQrsnTkyA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YYrSw33LLzk7n; Thu, 16 Jan 2025 18:08:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 50GI8GaL091845; Thu, 16 Jan 2025 18:08:16 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 50GI8G54091842; Thu, 16 Jan 2025 18:08:16 GMT (envelope-from git) Date: Thu, 16 Jan 2025 18:08:16 GMT Message-Id: <202501161808.50GI8G54091842@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Olivier Certner Subject: git: c2bf375d1023 - stable/14 - MAC: syscalls: Split mac_set_proc() into reusable pieces List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: olce X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: c2bf375d102329723f5e2fd45429bc4d92878a51 Auto-Submitted: auto-generated The branch stable/14 has been updated by olce: URL: https://cgit.FreeBSD.org/src/commit/?id=c2bf375d102329723f5e2fd45429bc4d92878a51 commit c2bf375d102329723f5e2fd45429bc4d92878a51 Author: Olivier Certner AuthorDate: 2024-07-27 08:31:16 +0000 Commit: Olivier Certner CommitDate: 2025-01-16 18:06:56 +0000 MAC: syscalls: Split mac_set_proc() into reusable pieces This is in preparation for enabling the new setcred() system call to set a process' MAC label. No functional change (intended). MFC after: 2 weeks Approved by: markj (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46905 (cherry picked from commit 8a4d24a39098ed8170a37ca2aa83bf1da1976de1) --- sys/security/mac/mac_syscalls.c | 115 +++++++++++++++++++++++++++++++++------- sys/security/mac/mac_syscalls.h | 33 ++++++++++++ 2 files changed, 128 insertions(+), 20 deletions(-) diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index 74db8625114e..e97a7dc09700 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -68,6 +68,7 @@ #include #include #include +#include #ifdef MAC @@ -85,7 +86,7 @@ static int kern___mac_set_path(struct thread *td, const char *path_p, * after use by calling free_copied_label() (which see). On success, 'u_string' * if not NULL is filled with the userspace address for 'u_mac->m_string'. */ -static int +int mac_label_copyin(const struct mac *const u_mac, struct mac *const mac, char **const u_string) { @@ -115,7 +116,7 @@ mac_label_copyin(const struct mac *const u_mac, struct mac *const mac, return (0); } -static void +void free_copied_label(const struct mac *const mac) { free(mac->m_string, M_MACTEMP); @@ -183,52 +184,126 @@ sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) return (error); } +/* + * Performs preparation (including allocations) for mac_set_proc(). + * + * No lock should be held while calling this function. On success, + * mac_set_proc_finish() must be called to free the data associated to + * 'mac_set_proc_data', even if mac_set_proc_core() fails. 'mac_set_proc_data' + * is not set in case of error, and is set to a non-NULL value on success. + */ int -sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) +mac_set_proc_prepare(struct thread *const td, const struct mac *const mac, + void **const mac_set_proc_data) { - struct ucred *newcred, *oldcred; struct label *intlabel; - struct proc *p; - struct mac mac; int error; + PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED); + if (!(mac_labeled & MPC_OBJECT_CRED)) return (EINVAL); + intlabel = mac_cred_label_alloc(); + error = mac_cred_internalize_label(intlabel, mac->m_string); + if (error) { + mac_cred_label_free(intlabel); + return (error); + } + + *mac_set_proc_data = intlabel; + return (0); +} + +/* + * Actually sets the MAC label on 'newcred'. + * + * The current process' lock *must* be held. This function only sets the label + * on 'newcred', but does not put 'newcred' in place on the current process' + * (consequently, it also does not call setsugid()). 'mac_set_proc_data' must + * be the pointer returned by mac_set_proc_prepare(). If called, this function + * must be so between a successful call to mac_set_proc_prepare() and + * mac_set_proc_finish(), but calling it is not mandatory (e.g., if some other + * error occured under the process lock that obsoletes setting the MAC label). + */ +int +mac_set_proc_core(struct thread *const td, struct ucred *const newcred, + void *const mac_set_proc_data) +{ + struct label *const intlabel = mac_set_proc_data; + struct proc *const p = td->td_proc; + int error; + + MPASS(td == curthread); + PROC_LOCK_ASSERT(p, MA_OWNED); + + error = mac_cred_check_relabel(p->p_ucred, intlabel); + if (error) + return (error); + + mac_cred_relabel(newcred, intlabel); + return (0); +} + +/* + * Performs mac_set_proc() last operations, without the process lock. + * + * 'proc_label_set' indicates whether the label was actually set by a call to + * mac_set_proc_core() that succeeded. 'mac_set_proc_data' must be the pointer + * returned by mac_set_proc_prepare(), and its associated data will be freed. + */ +void +mac_set_proc_finish(struct thread *const td, bool proc_label_set, + void *const mac_set_proc_data) +{ + struct label *const intlabel = mac_set_proc_data; + + PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED); + + if (proc_label_set) + mac_proc_vm_revoke(td); + mac_cred_label_free(intlabel); +} + +int +sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) +{ + struct ucred *newcred, *oldcred; + void *intlabel; + struct proc *const p = td->td_proc; + struct mac mac; + int error; + error = mac_label_copyin(uap->mac_p, &mac, NULL); if (error) return (error); - intlabel = mac_cred_label_alloc(); - error = mac_cred_internalize_label(intlabel, mac.m_string); - free_copied_label(&mac); + error = mac_set_proc_prepare(td, &mac, &intlabel); if (error) - goto out; + goto free_label; newcred = crget(); - p = td->td_proc; PROC_LOCK(p); oldcred = p->p_ucred; + crcopy(newcred, oldcred); - error = mac_cred_check_relabel(oldcred, intlabel); + error = mac_set_proc_core(td, newcred, intlabel); if (error) { PROC_UNLOCK(p); crfree(newcred); - goto out; + goto finish; } setsugid(p); - crcopy(newcred, oldcred); - mac_cred_relabel(newcred, intlabel); proc_set_cred(p, newcred); - PROC_UNLOCK(p); - crfree(oldcred); - mac_proc_vm_revoke(td); -out: - mac_cred_label_free(intlabel); + crfree(oldcred); +finish: + mac_set_proc_finish(td, error == 0, intlabel); +free_label: + free_copied_label(&mac); return (error); } diff --git a/sys/security/mac/mac_syscalls.h b/sys/security/mac/mac_syscalls.h new file mode 100644 index 000000000000..37445eafe364 --- /dev/null +++ b/sys/security/mac/mac_syscalls.h @@ -0,0 +1,33 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 The FreeBSD Foundation + * + * This software was developed by Olivier Certner at + * Kumacom SARL under sponsorship from the FreeBSD Foundation. + */ + +/* + * Prototypes for functions used to implement system calls that must manipulate + * MAC labels. + */ + +#ifndef _SECURITY_MAC_MAC_SYSCALLS_H_ +#define _SECURITY_MAC_MAC_SYSCALLS_H_ + +#ifndef _KERNEL +#error "no user-serviceable parts inside" +#endif + +int mac_label_copyin(const struct mac *const u_mac, struct mac *const mac, + char **const u_string); +void free_copied_label(const struct mac *const mac); + +int mac_set_proc_prepare(struct thread *const td, + const struct mac *const mac, void **const mac_set_proc_data); +int mac_set_proc_core(struct thread *const td, struct ucred *const newcred, + void *const mac_set_proc_data); +void mac_set_proc_finish(struct thread *const td, bool proc_label_set, + void *const mac_set_proc_data); + +#endif /* !_SECURITY_MAC_MAC_SYSCALLS_H_ */