anchore / anchore/syft

Support scanning files in other mount namespaces

Open
#3,396 9 comments 0 reactions 1 assignee Claimed by @kzantow View on GitHub
enhancement
Dominant language
Go
Stars
9.6k
Forks
954
Avg merge
23h 27m
Merged PRs (30d)
48

Description

**What would you like to be added**:
I want syft to be able to scan files in other mount namespaces.

**Why is this needed**:
* to scan files in other docker containers
* to scan host files while syft itself runs in a docker container
* to scan files in other docker containers while syft itself runs in a docker container

**Additional context**:
As an example, I'm trying to scan a file on my host filesystem by running the syft scanner inside a docker container. Here, pid 117851 is a process running in my host mount namespace, and the docker permissions allow me to access `/proc/117851/root/`.
```
❯ docker run --rm --cap-add CAP_SYS_ADMIN --cap-add CAP_SYS_PTRACE --pid=host --security-opt apparmor=unconfined anchore/syft scan /proc/117851/root/home/amiculas/ran

unable to get file resolver: unable to get absolute path for analysis path="/proc/117851/root/home/amiculas/ran": lstat /home: no such file or directory
```
syft cannot find `/home` because it's looking for it in its own mount namespace, instead of looking for it in the host's mount namespace. To work as expected, something like [procfsroot](https://github.com/thediveo/procfsroot) should be used.

Another way to make this work would be to use this file path as-is, instead of trying to resolve any paths. But the way syft's FileResolver from `file_source.go` works is by calling `fileresolver.NewFromDirectory` which ends up calling `filepath.EvalSymlinks(...)`. This doesn't work for `proc/PID/root` paths because `proc/PID/root` is a symlink to `/`, but `/` refers to the root from the mount namespace that `syft` is running in, not the target mount namespace that needs to be scanned.

As a proof that this feature should be possible, I'm running trivy from a docker container set up identically:
```
❯ docker run --rm --cap-add CAP_SYS_ADMIN --cap-add CAP_SYS_PTRACE --pid=host --security-opt apparmor=unconfined aquasec/trivy rootfs --format=spdx-json /proc/117851/root/home/amiculas/ran
2024-10-29T16:30:26Z INFO "--format spdx-json" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the "spdx-json" report.
2024-10-29T16:30:26Z INFO Number of language-specific files num=1
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "/proc/117851/root/home/amiculas/ran",
"documentNamespace": "http://aquasecurity.github.io/trivy/filesystem//proc/117851/root/home/amiculas/ran-bf738818-b10b-4ec1-83db-1fe6a9c7cd70",
"creationInfo": {
"creators": [
"Organization: aquasecurity",
"Tool: trivy-0.56.2"
],
"created": "2024-10-29T16:30:26Z"
},
"packages": [
{
"name": "ran",
"SPDXID": "SPDXRef-Application-652ea8ed26a8b19",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"attributionTexts": [
"Class: lang-pkgs",
"Type: gobinary"
],
"primaryPackagePurpose": "APPLICATION"
},
{
"name": "github.com/abbot/go-http-auth",
"SPDXID": "SPDXRef-Package-6bced50b61582bca",
"versionInfo": "v0.4.0",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/github.com/abbot/go-http-auth@v0.4.0"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "github.com/m3ng9i/go-utils",
"SPDXID": "SPDXRef-Package-3142a384896121f8",
"versionInfo": "v0.0.0-20160811013010-f9b7dc669fde",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/github.com/m3ng9i/go-utils@v0.0.0-20160811013010-f9b7dc669fde"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "github.com/m3ng9i/ran",
"SPDXID": "SPDXRef-Package-d371b45954284092",
"versionInfo": "v0.1.6",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/github.com/m3ng9i/ran@v0.1.6"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "github.com/oxtoacart/bpool",
"SPDXID": "SPDXRef-Package-61d659ef30bff13d",
"versionInfo": "v0.0.0-20190530202638-03653db5a59c",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/github.com/oxtoacart/bpool@v0.0.0-20190530202638-03653db5a59c"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "golang.org/x/crypto",
"SPDXID": "SPDXRef-Package-1882a12b82ac17bc",
"versionInfo": "v0.0.0-20190308221718-c2843e01d9a2",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "golang.org/x/net",
"SPDXID": "SPDXRef-Package-3d35ed607a647f31",
"versionInfo": "v0.0.0-20190724013045-ca1201d0de80",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/golang.org/x/net@v0.0.0-20190724013045-ca1201d0de80"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "stdlib",
"SPDXID": "SPDXRef-Package-a77035723e5d3079",
"versionInfo": "1.22.2",
"supplier": "NOASSERTION",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"sourceInfo": "package found in: ran",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:golang/stdlib@1.22.2"
}
],
"attributionTexts": [
"PkgType: gobinary"
],
"primaryPackagePurpose": "LIBRARY"
},
{
"name": "/proc/117851/root/home/amiculas/ran",
"SPDXID": "SPDXRef-Filesystem-84989ddda734b091",
"downloadLocation": "NONE",
"filesAnalyzed": false,
"attributionTexts": [
"SchemaVersion: 2"
],
"primaryPackagePurpose": "SOURCE"
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-Application-652ea8ed26a8b19",
"relatedSpdxElement": "SPDXRef-Package-d371b45954284092",
"relationshipType": "CONTAINS"
},
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-Filesystem-84989ddda734b091",
"relationshipType": "DESCRIBES"
},
{
"spdxElementId": "SPDXRef-Filesystem-84989ddda734b091",
"relatedSpdxElement": "SPDXRef-Application-652ea8ed26a8b19",
"relationshipType": "CONTAINS"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-1882a12b82ac17bc",
"relationshipType": "DEPENDS_ON"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-3142a384896121f8",
"relationshipType": "DEPENDS_ON"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-3d35ed607a647f31",
"relationshipType": "DEPENDS_ON"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-61d659ef30bff13d",
"relationshipType": "DEPENDS_ON"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-6bced50b61582bca",
"relationshipType": "DEPENDS_ON"
},
{
"spdxElementId": "SPDXRef-Package-d371b45954284092",
"relatedSpdxElement": "SPDXRef-Package-a77035723e5d3079",
"relationshipType": "DEPENDS_ON"
}
]
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.