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: add config files to FS for post-analyzers #5218

Closed
wants to merge 9 commits into from

Conversation

nikpivkin
Copy link
Contributor

@nikpivkin nikpivkin commented Sep 20, 2023

Description

This PR fixes a bug when Trivy could not use configuration files (such as tfvars or helm-values) that are located outside the scan directory or their absolute path was passed.

Related issues

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

@nikpivkin nikpivkin marked this pull request as ready for review September 20, 2023 12:12
pkg/x/slices/slices.go Outdated Show resolved Hide resolved
@simar7 simar7 self-requested a review September 23, 2023 04:34
@simar7 simar7 added this pull request to the merge queue Sep 23, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 23, 2023
@simar7 simar7 added this pull request to the merge queue Sep 23, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 23, 2023
@simar7 simar7 added this pull request to the merge queue Sep 25, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 25, 2023
@simar7
Copy link
Member

simar7 commented Sep 25, 2023

@knqyf263 are you able to reproduce the linter issue locally? For some reason it keeps failing in the CI, without a descriptive message that we can use to fix the issue. But locally for me it seems fine:

golangci-lint --version                                                                  
golangci-lint has version 1.54.2 built with go1.21.0 from 411e0bb on 2023-08-21T11:04:00Z


golangci-lint  run  --verbose --timeout 10m          
INFO [config_reader] Config search paths: [./ /Users/simarpreetsingh/repos/trivy /Users/simarpreetsingh/repos /Users/simarpreetsingh /Users /] 
INFO [config_reader] Used config file .golangci.yaml 
INFO [lintersdb] Active 11 linters: [goconst gocyclo gofmt goimports gosec govet ineffassign misspell revive unconvert unused] 
INFO [loader] Go packages loading at mode 575 (exports_file|types_sizes|imports|name|compiled_files|deps|files) took 2.172765416s 
INFO [runner/filename_unadjuster] Pre-built 1 adjustments in 17.912125ms 
INFO [linters_context/goanalysis] analyzers took 0s with no stages 
INFO [runner] Issues before processing: 369, after processing: 0 
INFO [runner] Processors filtering stat (out/in): nolint: 0/7, filename_unadjuster: 369/369, skip_dirs: 239/239, exclude-rules: 7/32, skip_files: 239/369, identifier_marker: 32/32, cgo: 369/369, path_prettifier: 369/369, autogenerated_exclude: 32/239, exclude: 32/32 
INFO [runner] processing took 4.914291ms with stages: path_prettifier: 1.717251ms, nolint: 1.557541ms, skip_files: 662.001µs, autogenerated_exclude: 482.333µs, identifier_marker: 237.25µs, skip_dirs: 199.542µs, exclude-rules: 33.958µs, cgo: 13.791µs, filename_unadjuster: 6.666µs, exclude: 1.291µs, max_same_issues: 541ns, fixer: 500ns, uniq_by_line: 334ns, diff: 292ns, severity-rules: 209ns, sort_results: 208ns, source_code: 167ns, max_from_linter: 166ns, max_per_file_from_linter: 84ns, path_shortener: 83ns, path_prefixer: 83ns 
INFO [runner] linters took 558.617875ms with stages: goanalysis_metalinter: 553.658709ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 29 samples, avg is 46.3MB, max is 118.5MB 
INFO Execution took 2.783455625s  

I even tried with the version of the linter that we run within GitHub actions:

