os: Update GetLocalClientCreds to prefer getpeerucred() or SO_PEERCRED over getpeereid()

GetLocalClientCreds() was preferring getpeereid() above other implementations.

getpeereid(), however, only returns the effective uid and gid of the peer,
leaving the pid unset.  When this happens, we are unable to use the pid to
determine the peer's command line arguments and incorrectly treat ssh-tunneled
traffic as local.

To address this, we now prioritize getpeerucred() or SO_PEERCRED as those two
implementations will return the pid in addition to uid and gid.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 165d5c1260)
This commit is contained in:
Jeremy Huddleston Sequoia 2023-01-18 12:02:54 -08:00
parent a220f53cb8
commit a6c49106ce

View File

@ -1167,15 +1167,15 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
XtransConnInfo ci; XtransConnInfo ci;
LocalClientCredRec *lcc; LocalClientCredRec *lcc;
#ifdef HAVE_GETPEEREID #if defined(HAVE_GETPEERUCRED)
uid_t uid;
gid_t gid;
#elif defined(HAVE_GETPEERUCRED)
ucred_t *peercred = NULL; ucred_t *peercred = NULL;
const gid_t *gids; const gid_t *gids;
#elif defined(SO_PEERCRED) #elif defined(SO_PEERCRED)
struct ucred peercred; struct ucred peercred;
socklen_t so_len = sizeof(peercred); socklen_t so_len = sizeof(peercred);
#elif defined(HAVE_GETPEEREID)
uid_t uid;
gid_t gid;
#endif #endif
if (client == NULL) if (client == NULL)
@ -1197,16 +1197,7 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
lcc = *lccp; lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci); fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAVE_GETPEEREID #if defined(HAVE_GETPEERUCRED)
if (getpeereid(fd, &uid, &gid) == -1) {
FreeLocalClientCreds(lcc);
return -1;
}
lcc->euid = uid;
lcc->egid = gid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0;
#elif defined(HAVE_GETPEERUCRED)
if (getpeerucred(fd, &peercred) < 0) { if (getpeerucred(fd, &peercred) < 0) {
FreeLocalClientCreds(lcc); FreeLocalClientCreds(lcc);
return -1; return -1;
@ -1254,6 +1245,15 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
lcc->pid = peercred.pid; lcc->pid = peercred.pid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET; lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0; return 0;
#elif defined(HAVE_GETPEEREID)
if (getpeereid(fd, &uid, &gid) == -1) {
FreeLocalClientCreds(lcc);
return -1;
}
lcc->euid = uid;
lcc->egid = gid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0;
#endif #endif
#else #else
/* No system call available to get the credentials of the peer */ /* No system call available to get the credentials of the peer */