diff --git a/component/process/process_darwin.go b/component/process/process_darwin.go index a484c78d3..6ae04552c 100644 --- a/component/process/process_darwin.go +++ b/component/process/process_darwin.go @@ -3,7 +3,6 @@ package process import ( "encoding/binary" "net" - "path/filepath" "syscall" "unsafe" @@ -96,7 +95,7 @@ func getExecPathFromPID(pid uint32) (string, error) { return "", errno } - return filepath.Base(unix.ByteSliceToString(buf)), nil + return unix.ByteSliceToString(buf), nil } func readNativeUint32(b []byte) uint32 { diff --git a/component/process/process_freebsd_amd64.go b/component/process/process_freebsd_amd64.go index bf84ce5b8..f3e646463 100644 --- a/component/process/process_freebsd_amd64.go +++ b/component/process/process_freebsd_amd64.go @@ -4,7 +4,6 @@ import ( "encoding/binary" "fmt" "net" - "path/filepath" "strconv" "strings" "sync" @@ -77,7 +76,7 @@ func getExecPathFromPID(pid uint32) (string, error) { return "", errno } - return filepath.Base(string(buf[:size-1])), nil + return string(buf[:size-1]), nil } func readNativeUint32(b []byte) uint32 { diff --git a/component/process/process_linux.go b/component/process/process_linux.go index 0ca427163..d70a29228 100644 --- a/component/process/process_linux.go +++ b/component/process/process_linux.go @@ -4,11 +4,9 @@ import ( "bytes" "encoding/binary" "fmt" - "io" "net" "os" "path" - "path/filepath" "strings" "syscall" "unicode" @@ -27,17 +25,6 @@ var nativeEndian = func() binary.ByteOrder { return binary.LittleEndian }() -type ( - SocketResolver func(network string, ip net.IP, srcPort int) (inode, uid int, err error) - ProcessNameResolver func(inode, uid int) (name string, err error) -) - -// export for android -var ( - DefaultSocketResolver SocketResolver = resolveSocketByNetlink - DefaultProcessNameResolver ProcessNameResolver = resolveProcessNameByProcSearch -) - const ( sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + 8 + 48 socketDiagByFamily = 20 @@ -45,15 +32,15 @@ const ( ) func findProcessName(network string, ip net.IP, srcPort int) (string, error) { - inode, uid, err := DefaultSocketResolver(network, ip, srcPort) + inode, uid, err := resolveSocketByNetlink(network, ip, srcPort) if err != nil { return "", err } - return DefaultProcessNameResolver(inode, uid) + return resolveProcessNameByProcSearch(inode, uid) } -func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, error) { +func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int32, int32, error) { var family byte var protocol byte @@ -76,13 +63,12 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e socket, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_INET_DIAG) if err != nil { - return 0, 0, err + return 0, 0, fmt.Errorf("dial netlink: %w", err) } defer syscall.Close(socket) - syscall.SetNonblock(socket, true) - syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &syscall.Timeval{Usec: 50}) - syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &syscall.Timeval{Usec: 50}) + syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &syscall.Timeval{Usec: 100}) + syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &syscall.Timeval{Usec: 100}) if err := syscall.Connect(socket, &syscall.SockaddrNetlink{ Family: syscall.AF_NETLINK, @@ -94,7 +80,7 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e } if _, err := syscall.Write(socket, req); err != nil { - return 0, 0, err + return 0, 0, fmt.Errorf("write request: %w", err) } rb := pool.Get(pool.RelayBufferSize) @@ -102,24 +88,27 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e n, err := syscall.Read(socket, rb) if err != nil { - return 0, 0, err + return 0, 0, fmt.Errorf("read response: %w", err) } messages, err := syscall.ParseNetlinkMessage(rb[:n]) if err != nil { - return 0, 0, err + return 0, 0, fmt.Errorf("parse netlink message: %w", err) } else if len(messages) == 0 { - return 0, 0, io.ErrUnexpectedEOF + return 0, 0, fmt.Errorf("unexcepted netlink response") } message := messages[0] if message.Header.Type&syscall.NLMSG_ERROR != 0 { - return 0, 0, syscall.ESRCH + return 0, 0, fmt.Errorf("netlink message: NLMSG_ERROR") } uid, inode := unpackSocketDiagResponse(&messages[0]) + if uid < 0 || inode < 0 { + return 0, 0, fmt.Errorf("invalid uid(%d) or inode(%d)", uid, inode) + } - return int(uid), int(inode), nil + return uid, inode, nil } func packSocketDiagRequest(family, protocol byte, source net.IP, sourcePort uint16) []byte { @@ -157,20 +146,20 @@ func packSocketDiagRequest(family, protocol byte, source net.IP, sourcePort uint return buf } -func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid uint32) { +func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid int32) { if len(msg.Data) < 72 { return 0, 0 } data := msg.Data - uid = nativeEndian.Uint32(data[64:68]) - inode = nativeEndian.Uint32(data[68:72]) + uid = int32(nativeEndian.Uint32(data[64:68])) + inode = int32(nativeEndian.Uint32(data[68:72])) return } -func resolveProcessNameByProcSearch(inode, uid int) (string, error) { +func resolveProcessNameByProcSearch(inode, uid int32) (string, error) { files, err := os.ReadDir(pathProc) if err != nil { return "", err @@ -207,25 +196,12 @@ func resolveProcessNameByProcSearch(inode, uid int) (string, error) { } if bytes.Equal(buffer[:n], socket) { - cmdline, err := os.ReadFile(path.Join(processPath, "cmdline")) - if err != nil { - return "", err - } - - return splitCmdline(cmdline), nil + return os.Readlink(path.Join(processPath, "exe")) } } } - return "", syscall.ESRCH -} - -func splitCmdline(cmdline []byte) string { - idx := bytes.IndexFunc(cmdline, func(r rune) bool { - return unicode.IsControl(r) || unicode.IsSpace(r) - }) - - return filepath.Base(string(cmdline[:idx])) + return "", fmt.Errorf("process of uid(%d),inode(%d) not found", uid, inode) } func isPid(s string) bool { diff --git a/component/process/process_windows.go b/component/process/process_windows.go index 834bc8241..e2fb96cab 100644 --- a/component/process/process_windows.go +++ b/component/process/process_windows.go @@ -3,7 +3,6 @@ package process import ( "fmt" "net" - "path/filepath" "sync" "syscall" "unsafe" @@ -220,5 +219,5 @@ func getExecPathFromPID(pid uint32) (string, error) { if r1 == 0 { return "", err } - return filepath.Base(syscall.UTF16ToString(buf[:size])), nil + return syscall.UTF16ToString(buf[:size]), nil }