~/Downloads/golangci-lint-1.52.2-darwin-arm64/golangci-lint  run  --verbose --timeout 10m
INFO [config_reader] Config search paths: [./ /Users/simarpreetsingh/repos/trivy /Users/simarpreetsingh/repos /Users/simarpreetsingh /Users /] 
INFO [config_reader] Used config file .golangci.yaml 
INFO [lintersdb] Active 12 linters: [goconst gocyclo gofmt goimports gosec govet ineffassign misspell revive typecheck unconvert unused] 
INFO [loader] Go packages loading at mode 575 (files|imports|compiled_files|deps|exports_file|name|types_sizes) took 1.919123958s 
INFO [runner/filename_unadjuster] Pre-built 1 adjustments in 17.8755ms 
INFO [linters_context/goanalysis] analyzers took 0s with no stages 
INFO [runner] Issues before processing: 445, after processing: 0 
INFO [runner] Processors filtering stat (out/in): cgo: 445/445, filename_unadjuster: 445/445, path_prettifier: 445/445, skip_dirs: 271/271, autogenerated_exclude: 64/271, exclude: 64/64, exclude-rules: 7/64, skip_files: 271/445, identifier_marker: 64/64, nolint: 0/7 
INFO [runner] processing took 6.53254ms with stages: path_prettifier: 2.625625ms, nolint: 1.459792ms, skip_files: 826.583µs, autogenerated_exclude: 715.541µs, identifier_marker: 511.416µs, skip_dirs: 296.083µs, exclude-rules: 67.667µs, cgo: 18.209µs, filename_unadjuster: 7.833µs, exclude: 1.334µs, max_same_issues: 541ns, fixer: 374ns, diff: 250ns, severity-rules: 250ns, source_code: 209ns, uniq_by_line: 209ns, path_shortener: 209ns, max_from_linter: 126ns, sort_results: 124ns, max_per_file_from_linter: 83ns, path_prefixer: 82ns 
INFO [runner] linters took 560.036917ms with stages: goanalysis_metalinter: 553.453417ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 27 samples, avg is 49.8MB, max is 122.6MB 
INFO Execution took 2.526622916s   

Any ideas?

@knqyf263
Copy link
Collaborator

@DmitriyLewen Can you help them?

@DmitriyLewen
Copy link
Contributor

DmitriyLewen commented Sep 26, 2023

Hm... it is strange case.

I tried to reproduce this error on local PC with Ubuntu amd64:

➜  golangci-lint --version                                     
golangci-lint has version 1.52.2 built with go1.20.2 from da04413a on 2023-03-25T18:11:28Z
➜ golangci-lint run --out-format=github-actions --deadline=30m

But linter works as expected.

I have 1 idea - goimport is still used in this PR - https://github.com/nikpivkin/trivy/blob/0653c20a260bf2751a33f0bf2ac9d432c5be5107/.golangci.yaml#L20-L21

But looks like GitHub Action takes settings from main branch - https://github.com/aquasecurity/trivy/actions/runs/6281647291/job/17060265423#step:5:24(error for gci).

Perhaps there is some kind of conflict taking place.
Can you merge main branch to this PR and recheck?

UPD:
i inserted new config file (from main branch) into this PR and got next errors:

➜  trivy git:(fix/fs-config-files) ✗ golangci-lint run --out-format=github-actions --deadline=30m          
::error file=pkg/fanal/analyzer/language/dotnet/nuget/nuget.go,line=9::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/resource.go,line=9::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/resource.go,line=13::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/result.go,line=8::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/result.go,line=11::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/service.go,line=10::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/cloud/report/service.go,line=12::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/image/registry/ecr/ecr.go,line=8::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/image/registry/ecr/ecr.go,line=12::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/image/registry/ecr/ecr.go,line=16::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/k8s/scanner/io.go,line=12::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/k8s/scanner/io.go,line=14::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/analyzer/language/rust/cargo/cargo.go,line=12::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/analyzer/language/rust/cargo/cargo.go,line=17::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/image/registry/azure/azure.go,line=10::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/image/registry/azure/azure.go,line=14::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/detector/ospkg/chainguard/chainguard.go,line=8::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/detector/ospkg/chainguard/chainguard.go,line=10::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/analyzer/language/java/pom/pom.go,line=11::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/artifact/artifact.go,line=7::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/fanal/artifact/artifact.go,line=10::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/report/table/licensing.go,line=8::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/report/table/licensing.go,line=12::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/report/table/licensing.go,line=16::File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/aquasecurity/),blank,dot (gci)
::error file=pkg/report/table/misconfig.go,line=9::File is not `gci`-ed with --skip-generated -s
...

@DmitriyLewen DmitriyLewen mentioned this pull request Sep 26, 2023
6 tasks
@simar7 simar7 force-pushed the fix/fs-config-files branch 2 times, most recently from dcd3fce to 307fdc9 Compare September 26, 2023 07:06
@simar7 simar7 added this pull request to the merge queue Sep 26, 2023
@knqyf263 knqyf263 removed this pull request from the merge queue due to a manual request Sep 26, 2023
@knqyf263
Copy link
Collaborator

I'm sorry to interrupt it, but please let me leave some comments.

@@ -277,9 +277,13 @@ func (a Artifact) inspectLayer(ctx context.Context, layerInfo LayerInfo, disable
}
defer composite.Cleanup()

