Skip to content

Commit 2a83012

Browse files
authored
Merge pull request #34 from swarit-stepsecurity/swarit/fix/33
fix: add nil check before attempting to kill
2 parents bdee96f + 54fd641 commit 2a83012

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

pipe/command_nil_panic_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package pipe
5+
6+
import (
7+
"context"
8+
"os/exec"
9+
"testing"
10+
)
11+
12+
func TestKillWithNilProcess(t *testing.T) {
13+
cmd := exec.Command("sleep", "100")
14+
stage := &commandStage{
15+
name: "test-command",
16+
cmd: cmd,
17+
done: make(chan struct{}),
18+
}
19+
20+
defer func() {
21+
if r := recover(); r != nil {
22+
t.Fatalf("PANIC OCCURRED (bug not fixed): %v", r)
23+
}
24+
}()
25+
26+
stage.Kill(context.Canceled)
27+
28+
t.Log("SUCCESS: Kill() handled nil Process gracefully without panicking")
29+
}
30+
31+
func TestKillWithFailedStart(t *testing.T) {
32+
ctx := context.Background()
33+
34+
stage := Command("/this/path/does/not/exist/invalid_command_12345")
35+
36+
_, err := stage.Start(ctx, Env{}, nil)
37+
if err == nil {
38+
t.Fatal("Expected start to fail, but it succeeded")
39+
}
40+
41+
// At this point, if someone calls Kill (perhaps from a memory monitor
42+
// or other external component), it could panic if Process is nil
43+
44+
// Note: In the current implementation, Kill won't be called from the
45+
// context goroutine because Start failed. But external callers like
46+
// MemoryLimit could potentially call Kill on a failed stage.
47+
}

pipe/command_unix.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ func (s *commandStage) Kill(err error) {
3030
// use internal synchronization. But those methods only kill the
3131
// process, not the process group, so they are not suitable here.
3232

33+
// Check if the process was started successfully before attempting to kill
34+
if s.cmd.Process == nil {
35+
return
36+
}
37+
3338
// We started the process with PGID == PID:
3439
pid := s.cmd.Process.Pid
3540
select {

pipe/command_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ func (s *commandStage) runInOwnProcessGroup() {}
99
// kill is called to kill the process if the context expires. `err` is
1010
// the corresponding value of `Context.Err()`.
1111
func (s *commandStage) Kill(err error) {
12+
// Check if the process was started successfully before attempting to kill
13+
if s.cmd.Process == nil {
14+
return
15+
}
16+
1217
select {
1318
case <-s.done:
1419
// Process has ended; no need to kill it again.

0 commit comments

Comments
 (0)