aboutsummaryrefslogtreecommitdiff
path: root/internal/lock
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lock')
-rw-r--r--internal/lock/lock.go5
-rw-r--r--internal/lock/lock_test.go13
2 files changed, 17 insertions, 1 deletions
diff --git a/internal/lock/lock.go b/internal/lock/lock.go
index 462b26e..2b98227 100644
--- a/internal/lock/lock.go
+++ b/internal/lock/lock.go
@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"io/fs"
+ "math"
"os"
"path/filepath"
"strconv"
@@ -156,8 +157,10 @@ func parsePid(s string) (int, bool) {
}
// running reports whether pid names a process that is currently running.
+// A pid outside the kernel's 32-bit range names no process: kill(2) would
+// cut it to its low bits and ask about another one.
func running(pid int) bool {
- if pid <= 0 {
+ if pid <= 0 || pid > math.MaxInt32 {
return false
}
proc, err := os.FindProcess(pid)
diff --git a/internal/lock/lock_test.go b/internal/lock/lock_test.go
index fca4d76..53ce5ca 100644
--- a/internal/lock/lock_test.go
+++ b/internal/lock/lock_test.go
@@ -122,3 +122,16 @@ func TestStaleLockIsTakenOver(t *testing.T) {
t.Error("the takeover was not reported to the caller")
}
}
+
+// TestRunningRejectsPidsBeyondTheKernelsRange: a pid wider than 32 bits in a
+// damaged lock file is cut to its low bits by kill(2), so without a range
+// check it names some other process - here this very one - and a stale lock
+// would never be taken over.
+func TestRunningRejectsPidsBeyondTheKernelsRange(t *testing.T) {
+ if running(os.Getpid() + 1<<32) {
+ t.Error("running(pid + 2^32) is true: the pid was truncated to this process")
+ }
+ if !running(os.Getpid()) {
+ t.Error("running(own pid) is false")
+ }
+}