Skip to content

Commit

Permalink
expose the client pid in our stream layer
Browse files Browse the repository at this point in the history
Summary:
While troubleshooting the source of some queries it is valuable to be
able to determine the process id of the peer, so add a method that returns the
pid of the peer if known.

We already had code to query the peer credentials on Linux and Mac, so this
just moves it to the constructor and makes the existing ownership check
a simple accessor for that that, then adds a method to return the process
ID from that same state.

Reviewed By: sid0

Differential Revision: D4282299

fbshipit-source-id: fcfa7a10723d088b4a33a756110933dc39ee0605
  • Loading branch information
wez authored and Facebook Github Bot committed Dec 8, 2016
1 parent 3416273 commit c5d14f1
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
4 changes: 4 additions & 0 deletions stream_stdout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class StdioStream : public watchman_stream {
return false;
}

pid_t getPeerProcessID() const override {
return 0;
}

#ifndef _WIN32
int getFileDescriptor() const override {
return fd;
Expand Down
49 changes: 33 additions & 16 deletions stream_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,23 @@ class UnixStream : public watchman_stream {
public:
FileDescriptor fd;
FakeSocketEvent evt;
#ifdef SO_PEERCRED
struct ucred cred;
#elif defined(LOCAL_PEERCRED)
struct xucred cred;
#endif
bool credvalid{false};

explicit UnixStream(FileDescriptor&& descriptor)
: fd(std::move(descriptor)), evt(fd.fd()) {}
: fd(std::move(descriptor)), evt(fd.fd()) {
socklen_t len = sizeof(cred);
#ifdef SO_PEERCRED
credvalid = getsockopt(fd.fd(), SOL_SOCKET, SO_PEERCRED, &cred, &len) == 0;
#elif defined(LOCAL_PEERCRED)
credvalid =
getsockopt(fd.fd(), SOL_LOCAL, LOCAL_PEERCRED, &cred, &len) == 0;
#endif
}

int getFileDescriptor() const override {
return fd.fd();
Expand Down Expand Up @@ -138,28 +152,31 @@ class UnixStream : public watchman_stream {
// mechanisms. We'll treat the other process as an owner if their
// effective UID matches ours, or if they are root.
bool peerIsOwner() override {
if (!credvalid) {
return false;
}
#ifdef SO_PEERCRED
struct ucred cred;
socklen_t len = sizeof(cred);

if (getsockopt(fd.fd(), SOL_SOCKET, SO_PEERCRED, &cred, &len) == 0) {
if (cred.uid == getuid() || cred.uid == 0) {
return true;
}
if (cred.uid == getuid() || cred.uid == 0) {
return true;
}
#elif defined(LOCAL_PEERCRED)
struct xucred cred;
socklen_t len = sizeof(cred);

if (getsockopt(fd.fd(), SOL_LOCAL, LOCAL_PEERCRED, &cred, &len) == 0) {
if (cred.cr_uid == getuid() || cred.cr_uid == 0) {
return true;
}
if (cred.cr_uid == getuid() || cred.cr_uid == 0) {
return true;
}
#endif

return false;
}

pid_t getPeerProcessID() const override {
if (!credvalid) {
return 0;
}
#ifdef SO_PEERCRED
return cred.pid;
#else
return 0;
#endif
}
};
}

Expand Down
4 changes: 4 additions & 0 deletions stream_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class win_handle : public watchman_stream {
inline HANDLE handle() const {
return (HANDLE)h.handle();
}

pid_t getPeerProcessID() const override {
return 0;
}
};

#if 1
Expand Down
1 change: 1 addition & 0 deletions watchman_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class watchman_stream {
virtual bool rewind() = 0;
virtual bool shutdown() = 0;
virtual bool peerIsOwner() = 0;
virtual pid_t getPeerProcessID() const = 0;
#ifndef _WIN32
virtual int getFileDescriptor() const = 0;
#else
Expand Down

0 comments on commit c5d14f1

Please sign in to comment.