if err := artifact.AddConfigFilesToFS(composite, a.artifactOption); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should not call a misconfiguration-specific method here because we must call it in all artifacts. For example, this PR is not calling it in VM artifacts. It can lead to a bug.

What if putting files in misconf/scanner.go? Then, each artifact doesn't have to care about IaC config files.

diff --git a/pkg/misconf/scanner.go b/pkg/misconf/scanner.go
index 72f97f968..8f76b739c 100644
--- a/pkg/misconf/scanner.go
+++ b/pkg/misconf/scanner.go
@@ -71,6 +71,7 @@ type Scanner struct {
        fileType       detection.FileType
        scanner        scanners.FSScanner
        hasFilePattern bool
+       configFiles    []string
 }

 func NewAzureARMScanner(filePatterns []string, opt ScannerOption) (*Scanner, error) {
@@ -108,6 +109,7 @@ func newScanner(t detection.FileType, filePatterns []string, opt ScannerOption)
        }

        var scanner scanners.FSScanner
+       var configFiles []string
        switch t {
        case detection.FileTypeAzureARM:
                scanner = arm.New(opts...)
@@ -117,10 +119,12 @@ func newScanner(t detection.FileType, filePatterns []string, opt ScannerOption)
                scanner = dfscanner.NewScanner(opts...)
        case detection.FileTypeHelm:
                scanner = helm.New(opts...)
+               configFiles = append(opt.HelmValueFiles, opt.HelmValueFiles...)
        case detection.FileTypeKubernetes:
                scanner = k8sscanner.NewScanner(opts...)
        case detection.FileTypeTerraform:
                scanner = tfscanner.New(opts...)
+               configFiles = opt.TerraformTFVars
        case detection.FileTypeTerraformPlan:
                scanner = tfpscanner.New(opts...)
        }
@@ -129,6 +133,7 @@ func newScanner(t detection.FileType, filePatterns []string, opt ScannerOption)
                fileType:       t,
                scanner:        scanner,
                hasFilePattern: hasFilePattern(t, filePatterns),
+               configFiles:    configFiles,
        }, nil
 }

@@ -141,6 +146,9 @@ func (s *Scanner) Scan(ctx context.Context, fsys fs.FS) ([]types.Misconfiguratio
                return nil, nil
        }

+       // Add config files to newfs here
+       // addConfigFilesToFS(newfs, s.configFiles)
+
        log.Logger.Debugf("Scanning %s files for misconfigurations...", s.scanner.Name())
        results, err := s.scanner.ScanFS(ctx, newfs, ".")
        if err != nil {
@@ -196,6 +204,7 @@ func (s *Scanner) filterFS(fsys fs.FS) (fs.FS, error) {
        if !foundRelevantFile {
                return nil, nil
        }
+
        return newfs, nil
 }

Copy link
Collaborator

@knqyf263 knqyf263 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it adds files to the existing filesystem, then there are two concerns.

  1. Conflict with the existing files

e.g.

  • pwd
    • tfvars
      • foo.tfvars
    • app
      • tfvars
        • foo.tfvars
      • main.tf

And call trivy config --tf-vars ./tfvars/foo.tfvars ./app. --tf-vars overwrites app/tfvars/foo.tfvars as the mapfs is rooted /app. Please correct me if I'm wrong.

  1. Outside of root dir

e.g.

  • tfvars
    • foo.tfvars
  • pwd
    • app
      • tfvars
        • foo.tfvars
      • main.tf

And call trivy config --tf-vars ../tfvars/foo.tfvars ./app. --tf-vars points to outside of the root dir, meaning /app here. It may work well, but mapfs should not have ../ as much as possible.

This PR is okay for a workaround, but ideally, we may want to create a dedicated filesystem for config files and pass it to scanners.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what do you propose? Should we merge this and create a new issue to track the improvement for a dedicated filesystem for config files?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. That is in my mind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I created #5280 to track that change. Can we merge this PR for now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd apply this kind of change regardless of #5280.
#5218 (comment)

@simar7
Copy link
Member

simar7 commented Oct 4, 2023

@nikpivkin - I rebased on top of latest main branch to see if it helps please the CI tests. Not entirely sure why they are still failing only on GitHub CI (ubuntu).

@nikpivkin
Copy link
Contributor Author

Closed in favor of #5333.

@nikpivkin nikpivkin closed this Oct 4, 2023
@nikpivkin nikpivkin deleted the fix/fs-config-files branch October 4, 2023 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to pass tfvars file
4 participants