Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(debian): move *.list dpkg analyzer to separate analyzer #6682

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"PkgName": "libidn2-0",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-10.1",
"UID": "473f5eb9e3d4a2f2"
"UID": "90ca98dd0e7ef4c9"
},
"InstalledVersion": "2.0.5-1",
"FixedVersion": "2.0.5-1+deb10u1",
Expand Down
4 changes: 2 additions & 2 deletions integration/testdata/debian-buster.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-10.1",
"UID": "d45ab8ae65ffe67"
"UID": "8d7a8682e8e570f6"
},
"InstalledVersion": "5.0-4",
"Status": "affected",
Expand Down Expand Up @@ -126,7 +126,7 @@
"PkgName": "libidn2-0",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-10.1",
"UID": "473f5eb9e3d4a2f2"
"UID": "90ca98dd0e7ef4c9"
},
"InstalledVersion": "2.0.5-1",
"FixedVersion": "2.0.5-1+deb10u1",
Expand Down
10 changes: 5 additions & 5 deletions integration/testdata/debian-stretch.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-9.9",
"UID": "6100d09336f565a0"
"UID": "169a2eb9316cbc25"
},
"InstalledVersion": "4.4-5",
"Status": "end_of_life",
Expand Down Expand Up @@ -126,7 +126,7 @@
"PkgName": "e2fslibs",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-9.9",
"UID": "656652ce5818f7b6"
"UID": "8e9a3beaf044163"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
Expand Down Expand Up @@ -200,7 +200,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-9.9",
"UID": "3d19fd957338dc06"
"UID": "8e1a49ed8eab9cdd"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
Expand Down Expand Up @@ -274,7 +274,7 @@
"PkgName": "libcomerr2",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-9.9",
"UID": "6ba1fac685a0c068"
"UID": "8defa5f1bc216456"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
Expand Down Expand Up @@ -348,7 +348,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/[email protected]?arch=amd64\u0026distro=debian-9.9",
"UID": "e507c185f61cd2e8"
"UID": "acde693812d0c389"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
Expand Down
8 changes: 4 additions & 4 deletions integration/testdata/ubuntu-1804-ignore-unfixed.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "ae80ec86b8816b6c"
"UID": "b72413ab1b4bb266"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -148,7 +148,7 @@
"PkgName": "libcom-err2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "3c28244e063693a2"
"UID": "7bb2b92159d48f66"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -219,7 +219,7 @@
"PkgName": "libext2fs2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "937ce6e3021ed568"
"UID": "bbf41e10db8e7ccc"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -290,7 +290,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "7a50c6bc4279c93b"
"UID": "c85c62b3de87638"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down
10 changes: 5 additions & 5 deletions integration/testdata/ubuntu-1804.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "da318bd19a304cc0"
"UID": "bbe28cf85cdf4616"
},
"InstalledVersion": "4.4.18-2ubuntu1.2",
"Status": "affected",
Expand Down Expand Up @@ -140,7 +140,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "ae80ec86b8816b6c"
"UID": "b72413ab1b4bb266"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -211,7 +211,7 @@
"PkgName": "libcom-err2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "3c28244e063693a2"
"UID": "7bb2b92159d48f66"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -282,7 +282,7 @@
"PkgName": "libext2fs2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "937ce6e3021ed568"
"UID": "bbf41e10db8e7ccc"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down Expand Up @@ -353,7 +353,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/[email protected]?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "7a50c6bc4279c93b"
"UID": "c85c62b3de87638"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
Expand Down
12 changes: 7 additions & 5 deletions pkg/fanal/analyzer/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ const (
TypeUbuntuESM Type = "ubuntu-esm"

// OS Package
TypeApk Type = "apk"
TypeDpkg Type = "dpkg"
TypeDpkgLicense Type = "dpkg-license" // For analyzing licenses
TypeRpm Type = "rpm"
TypeRpmqa Type = "rpmqa"
TypeApk Type = "apk"
TypeDpkg Type = "dpkg"
TypeDpkgLicense Type = "dpkg-license" // For analyzing licenses
TypeDpkgSystemFiles Type = "dpkg-system-files" // For analyzing system files
TypeRpm Type = "rpm"
TypeRpmqa Type = "rpmqa"

// OS Package Repository
TypeApkRepo Type = "apk-repo"
Expand Down Expand Up @@ -156,6 +157,7 @@ var (
TypeApk,
TypeDpkg,
TypeDpkgLicense,
TypeDpkgSystemFiles,
TypeRpm,
TypeRpmqa,
TypeApkRepo,
Expand Down
83 changes: 2 additions & 81 deletions pkg/fanal/analyzer/pkg/dpkg/dpkg.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dpkg

import (
"bufio"
"context"
"errors"
"fmt"
Expand Down Expand Up @@ -45,7 +44,6 @@ const (

statusFile = "var/lib/dpkg/status"
statusDir = "var/lib/dpkg/status.d/"
infoDir = "var/lib/dpkg/info/"
availableFile = "var/lib/dpkg/available"
)

Expand All @@ -55,7 +53,6 @@ var (
)

func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) {
var systemInstalledFiles []string
var packageInfos []types.PackageInfo

// parse `available` file to get digest for packages
Expand All @@ -68,21 +65,8 @@ func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysis
return path != availableFile
}

packageFiles := make(map[string][]string)

// parse other files
err = fsutils.WalkDir(input.FS, ".", required, func(path string, d fs.DirEntry, r io.Reader) error {
// parse list files
if a.isListFile(filepath.Split(path)) {
scanner := bufio.NewScanner(r)
systemFiles, err := a.parseDpkgInfoList(scanner)
if err != nil {
return err
}
packageFiles[strings.TrimSuffix(filepath.Base(path), ".list")] = systemFiles
systemInstalledFiles = append(systemInstalledFiles, systemFiles...)
return nil
}
// parse status files
infos, err := a.parseDpkgStatus(path, r, digests)
if err != nil {
Expand All @@ -95,67 +79,12 @@ func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysis
return nil, xerrors.Errorf("dpkg walk error: %w", err)
}

// map the packages to their respective files
for i, pkgInfo := range packageInfos {
for j, pkg := range pkgInfo.Packages {
installedFiles, found := packageFiles[pkg.Name]
if !found {
installedFiles = packageFiles[pkg.Name+":"+pkg.Arch]
}
packageInfos[i].Packages[j].InstalledFiles = installedFiles
}
}

return &analyzer.AnalysisResult{
PackageInfos: packageInfos,
SystemInstalledFiles: systemInstalledFiles,
PackageInfos: packageInfos,
}, nil

}

// parseDpkgInfoList parses /var/lib/dpkg/info/*.list
func (a dpkgAnalyzer) parseDpkgInfoList(scanner *bufio.Scanner) ([]string, error) {
var (
allLines []string
installedFiles []string
previous string
)

for scanner.Scan() {
current := scanner.Text()
if current == "/." {
continue
}
allLines = append(allLines, current)
}

if err := scanner.Err(); err != nil {
return nil, xerrors.Errorf("scan error: %w", err)
}

// Add the file if it is not directory.
// e.g.
// /usr/sbin
// /usr/sbin/tarcat
//
// In the above case, we should take only /usr/sbin/tarcat since /usr/sbin is a directory
// sort first,see here:https://github.com/aquasecurity/trivy/discussions/6543
sort.Strings(allLines)
for _, current := range allLines {
if !strings.HasPrefix(current, previous+"/") {
installedFiles = append(installedFiles, previous)
}
previous = current
}

// // Add the last file
if previous != "" && !strings.HasSuffix(previous, "/") {
installedFiles = append(installedFiles, previous)
}

return installedFiles, nil
}

// parseDpkgAvailable parses /var/lib/dpkg/available
func (a dpkgAnalyzer) parseDpkgAvailable(fsys fs.FS) (map[string]digest.Digest, error) {
f, err := fsys.Open(availableFile)
Expand Down Expand Up @@ -290,7 +219,7 @@ func (a dpkgAnalyzer) parseDpkgPkg(header textproto.MIMEHeader) *types.Package {

func (a dpkgAnalyzer) Required(filePath string, _ os.FileInfo) bool {
dir, fileName := filepath.Split(filePath)
if a.isListFile(dir, fileName) || filePath == statusFile || filePath == availableFile {
if filePath == statusFile || filePath == availableFile {
return true
}

Expand Down Expand Up @@ -357,14 +286,6 @@ func (a dpkgAnalyzer) consolidateDependencies(pkgs map[string]*types.Package, pk
}
}

func (a dpkgAnalyzer) isListFile(dir, fileName string) bool {
if dir != infoDir {
return false
}

return strings.HasSuffix(fileName, ".list")
}

func (a dpkgAnalyzer) Type() analyzer.Type {
return analyzer.TypeDpkg
}
Expand Down
32 changes: 0 additions & 32 deletions pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1417,28 +1417,6 @@ func Test_dpkgAnalyzer_Analyze(t *testing.T) {
},
},
},
{
name: "info list",
testFiles: map[string]string{"./testdata/tar.list": "var/lib/dpkg/info/tar.list"},
want: &analyzer.AnalysisResult{
SystemInstalledFiles: []string{
"/bin/tar",
"/etc/rmt",
"/usr/lib/mime/packages/tar",
"/usr/sbin/rmt-tar",
"/usr/sbin/tarcat",
"/usr/share/doc/tar/AUTHORS",
"/usr/share/doc/tar/NEWS.gz",
"/usr/share/doc/tar/README.Debian",
"/usr/share/doc/tar/THANKS.gz",
"/usr/share/doc/tar/changelog.Debian.gz",
"/usr/share/doc/tar/copyright",
"/usr/share/man/man1/tar.1.gz",
"/usr/share/man/man1/tarcat.1.gz",
"/usr/share/man/man8/rmt-tar.8.gz",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -1490,21 +1468,11 @@ func Test_dpkgAnalyzer_Required(t *testing.T) {
filePath: "var/lib/dpkg/status.d/base-files.md5sums",
want: false,
},
{
name: "list file",
filePath: "var/lib/dpkg/info/bash.list",
want: true,
},
{
name: "available file",
filePath: "var/lib/dpkg/available",
want: true,
},
{
name: "sad path",
filePath: "var/lib/dpkg/status/bash.list",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Loading
Loading