summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston Sequoia <jeremyhu@apple.com>2023-01-18 12:02:54 -0800
committerJeremy Huddleston Sequoia <jeremyhu@apple.com>2023-01-26 17:51:16 +0000
commit165d5c1260edcb998c5cf31d3969723c7452aa7f (patch)
treef77b0b3acae1e1a81485d81086e8d1a29bc088ee
parent2577291f010e07173d0fc8b310ac355928f8ed7d (diff)
downloadxserver-165d5c1260edcb998c5cf31d3969723c7452aa7f.tar.gz
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>
-rw-r--r--os/access.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/os/access.c b/os/access.c
index b1703048d..debf4c741 100644
--- a/os/access.c
+++ b/os/access.c
@@ -1167,15 +1167,15 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
XtransConnInfo ci;
LocalClientCredRec *lcc;
-#ifdef HAVE_GETPEEREID
- uid_t uid;
- gid_t gid;
-#elif defined(HAVE_GETPEERUCRED)
+#if defined(HAVE_GETPEERUCRED)
ucred_t *peercred = NULL;
const gid_t *gids;
#elif defined(SO_PEERCRED)
struct ucred peercred;
socklen_t so_len = sizeof(peercred);
+#elif defined(HAVE_GETPEEREID)
+ uid_t uid;
+ gid_t gid;
#endif
if (client == NULL)
@@ -1197,16 +1197,7 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci);
-#ifdef 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;
-#elif defined(HAVE_GETPEERUCRED)
+#if defined(HAVE_GETPEERUCRED)
if (getpeerucred(fd, &peercred) < 0) {
FreeLocalClientCreds(lcc);
return -1;
@@ -1254,6 +1245,15 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
lcc->pid = peercred.pid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
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
#else
/* No system call available to get the credentials of the peer */