From nobody Mon Dec 16 14:45:18 2024 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 4YBjR262C3z5hVxx; Mon, 16 Dec 2024 14:45:18 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YBjR21y90z4cQl; Mon, 16 Dec 2024 14:45:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734360318; 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=EtPhipPJ+6SeGM6rioFJumETNlATeckCJKKnaw5lUaE=; b=BMm5QIJ09F961/6Hkf08CIjfue2bnAY9s/Z7kNX0SIAWkUD0p32W4CdjED4ToJY8B5uHgC WpyXIIahwFBB9FN4lk9s9GvSukWr2mihbVmrB2EllLnhPTuyKDVJihfVc9H/9y69zKaSB0 m/esZCB3D/s9fEYI1+ihsij+uXNE1inzsj89VlOoVHXsIlXYf7dbE3M/H/Bgl5gIr4JxwY CuDtJ3r7hxHJjeiKO2KwGTyBbfSvEtTXbS5jMSFisW0SQWkICzUrRsZEDY9mHZwEfctA6w I962XayVXN/BQAhpuA901cpDtzwYGYsAEVdzSB8CXtsYjAR3htsFkW8O0JBtjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734360318; 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=EtPhipPJ+6SeGM6rioFJumETNlATeckCJKKnaw5lUaE=; b=qLb5GM+k5sujGebLjRwRGrvjEvhUimUVGnwsa02YdUHH9jvxIAxERBXc4fwvlB5ixDVrNx Wlp8MMJzPokRSSX3gEhbKeWT33PhkC2A2ZrRHFd+oG908dQac/JdC/Oo+ei4CiU9vh0Bjp HCTJqxEErO6YogyKcyD1Mq7fPdbvynXecwfk0niUS6fVffq2ttgRGnfPJ1TwLBeLxbzORu 9W2JL9w2u+ginGPstXc6CWKQEfbQ+HdMIrn5KTUe/8Mhp1AQw6z1yqh6nz1NW1DP+nuU8+ YjAw+A031RW1DgTZDVxZLZ8POZ52eIORWTq16tN7o0u1lZXtN7GttwPYxqSF4w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1734360318; a=rsa-sha256; cv=none; b=Ao9CALkmuY/cvL/1yi663wbUWj7qjBeHtZtJXBS7avQ7swP+RJKgiJNGRf3rz/9Yu3Ihmw 4O5rv2+8ExQnqIUT+sVS2zcgX5QuwlKGfUJGpAushKGtLuSYXvZaawbFpU6iyZoGKex/1w MoBs0CSBJaEzM7dqzxShiMOXHlt3Ra834AMuWr/SSKBHwj3bvWT6YWdN7W9cV96Q85I1/P qij2TjM0vauWZSgXReVWQNkCv8/E/E7PM4aSbKm41O6StsUqZrm5DADhTlNsYDmtUyhqjk Ulovj4chnQt3mm2VRde3R3OwAHOHCXyCrR9EILq3nfFPTwA3iVRdD/jtLq2OQA== 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 4YBjR21GBczxYH; Mon, 16 Dec 2024 14:45:18 +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 4BGEjIOV051602; Mon, 16 Dec 2024 14:45:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BGEjIw8051599; Mon, 16 Dec 2024 14:45:18 GMT (envelope-from git) Date: Mon, 16 Dec 2024 14:45:18 GMT Message-Id: <202412161445.4BGEjIw8051599@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Olivier Certner Subject: git: 8a4d24a39098 - main - 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/main X-Git-Reftype: branch X-Git-Commit: 8a4d24a39098ed8170a37ca2aa83bf1da1976de1 Auto-Submitted: auto-generated The branch main has been updated by olce: URL: https://cgit.FreeBSD.org/src/commit/?id=8a4d24a39098ed8170a37ca2aa83bf1da1976de1 commit 8a4d24a39098ed8170a37ca2aa83bf1da1976de1 Author: Olivier Certner AuthorDate: 2024-07-27 08:31:16 +0000 Commit: Olivier Certner CommitDate: 2024-12-16 14:42:28 +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 --- 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_ */