diff options
| author | Alan Somers <asomers@FreeBSD.org> | 2026-04-27 23:46:53 +0000 |
|---|---|---|
| committer | Alan Somers <asomers@FreeBSD.org> | 2026-05-07 20:52:35 +0000 |
| commit | 1d24638d3e8875e4b99a4b5e39f4241e37221b3d (patch) | |
| tree | 1756517e46f40bfefa45bf872eff9d9f01ddfa7a | |
| parent | 8eef59db254283eaaee47be94d4ea9f2fef4f2ad (diff) | |
Fix LOCAL_PEERCRED in 32-bit compat mode
Previously the cr_pid field would be incorrectly copied to userland, due
to a size mismatch between the structure as defined in 32-bit vs 64-bit
builds. Fix it by converting the structure before copying it to
userland.
PR: 294833
Sponsored by: ConnectWise
MFC after: 1 week
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D56675
| -rw-r--r-- | sys/kern/uipc_usrreq.c | 21 | ||||
| -rw-r--r-- | sys/sys/ucred.h | 11 |
2 files changed, 30 insertions, 2 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 8ff9822ee9eb..2508f7edd1c5 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -83,6 +83,7 @@ #include <sys/socketvar.h> #include <sys/signalvar.h> #include <sys/stat.h> +#include <sys/sysent.h> #include <sys/sx.h> #include <sys/sysctl.h> #include <sys/systm.h> @@ -2752,8 +2753,24 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) error = EINVAL; } UNP_PCB_UNLOCK(unp); - if (error == 0) - error = sooptcopyout(sopt, &xu, sizeof(xu)); + if (error != 0) + break; +#ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(sopt->sopt_td->td_proc, SV_ILP32)) { + struct xucred32 xu32 = {}; + int i; + + xu32.cr_version = xu.cr_version; + xu32.cr_uid = xu.cr_uid; + xu32.cr_ngroups = xu.cr_ngroups; + for (i = 0; i < XU_NGROUPS; i++) + xu32.cr_groups[i] = xu.cr_groups[i]; + xu32.cr_pid = xu.cr_pid; + error = sooptcopyout(sopt, &xu32, sizeof(xu32)); + break; + } +#endif + error = sooptcopyout(sopt, &xu, sizeof(xu)); break; case LOCAL_CREDS: diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index ba241cf9ff3a..4bf48a5e4b87 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -193,6 +193,17 @@ struct setcred32 { uint32_t sc_label; /* struct mac32 [*] */ }; +#ifdef COMPAT_FREEBSD32 +/* 32-bit compatible version of xucred */ +struct xucred32 { + u_int cr_version; /* structure layout version */ + uid_t cr_uid; /* effective user id */ + short cr_ngroups; /* number of groups (incl. cr_gid). */ + gid_t cr_groups[XU_NGROUPS]; /* groups */ + pid_t cr_pid; +}; +#endif + struct thread; /* Common native and 32-bit compatibility entry point. */ |
