From 9de39e08f19baada5abe2e579b65f8937fefaebe Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 29 Jul 2026 21:03:30 +0000 Subject: [PATCH 8/8] Handle pre-10.8 macOS in UnixStream peer credentials Two issues on macOS 10.7-and-earlier SDKs/kernels: - SOL_LOCAL was only added to in the 10.8 SDK. The value has always been 0 on Darwin (and the rest of the BSD family passes a literal 0 as the level for LOCAL_* options), so define it when missing. - LOCAL_PEEREPID is 10.8+: older SDKs lack the definition and older kernels answer ENOPROTOOPT regardless. Upstream invalidated the whole credential when the pid query failed, which would have wrongly turned peerIsOwner() false even though the uid from LOCAL_PEERCRED (present since 10.5 and the only input to the ownership check) was fetched fine. Make the pid lookup best-effort: compile-gate it on LOCAL_PEEREPID and degrade to 0 ("unknown") on failure, which is what every getPeerProcessID() caller already expects for streams without pid information. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01K6JXw8CwYRiXvqHMBGZRgP --- watchman/stream_unix.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/watchman/stream_unix.cpp b/watchman/stream_unix.cpp index 3cc229e..2ae3b3c 100644 --- a/watchman/stream_unix.cpp +++ b/watchman/stream_unix.cpp @@ -21,6 +21,12 @@ #ifdef HAVE_SYS_UCRED_H #include // @manual #endif +#if defined(__APPLE__) && !defined(SOL_LOCAL) +// getsockopt level for LOCAL_* options on unix sockets. Darwin has always +// used 0 (as does the rest of the BSD family), but the SOL_LOCAL name was +// only added to in the 10.8 SDK. +#define SOL_LOCAL 0 +#endif #ifdef HAVE_SYS_SOCKET_H #include // @manual #endif @@ -139,9 +145,18 @@ class UnixStream : public watchman_stream { #endif if (credvalid) { #if defined(__APPLE__) + // The peer pid is informational (see getPeerProcessID); a failure to + // obtain it must not invalidate the credential itself, whose uid + // already drives peerIsOwner. LOCAL_PEEREPID was added in macOS 10.8: + // older SDKs lack the definition, and older kernels answer + // ENOPROTOOPT even if we define it ourselves. + epid = 0; +#ifdef LOCAL_PEEREPID len = sizeof(epid); - credvalid = - getsockopt(fd.fd(), SOL_LOCAL, LOCAL_PEEREPID, &epid, &len) == 0; + if (getsockopt(fd.fd(), SOL_LOCAL, LOCAL_PEEREPID, &epid, &len) != 0) { + epid = 0; + } +#endif #elif defined(__FreeBSD__) epid = cred.cr_pid; #else