mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-21 07:26:52 +00:00
Fix Linux process path lookup after privilege drop
This commit is contained in:
@@ -22,7 +22,11 @@ import (
|
||||
"github.com/sagernet/sing/contrab/maphash"
|
||||
)
|
||||
|
||||
const pathProc = "/proc"
|
||||
const (
|
||||
pathProc = "/proc"
|
||||
|
||||
processPathsAllUsers = ^uint32(0)
|
||||
)
|
||||
|
||||
var _ Searcher = (*linuxSearcher)(nil)
|
||||
|
||||
@@ -123,25 +127,30 @@ func (s *linuxSearcher) resolveSocketByNetlink(network string, source netip.Addr
|
||||
return dumpSocketDiag(family, protocol, source, destination)
|
||||
}
|
||||
|
||||
// The socket keeps the uid it was created with, while /proc reflects the
|
||||
// current uid of the process, so a socket created before a privilege drop
|
||||
// only appears under a scan of all users.
|
||||
func (s *linuxSearcher) findProcessPath(targetInode, uid uint32) (string, error) {
|
||||
if cached, ok := s.processPathCache.Get(uid); ok {
|
||||
if processPath, found := cached.entries[targetInode]; found {
|
||||
for _, scanUID := range []uint32{uid, processPathsAllUsers} {
|
||||
if cached, ok := s.processPathCache.Get(scanUID); ok {
|
||||
if processPath, found := cached.entries[targetInode]; found {
|
||||
return processPath, nil
|
||||
}
|
||||
}
|
||||
processPaths, err := buildProcessPaths(scanUID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.processPathCache.Add(scanUID, &uidProcessPaths{entries: processPaths})
|
||||
processPath, found := processPaths[targetInode]
|
||||
if found {
|
||||
return processPath, nil
|
||||
}
|
||||
}
|
||||
processPaths, err := buildProcessPathsByUID(uid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.processPathCache.Add(uid, &uidProcessPaths{entries: processPaths})
|
||||
processPath, found := processPaths[targetInode]
|
||||
if !found {
|
||||
return "", E.New("process of uid(", uid, "), inode(", targetInode, ") not found")
|
||||
}
|
||||
return processPath, nil
|
||||
return "", E.New("process of uid(", uid, "), inode(", targetInode, ") not found")
|
||||
}
|
||||
|
||||
func buildProcessPathsByUID(uid uint32) (map[uint32]string, error) {
|
||||
func buildProcessPaths(uid uint32) (map[uint32]string, error) {
|
||||
files, err := os.ReadDir(pathProc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -159,7 +168,7 @@ func buildProcessPathsByUID(uid uint32) (map[uint32]string, error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if info.Sys().(*syscall.Stat_t).Uid != uid {
|
||||
if uid != processPathsAllUsers && info.Sys().(*syscall.Stat_t).Uid != uid {
|
||||
continue
|
||||
}
|
||||
processPath := filepath.Join(pathProc, file.Name())
|
||||
|
||||
Reference in New Issue
Block a user