mirror of
https://github.com/safing/portmaster
synced 2025-09-02 10:39:22 +00:00
Merge pull request #240 from safing/fix/pid-lock
Check binary path of PID lock
This commit is contained in:
commit
16c0eafd1f
2 changed files with 44 additions and 6 deletions
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -32,16 +33,50 @@ func checkAndCreateInstanceLock(name string) (pid int32, err error) {
|
||||||
return 0, createInstanceLock(lockFilePath)
|
return 0, createInstanceLock(lockFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if process exists
|
// Check if process exists.
|
||||||
p, err := processInfo.NewProcess(int32(parsedPid))
|
p, err := processInfo.NewProcess(int32(parsedPid))
|
||||||
if err == nil {
|
switch {
|
||||||
return p.Pid, nil
|
case err == nil:
|
||||||
|
// Process exists, continue.
|
||||||
|
case errors.Is(err, processInfo.ErrorProcessNotRunning):
|
||||||
|
// A process with the locked PID does not exist.
|
||||||
|
// This is expected, so we can continue normally.
|
||||||
|
return 0, createInstanceLock(lockFilePath)
|
||||||
|
default:
|
||||||
|
// There was an internal error getting the process.
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// else create new lock
|
// Get the process paths and evaluate and clean them.
|
||||||
|
executingBinaryPath, err := p.Exe()
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to get path of existing process: %w", err)
|
||||||
|
}
|
||||||
|
cleanedExecutingBinaryPath, err := filepath.EvalSymlinks(executingBinaryPath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to evaluate path of existing process: %w", err)
|
||||||
|
}
|
||||||
|
ownBinaryPath, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to get path of own process: %w", err)
|
||||||
|
}
|
||||||
|
cleanedOwnBinaryPath, err := filepath.EvalSymlinks(ownBinaryPath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to evaluate path of own process: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the binary path matches.
|
||||||
|
if cleanedExecutingBinaryPath != cleanedOwnBinaryPath {
|
||||||
|
// The process with the locked PID belongs to another binary.
|
||||||
|
// As the Portmaster usually starts very early, it will have a low PID,
|
||||||
|
// which could be assigned to another process on next boot.
|
||||||
return 0, createInstanceLock(lockFilePath)
|
return 0, createInstanceLock(lockFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return PID of already running instance.
|
||||||
|
return p.Pid, nil
|
||||||
|
}
|
||||||
|
|
||||||
func createInstanceLock(lockFilePath string) error {
|
func createInstanceLock(lockFilePath string) error {
|
||||||
// check data root dir
|
// check data root dir
|
||||||
err := dataRoot.Ensure()
|
err := dataRoot.Ensure()
|
||||||
|
|
|
@ -130,7 +130,10 @@ func run(opts *Options, cmdArgs []string) (err error) {
|
||||||
|
|
||||||
// check for duplicate instances
|
// check for duplicate instances
|
||||||
if opts.ShortIdentifier == "core" || opts.ShortIdentifier == "hub" {
|
if opts.ShortIdentifier == "core" || opts.ShortIdentifier == "hub" {
|
||||||
pid, _ := checkAndCreateInstanceLock(opts.ShortIdentifier)
|
pid, err := checkAndCreateInstanceLock(opts.ShortIdentifier)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to exec lock: %w", err)
|
||||||
|
}
|
||||||
if pid != 0 {
|
if pid != 0 {
|
||||||
return fmt.Errorf("another instance of %s is already running: PID %d", opts.Name, pid)
|
return fmt.Errorf("another instance of %s is already running: PID %d", opts.Name, pid)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue