Bug 294833 - LOCAL_PEERCRED does not return cr_pid in 32-bit compat mode
Summary: LOCAL_PEERCRED does not return cr_pid in 32-bit compat mode
Status: In Progress
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 15.0-RELEASE
Hardware: Any Any
: --- Affects Only Me
Assignee: Alan Somers
URL: https://reviews.freebsd.org/D56675
Keywords:
Depends on:
Blocks:
 
Reported: 2026-04-27 22:27 UTC by Alan Somers
Modified: 2026-06-11 20:11 UTC (History)
1 user (show)

See Also:
asomers: mfc-stable14?


Attachments
testcase (1.94 KB, text/plain)
2026-04-27 22:28 UTC, Alan Somers
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alan Somers freebsd_committer freebsd_triage 2026-04-27 22:27:28 UTC
Background
==========

The LOCAL_PEERCRED sockopt is supposed to return the credentials of the process that owns the peer side of a connection-oriented unix domain socket.  It returns the peer's UID, GID, supplementary group list (up to 16), and pid.

Problem
=======

When the sockopt is fetched by a 32-bit process running on a 64-bit kernel, the structure's size is defined differently for the process than it is for the kernel.  The kernel fails to check that, and populates the structure as if it were the 64-bit version.  The problem is the anonymous union in struct xucred that contains a pointer.  The userspace process thinks that the union is 4 bytes large, but the kernel things that it's 8-bytes large.  As a result, the kernel will always populate the cr_pid field with 0.

Steps to Reproduce
==================

Build and run the attached program on a 64-bit host:

$ cc -m32 -o LOCAL_PEERCRED -Wall LOCAL_PEERCRED.c
$ ./LOCAL_PEERCRED
sizeof(struct xucred)=0x50
My pid = 0x192c
cr_uid=1000 cr_gid=1000 cr_pid=0
0000: 0000 0000 03e8 0000 0008 0000 03e8 0000
0010: 0000 0000 0005 0000 000d 0000 002c 0000
0020: 0074 0000 01be 0000 03e8 0000 0000 0000
0030: 0000 0000 0000 0000 0000 0000 0000 0000
0040: 0000 0000 0000 0000 0000 0000 0000 0000
0050: 192c 0000 0000 0000 c952 2059 0001 0000

Note that the kernel returns the correct pid (0x192c), but it returns it at offset 0x50, which is beyond the end of the xucred struct.
Comment 1 Alan Somers freebsd_committer freebsd_triage 2026-04-27 22:28:35 UTC
Created attachment 270193 [details]
testcase
Comment 2 commit-hook freebsd_committer freebsd_triage 2026-05-07 21:07:21 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=1d24638d3e8875e4b99a4b5e39f4241e37221b3d

commit 1d24638d3e8875e4b99a4b5e39f4241e37221b3d
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2026-04-27 23:46:53 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2026-05-07 20:52:35 +0000

    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

 sys/kern/uipc_usrreq.c | 21 +++++++++++++++++++--
 sys/sys/ucred.h        | 11 +++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
Comment 3 commit-hook freebsd_committer freebsd_triage 2026-05-13 17:23:34 UTC
A commit in branch stable/15 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=3298d82ea34059354dc1ff1a60d8b7d3e495c2cd

commit 3298d82ea34059354dc1ff1a60d8b7d3e495c2cd
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2026-04-27 23:46:53 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2026-05-13 16:54:53 +0000

    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
    Reviewed by:    emaste
    Differential Revision: https://reviews.freebsd.org/D56675

    (cherry picked from commit 1d24638d3e8875e4b99a4b5e39f4241e37221b3d)

 sys/kern/uipc_usrreq.c | 21 +++++++++++++++++++--
 sys/sys/ucred.h        | 11 +++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
Comment 4 commit-hook freebsd_committer freebsd_triage 2026-05-14 19:05:46 UTC
A commit in branch releng/15.1 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=39fcfcc64bbae6ff8792c8598c6147e3c63b60c1

commit 39fcfcc64bbae6ff8792c8598c6147e3c63b60c1
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2026-04-27 23:46:53 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2026-05-14 19:04:38 +0000

    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.

    Approved by:    re (cperciva)
    PR:             294833
    Sponsored by:   ConnectWise
    Reviewed by:    emaste
    Differential Revision: https://reviews.freebsd.org/D56675

    (cherry picked from commit 1d24638d3e8875e4b99a4b5e39f4241e37221b3d)
    (cherry picked from commit 3298d82ea34059354dc1ff1a60d8b7d3e495c2cd)

 sys/kern/uipc_usrreq.c | 21 +++++++++++++++++++--
 sys/sys/ucred.h        | 11 +++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)