Skip to content

Commit

Permalink
Merge pull request shirou#1051 from Lomanic/issue1049
Browse files Browse the repository at this point in the history
[process][posix] Fix shirou#1049 check if procfs is mounted before checking if pid exists there
  • Loading branch information
shirou authored Mar 21, 2021
2 parents f69e79f + 0881c11 commit 76779af
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
28 changes: 21 additions & 7 deletions process/process_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ func getTerminalMap() (map[uint64]string, error) {
return ret, nil
}

// isMount is a port of python's os.path.ismount()
// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216
// https://docs.python.org/3/library/os.path.html#os.path.ismount
func isMount(path string) bool {
var stat1 unix.Stat_t
if err := unix.Lstat(path, &stat1); err != nil {
return false
}
if stat1.Mode == unix.DT_LNK {
return false
}
parent := filepath.Join(path, "..")
var stat2 unix.Stat_t
if err := unix.Lstat(parent, &stat2); err != nil {
return false
}
return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino
}

func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
Expand All @@ -79,20 +98,15 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
if err != nil {
return false, err
}

if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
// This covers the case when running inside container with a different process namespace (by default)

if isMount(common.HostProc()) { // if /<HOST_PROC>/proc exists and is mounted, check if /<HOST_PROC>/proc/<PID> folder exists
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
if os.IsNotExist(err) {
return false, nil
}
return err == nil, err
}

//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
//Make sense only if we run in the same process namespace
// procfs does not exist or is not mounted, check PID existence by signalling the pid
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
Expand Down
28 changes: 21 additions & 7 deletions v3/process/process_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ func getTerminalMap() (map[uint64]string, error) {
return ret, nil
}

// isMount is a port of python's os.path.ismount()
// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216
// https://docs.python.org/3/library/os.path.html#os.path.ismount
func isMount(path string) bool {
var stat1 unix.Stat_t
if err := unix.Lstat(path, &stat1); err != nil {
return false
}
if stat1.Mode == unix.DT_LNK {
return false
}
parent := filepath.Join(path, "..")
var stat2 unix.Stat_t
if err := unix.Lstat(parent, &stat2); err != nil {
return false
}
return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino
}

func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
Expand All @@ -80,19 +99,15 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, err
}

if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
// This covers the case when running inside container with a different process namespace (by default)

if isMount(common.HostProc()) { // if /<HOST_PROC>/proc exists and is mounted, check if /<HOST_PROC>/proc/<PID> folder exists
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
if os.IsNotExist(err) {
return false, nil
}
return err == nil, err
}

//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
//Make sense only if we run in the same process namespace
// procfs does not exist or is not mounted, check PID existence by signalling the pid
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
Expand Down Expand Up @@ -158,4 +173,3 @@ func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
}
return "", nil
}

0 comments on commit 76779af

Please sign in to comment.