From f78dab50cbd81a75fb30a7c2c4accd35e8e1151e Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Sat, 31 Oct 2020 14:21:11 +0900 Subject: [PATCH] fix(fast-root): affectedProcs, ports bug (#1067) --- scan/base.go | 10 +++++----- scan/base_test.go | 37 +++++++++++++++++++++++++++++-------- scan/debian.go | 8 +++++--- scan/redhatbase.go | 14 ++++++++------ 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/scan/base.go b/scan/base.go index 606979fe..0a993cc8 100644 --- a/scan/base.go +++ b/scan/base.go @@ -898,13 +898,13 @@ func (l *base) lsOfListen() (stdout string, err error) { cmd := `lsof -i -P -n | grep LISTEN` r := l.exec(util.PrependProxyEnv(cmd), sudo) if !r.isSuccess(0, 1) { - return "", xerrors.Errorf("Failed to SSH: %s", r) + return "", xerrors.Errorf("Failed to lsof: %s", r) } return r.Stdout, nil } -func (l *base) parseLsOf(stdout string) map[string]string { - portPid := map[string]string{} +func (l *base) parseLsOf(stdout string) map[string][]string { + portPids := map[string][]string{} scanner := bufio.NewScanner(strings.NewReader(stdout)) for scanner.Scan() { ss := strings.Fields(scanner.Text()) @@ -912,9 +912,9 @@ func (l *base) parseLsOf(stdout string) map[string]string { continue } pid, ipPort := ss[1], ss[8] - portPid[ipPort] = pid + portPids[ipPort] = util.AppendIfMissing(portPids[ipPort], pid) } - return portPid + return portPids } func (l *base) parseListenPorts(port string) models.ListenPort { diff --git a/scan/base_test.go b/scan/base_test.go index 02a6a52e..d7c19bcd 100644 --- a/scan/base_test.go +++ b/scan/base_test.go @@ -244,7 +244,7 @@ func Test_base_parseLsOf(t *testing.T) { tests := []struct { name string args args - wantPortPid map[string]string + wantPortPid map[string][]string }{ { name: "lsof", @@ -257,13 +257,34 @@ node 1498 ubuntu 21u IPv6 20132 0t0 TCP *:35401 (LISTEN node 1498 ubuntu 22u IPv6 20133 0t0 TCP *:44801 (LISTEN) docker-pr 9135 root 4u IPv6 297133 0t0 TCP *:6379 (LISTEN)`, }, - wantPortPid: map[string]string{ - "localhost:53": "474", - "*:22": "644", - "*:3128": "959", - "*:35401": "1498", - "*:44801": "1498", - "*:6379": "9135", + wantPortPid: map[string][]string{ + "localhost:53": {"474"}, + "*:22": {"644"}, + "*:3128": {"959"}, + "*:35401": {"1498"}, + "*:44801": {"1498"}, + "*:6379": {"9135"}, + }, + }, + { + name: "lsof-duplicate-port", + args: args{ + stdout: `sshd 832 root 3u IPv4 15731 0t0 TCP *:22 (LISTEN) +sshd 832 root 4u IPv6 15740 0t0 TCP *:22 (LISTEN) +master 1099 root 13u IPv4 16657 0t0 TCP 127.0.0.1:25 (LISTEN) +master 1099 root 14u IPv6 16658 0t0 TCP [::1]:25 (LISTEN) +httpd 32250 root 4u IPv6 334982 0t0 TCP *:80 (LISTEN) +httpd 32251 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN) +httpd 32252 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN) +httpd 32253 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN) +httpd 32254 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN) +httpd 32255 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)`, + }, + wantPortPid: map[string][]string{ + "*:22": {"832"}, + "127.0.0.1:25": {"1099"}, + "[::1]:25": {"1099"}, + "*:80": {"32250", "32251", "32252", "32253", "32254", "32255"}, }, }, } diff --git a/scan/debian.go b/scan/debian.go index 82a3131f..6183f264 100644 --- a/scan/debian.go +++ b/scan/debian.go @@ -1299,9 +1299,11 @@ func (o *debian) dpkgPs() error { if err != nil { return xerrors.Errorf("Failed to ls of: %w", err) } - portPid := o.parseLsOf(stdout) - for port, pid := range portPid { - pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port)) + portPids := o.parseLsOf(stdout) + for port, pids := range portPids { + for _, pid := range pids { + pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port)) + } } for pid, loadedFiles := range pidLoadedFiles { diff --git a/scan/redhatbase.go b/scan/redhatbase.go index 107538d3..854a2ed7 100644 --- a/scan/redhatbase.go +++ b/scan/redhatbase.go @@ -361,7 +361,7 @@ func (o *redhatBase) scanUpdatablePackages() (models.Packages, error) { return nil, xerrors.Errorf("Failed to SSH: %s", r) } - // Collect Updateble packages, installed, candidate version and repository. + // Collect Updatable packages, installed, candidate version and repository. return o.parseUpdatablePacksLines(r.Stdout) } @@ -496,9 +496,11 @@ func (o *redhatBase) yumPs() error { if err != nil { return xerrors.Errorf("Failed to ls of: %w", err) } - portPid := o.parseLsOf(stdout) - for port, pid := range portPid { - pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port)) + portPids := o.parseLsOf(stdout) + for port, pids := range portPids { + for _, pid := range pids { + pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port)) + } } for pid, loadedFiles := range pidLoadedFiles { @@ -630,8 +632,8 @@ func (o *redhatBase) procPathToFQPN(execCommand string) (string, error) { func (o *redhatBase) getPkgName(paths []string) (pkgNames []string, err error) { cmd := o.rpmQf(o.Distro) + strings.Join(paths, " ") r := o.exec(util.PrependProxyEnv(cmd), noSudo) - if !r.isSuccess() { - return nil, xerrors.Errorf("Failed to SSH: %s", r) + if !r.isSuccess(0, 2, 4, 8) { + return nil, xerrors.Errorf("Failed to rpm -qf: %s, cmd: %s", r, cmd) } scanner := bufio.NewScanner(strings.NewReader(r.Stdout))