From 2f84aa3d20d4537f350521f3ac83912678e08bd8 Mon Sep 17 00:00:00 2001 From: "Theodor S. Midtlien" Date: Thu, 23 Jul 2026 19:37:37 +0200 Subject: [PATCH] Remove PID from Identity --- client/internal/ipcauth/creds_windows.go | 9 +-------- client/internal/ipcauth/forward.go | 13 +------------ client/internal/ipcauth/identity.go | 11 ----------- client/internal/ipcauth/identity_test.go | 2 +- client/internal/ipcauth/peercred_bsd.go | 3 +-- client/internal/ipcauth/peercred_linux.go | 6 ++---- 6 files changed, 6 insertions(+), 38 deletions(-) diff --git a/client/internal/ipcauth/creds_windows.go b/client/internal/ipcauth/creds_windows.go index 3ef43da75..6151a050d 100644 --- a/client/internal/ipcauth/creds_windows.go +++ b/client/internal/ipcauth/creds_windows.go @@ -31,11 +31,6 @@ func DefaultPipeSDDL() string { // NewTransportCredentials returns gRPC transport credentials that derive the // caller's identity from the named-pipe client token. // -// It uses ImpersonateNamedPipeClient, which binds the client's security context -// to the *connection* in the kernel — there is no PID lookup, so it is immune to -// the PID-reuse race that OpenProcess-by-PID would have. Per threat-model -// M-NOIMP, impersonation is used only to read the client token, then reverted -// immediately; the daemon never performs privileged work while impersonating. // This requires the client to dial at SECURITY_IDENTIFICATION (see dialNamedPipe). func NewTransportCredentials() credentials.TransportCredentials { return winpipeCreds{} @@ -77,8 +72,7 @@ func (winpipeCreds) OverrideServerName(string) error { return nil } // pipeClientIdentity reads the connecting client's user SID, enabled group SIDs, // and elevation by impersonating the pipe client on this thread and reading the -// impersonation token. Impersonation is connection-bound (no PID race) and the -// window is kept minimal and pinned to the OS thread (impersonation is thread-local). +// impersonation token. func pipeClientIdentity(handle windows.Handle) (id Identity, err error) { runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -123,7 +117,6 @@ func pipeClientIdentity(handle windows.Handle) (id Identity, err error) { SID: tu.User.Sid.String(), Groups: groups, Elevated: token.IsElevated(), - HasPID: false, }, nil } diff --git a/client/internal/ipcauth/forward.go b/client/internal/ipcauth/forward.go index b03de150d..c1b932040 100644 --- a/client/internal/ipcauth/forward.go +++ b/client/internal/ipcauth/forward.go @@ -14,7 +14,6 @@ import ( const ( mdFwdUID = "x-netbird-fwd-uid" mdFwdGID = "x-netbird-fwd-gid" - mdFwdPID = "x-netbird-fwd-pid" ) // ForwardIdentityMetadata encodes a Unix identity for the gateway to forward to @@ -24,14 +23,10 @@ func ForwardIdentityMetadata(id Identity) metadata.MD { if id.IsWindows() { return nil } - md := metadata.Pairs( + return metadata.Pairs( mdFwdUID, strconv.FormatUint(uint64(id.UID), 10), mdFwdGID, strconv.FormatUint(uint64(id.GID), 10), ) - if id.HasPID { - md.Set(mdFwdPID, strconv.FormatInt(int64(id.PID), 10)) - } - return md } // forwardedIdentity extracts a forwarded Unix identity from incoming gRPC @@ -55,12 +50,6 @@ func forwardedIdentity(ctx context.Context) (Identity, bool) { id.GID = uint32(v) } } - if p := mdFirst(md, mdFwdPID); p != "" { - if v, err := strconv.ParseInt(p, 10, 32); err == nil { - id.PID = int32(v) - id.HasPID = true - } - } return id, true } diff --git a/client/internal/ipcauth/identity.go b/client/internal/ipcauth/identity.go index 0260362c5..fb7de1513 100644 --- a/client/internal/ipcauth/identity.go +++ b/client/internal/ipcauth/identity.go @@ -29,11 +29,6 @@ type Identity struct { UID uint32 GID uint32 - // PID is the caller's process ID, for audit only. HasPID is false when the - // platform cannot supply it (e.g. Darwin/FreeBSD xucred carries no PID). - PID int32 - HasPID bool - // SID is the caller's Windows security identifier (empty on Unix). SID string @@ -68,14 +63,8 @@ func (i Identity) IsPrivileged() bool { // String renders the identity for audit logs. func (i Identity) String() string { if i.IsWindows() { - if i.HasPID { - return fmt.Sprintf("sid=%s elevated=%t pid=%d", i.SID, i.Elevated, i.PID) - } return fmt.Sprintf("sid=%s elevated=%t", i.SID, i.Elevated) } - if i.HasPID { - return fmt.Sprintf("uid=%d gid=%d pid=%d", i.UID, i.GID, i.PID) - } return fmt.Sprintf("uid=%d gid=%d", i.UID, i.GID) } diff --git a/client/internal/ipcauth/identity_test.go b/client/internal/ipcauth/identity_test.go index 61ac84cfe..7b69ddd24 100644 --- a/client/internal/ipcauth/identity_test.go +++ b/client/internal/ipcauth/identity_test.go @@ -21,7 +21,7 @@ func TestIdentityFromContext_WrongAuthInfo(t *testing.T) { } func TestIdentityFromContext_Present(t *testing.T) { - want := Identity{UID: 1000, GID: 1000, PID: 4242, HasPID: true} + want := Identity{UID: 1000, GID: 1000} ctx := peer.NewContext(context.Background(), &peer.Peer{ AuthInfo: AuthInfo{ CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.NoSecurity}, diff --git a/client/internal/ipcauth/peercred_bsd.go b/client/internal/ipcauth/peercred_bsd.go index 178c7a17e..636f4ebf6 100644 --- a/client/internal/ipcauth/peercred_bsd.go +++ b/client/internal/ipcauth/peercred_bsd.go @@ -11,8 +11,7 @@ import ( // PeerIdentity reads the kernel-authenticated identity of the process on the // other end of a Unix socket connection via LOCAL_PEERCRED (xucred). xucred -// carries the uid and group list but no pid, so audit on these platforms is -// uid/gid-based (HasPID is false); PID via LOCAL_PEERPID is a possible follow-up. +// carries the uid and primary group. func PeerIdentity(c net.Conn) (Identity, error) { uc, ok := c.(*net.UnixConn) if !ok { diff --git a/client/internal/ipcauth/peercred_linux.go b/client/internal/ipcauth/peercred_linux.go index 8c9e01b8e..8b419f7b7 100644 --- a/client/internal/ipcauth/peercred_linux.go +++ b/client/internal/ipcauth/peercred_linux.go @@ -35,9 +35,7 @@ func PeerIdentity(c net.Conn) (Identity, error) { } return Identity{ - UID: cred.Uid, - GID: cred.Gid, - PID: cred.Pid, - HasPID: true, + UID: cred.Uid, + GID: cred.Gid, }, nil }