From 7e615369920e5297d902e3bd6e7b9da5251fc3a1 Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Fri, 18 Apr 2025 17:23:59 +0300 Subject: [PATCH] [desktop] Portmaster UI process detection (including child processes) --- service/process/profile.go | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/service/process/profile.go b/service/process/profile.go index e97b1d01..7653bd72 100644 --- a/service/process/profile.go +++ b/service/process/profile.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "path/filepath" "runtime" "strings" @@ -72,7 +73,7 @@ func (p *Process) getSpecialProfileID() (specialProfileID string) { specialProfileID = profile.PortmasterProfileID default: // Check if this is another Portmaster component. - if module.portmasterUIPath != "" && p.Path == module.portmasterUIPath { + if p.IsPortmasterUi(context.Background()) { specialProfileID = profile.PortmasterAppProfileID } // Check if this is the system resolver. @@ -104,3 +105,37 @@ func (p *Process) getSpecialProfileID() (specialProfileID string) { return specialProfileID } + +// IsPortmasterUi checks if the process is the Portmaster UI or its child (up to 3 parent levels). +func (p *Process) IsPortmasterUi(ctx context.Context) bool { + if module.portmasterUIPath == "" { + return false + } + + // Find parent for up to two levels, if we don't match the path. + const checkLevels = 3 + + var previousPid int + proc := p + + for i := 0; i < checkLevels; i++ { + if proc.Pid == UnidentifiedProcessID || proc.Pid == SystemProcessID { + break + } + + realPath, err := filepath.EvalSymlinks(proc.Path) + if err == nil && realPath == module.portmasterUIPath { + return true + } + + if i < checkLevels-1 { // no need to check parent if we are at the last level + previousPid = proc.Pid + proc, err = GetOrFindProcess(ctx, proc.ParentPid) + if err != nil || proc.Pid == previousPid { + break + } + } + } + + return false +}