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
This commit is contained in:
Alan Somers
2026-04-27 17:46:53 -06:00
parent 8eef59db25
commit 1d24638d3e
2 changed files with 30 additions and 2 deletions
+19 -2
View File
@@ -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:
+11
View File
@@ -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. */