From nobody Tue Jan 6 13:34:30 2026 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 4dlsbC1pktz6NddJ for ; Tue, 06 Jan 2026 13:34:31 +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 "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dlsbB68q7z3T7t for ; Tue, 06 Jan 2026 13:34:30 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1767706470; 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=HxycPTC5NrzB3WaRCPUkKz16nuKwsoW44DhvMiyscKk=; b=XK4N2oYurzxGXhBgiS2dATXG/vGrAQJelPUKEQWqujGoT2KmJa79+UYKdzb4rLG6I4HGut 4yhurpggujKNi9Kym7kVj95KE1MVZhDaGE3X2npj3P8AHJW9qmNOn2Pdx+VIDg2SOjh7wm BgEMXKTsmhY8Sf6g/PmTuuRye2w2OVJV6UkIKm9mkbhVUCw/KklIRGwiHTOY9nbjIlFCeO 06xm5mKrz1eKh8+P01EENRahvavI7zVDWqhpbtboHisddLb99s5GHguuxtcbdmgNxqu8NB g9KLEgCUZ39UIQbExi+JNFLSyGC+nQw7g2b++FUE+urJfZbBiauNC+Mjzn6dqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1767706470; 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=HxycPTC5NrzB3WaRCPUkKz16nuKwsoW44DhvMiyscKk=; b=SPqTrPcOdfxDM5oIu5Jz6iZsBVwWW7JrCz4/VY062vqNrHkHaH28tOyxtSnIudJVtb36uK v+ONuiOJj54Onuc68G29JgbDbYzkVZbEvYWf0RWggs3RUXA1mzfuedM6TA/jAXU5xoG+7T uzb87NWeSE+c8sYwykzFuE4cTiozK1u/UvfUF7trf1dtGbZtLGQP9YMfA1BOD3RWxgwkl0 YRPRUl3Pb54VMP0fUKvd7rMgKCGQ65Ld8bx8kcpbAgwYSZhBvfoeR1oNLaS5OHmmJ8ulEU nh4fS7a1Oxv0tBKkgj9urn60rpyf3Fd1GH5ap/pA/vHqB9vEBR+6NgXCsE9bgQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1767706470; a=rsa-sha256; cv=none; b=ml9W6H9ZsZLIb5dT54O0uPdFnA8LNHRhur1OoEfz1nrNw3pBNVtV2roBh8jq+6udj+iORn 7AElbvTgH1Vo9Zv2OS7lzD3Zcj7J3lD7QG4Bm6bO9qawGCFGlEgZ03aiNIXW253zWvwhcA CDPHEvHuMnNAC4XiOSVaPGwDZR9bUU5YlZPHg0/L4MU1wtEfoNKVdy33ta2YIpnSoD7maa czpNDij+C7CkEnAmCr0B4NW5A2yvtplxzuqCvZRZ93Wrqgx8CjFU8YQloLUWCj6+SZ1JdZ O0mf5FP3r6W7jvDEK2i57eyUiqfgs4Auw5VO0pLQJ2319pOMXyWHSJb5jPq3lA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dlsbB5PqJz17XJ for ; Tue, 06 Jan 2026 13:34:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e463 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 06 Jan 2026 13:34:30 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Olivier Certner Subject: git: b6cba9028457 - stable/15 - setcred(): Remove an optimization for when cr_groups[0] was the egid 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/15 X-Git-Reftype: branch X-Git-Commit: b6cba9028457f938e2db403134415d843a1d79a4 Auto-Submitted: auto-generated Date: Tue, 06 Jan 2026 13:34:30 +0000 Message-Id: <695d0f66.3e463.69fdbd28@gitrepo.freebsd.org> The branch stable/15 has been updated by olce: URL: https://cgit.FreeBSD.org/src/commit/?id=b6cba9028457f938e2db403134415d843a1d79a4 commit b6cba9028457f938e2db403134415d843a1d79a4 Author: Olivier Certner AuthorDate: 2025-11-14 18:22:53 +0000 Commit: Olivier Certner CommitDate: 2026-01-06 13:33:25 +0000 setcred(): Remove an optimization for when cr_groups[0] was the egid Because setcred() has (always) treated the effective GID separately from the supplementary groups, when cr_groups[0] was storing the effective GID, it internally needed to build an array containing both the effective GID and the specified supplementary groups to eventually call crsetgroups_internal(). As kern_setcred() was only used to actually implement user_setcred()/sys_setcred(), which need to allocate a buffer to copy in the userland groups array into, some optimization was put in place where these would allocate an array with one more element than 'wc_supp_groups', copyin() the latter into the subarray starting at index 1 and pass the pointer to the whole array to kern_setcred() in 'preallocated_groups'. This would allow kern_setcred() not to have to allocate memory again to make room for the additional effective GID. Since commit be1f7435ef21 ("kern: start tracking cr_gid outside of cr_groups[]"), crsetgroups_internal() only takes supplementary groups, so this machinery has become obsolete. It was not removed as part of that commit, but just minimally amended to simplify the changes and lower the risks. Finally remove it. Reviewed by: kevans MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D53772 (cherry picked from commit 4cd93df95e697942adf0ff038fc8f357cbb07cf9) --- sys/kern/kern_prot.c | 112 ++++++++++++++++++++------------------------------ sys/sys/syscallsubr.h | 2 +- 2 files changed, 46 insertions(+), 68 deletions(-) diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 8021beed90e8..34d68927be71 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -526,44 +526,44 @@ gidp_cmp(const void *p1, const void *p2) } /* - * Final storage for supplementary groups will be returned via 'groups'. - * '*groups' must be NULL on input, and if not equal to 'smallgroups' - * on output, must be freed (M_TEMP) *even if* an error is returned. + * 'smallgroups' must be an (uninitialized) array of length CRED_SMALLGROUPS_NB. + * Always sets 'sc_supp_groups', either to a valid kernel-space groups array + * (which may or may not be 'smallgroups'), or NULL if SETCREDF_SUPP_GROUPS was + * not specified, or a buffer containing garbage on copyin() failure. In the + * last two cases, 'sc_supp_groups_nb' is additionally set to 0 as a security + * measure. 'sc_supp_groups' must be freed (M_TEMP) if not equal to + * 'smallgroups' even on failure. */ static int kern_setcred_copyin_supp_groups(struct setcred *const wcred, - const u_int flags, gid_t *const smallgroups, gid_t **const groups) + const u_int flags, gid_t *const smallgroups) { - MPASS(*groups == NULL); + gid_t *groups; + int error; - if (flags & SETCREDF_SUPP_GROUPS) { - int error; + if ((flags & SETCREDF_SUPP_GROUPS) == 0) { + wcred->sc_supp_groups_nb = 0; + wcred->sc_supp_groups = NULL; + return (0); + } - /* - * Check for the limit for number of groups right now in order - * to limit the amount of bytes to copy. - */ - if (wcred->sc_supp_groups_nb > ngroups_max) - return (EINVAL); + /* + * Check the number of groups' limit right now in order to limit the + * amount of bytes to copy. + */ + if (wcred->sc_supp_groups_nb > ngroups_max) + return (EINVAL); - /* - * Since we are going to be copying the supplementary groups - * from userland, make room also for the effective GID right - * now, to avoid having to allocate and copy again the - * supplementary groups. - */ - *groups = wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB ? - smallgroups : malloc(wcred->sc_supp_groups_nb * - sizeof(*groups), M_TEMP, M_WAITOK); + groups = wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB ? + smallgroups : malloc(wcred->sc_supp_groups_nb * sizeof(gid_t), + M_TEMP, M_WAITOK); - error = copyin(wcred->sc_supp_groups, *groups, - wcred->sc_supp_groups_nb * sizeof(*groups)); - if (error != 0) - return (error); - wcred->sc_supp_groups = *groups; - } else { + error = copyin(wcred->sc_supp_groups, groups, + wcred->sc_supp_groups_nb * sizeof(gid_t)); + wcred->sc_supp_groups = groups; + if (error != 0) { wcred->sc_supp_groups_nb = 0; - wcred->sc_supp_groups = NULL; + return (error); } return (0); @@ -578,7 +578,6 @@ user_setcred(struct thread *td, const u_int flags, struct setcred *const wcred) void *umac; #endif gid_t smallgroups[CRED_SMALLGROUPS_NB]; - gid_t *groups = NULL; int error; /* @@ -602,8 +601,7 @@ user_setcred(struct thread *td, const u_int flags, struct setcred *const wcred) * alternative for 32-bit compatibility as 'gid_t' has the same size * everywhere. */ - error = kern_setcred_copyin_supp_groups(wcred, flags, smallgroups, - &groups); + error = kern_setcred_copyin_supp_groups(wcred, flags, smallgroups); if (error != 0) goto free_groups; @@ -616,7 +614,7 @@ user_setcred(struct thread *td, const u_int flags, struct setcred *const wcred) } #endif - error = kern_setcred(td, flags, wcred, groups); + error = kern_setcred(td, flags, wcred); #ifdef MAC if (wcred->sc_label != NULL) @@ -624,8 +622,8 @@ user_setcred(struct thread *td, const u_int flags, struct setcred *const wcred) #endif free_groups: - if (groups != smallgroups) - free(groups, M_TEMP); + if (wcred->sc_supp_groups != smallgroups) + free(wcred->sc_supp_groups, M_TEMP); return (error); } @@ -654,24 +652,18 @@ sys_setcred(struct thread *td, struct setcred_args *uap) /* * CAUTION: This function normalizes groups in 'wcred'. - * - * If 'preallocated_groups' is non-NULL, it must be an already allocated array - * of size 'wcred->sc_supp_groups_nb' containing the supplementary groups, and - * 'wcred->sc_supp_groups' then must point to it. */ int kern_setcred(struct thread *const td, const u_int flags, - struct setcred *const wcred, gid_t *preallocated_groups) + struct setcred *const wcred) { struct proc *const p = td->td_proc; - struct ucred *new_cred, *old_cred, *to_free_cred; + struct ucred *new_cred, *old_cred, *to_free_cred = NULL; struct uidinfo *uip = NULL, *ruip = NULL; #ifdef MAC void *mac_set_proc_data = NULL; bool proc_label_set = false; #endif - gid_t *groups = NULL; - gid_t smallgroups[CRED_SMALLGROUPS_NB]; int error; bool cred_set = false; @@ -683,32 +675,18 @@ kern_setcred(struct thread *const td, const u_int flags, * Part 1: We allocate and perform preparatory operations with no locks. */ - if (flags & SETCREDF_SUPP_GROUPS) { - if (wcred->sc_supp_groups_nb > ngroups_max) + if ((flags & SETCREDF_SUPP_GROUPS) != 0 && + wcred->sc_supp_groups_nb > ngroups_max) return (EINVAL); - if (preallocated_groups != NULL) { - groups = preallocated_groups; - MPASS(preallocated_groups == wcred->sc_supp_groups); - } else { - if (wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB) - groups = smallgroups; - else - groups = malloc(wcred->sc_supp_groups_nb * - sizeof(*groups), M_TEMP, M_WAITOK); - memcpy(groups, wcred->sc_supp_groups, - wcred->sc_supp_groups_nb * sizeof(*groups)); - } - } if (flags & SETCREDF_MAC_LABEL) { #ifdef MAC error = mac_set_proc_prepare(td, wcred->sc_label, &mac_set_proc_data); if (error != 0) - goto free_groups; + return (error); #else - error = ENOTSUP; - goto free_groups; + return (ENOTSUP); #endif } @@ -734,8 +712,10 @@ kern_setcred(struct thread *const td, const u_int flags, * Output the raw supplementary groups array for better * traceability. */ - AUDIT_ARG_GROUPSET(groups, wcred->sc_supp_groups_nb); - groups_normalize(&wcred->sc_supp_groups_nb, groups); + AUDIT_ARG_GROUPSET(wcred->sc_supp_groups, + wcred->sc_supp_groups_nb); + groups_normalize(&wcred->sc_supp_groups_nb, + wcred->sc_supp_groups); } /* @@ -776,7 +756,7 @@ kern_setcred(struct thread *const td, const u_int flags, */ if (flags & SETCREDF_SUPP_GROUPS) crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb, - groups); + wcred->sc_supp_groups); if (flags & SETCREDF_GID) change_egid(new_cred, wcred->sc_gid); if (flags & SETCREDF_RGID) @@ -863,9 +843,7 @@ unlock_finish: uifree(uip); if (ruip != NULL) uifree(ruip); -free_groups: - if (groups != preallocated_groups && groups != smallgroups) - free(groups, M_TEMP); /* Deals with 'groups' being NULL. */ + return (error); } diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index d32690634059..5acce75e3302 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -325,7 +325,7 @@ int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, struct mbuf *control, enum uio_seg segflg); int kern_setcred(struct thread *const td, const u_int flags, - struct setcred *const wcred, gid_t *preallocated_groups); + struct setcred *const wcred); int kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups); int kern_setitimer(struct thread *, u_int, struct itimerval *, struct itimerval *);