PURL is empty for "graalvm-native-image-cataloger"

I am generating SBOM for graal-vm-native binaries.

  1. I have created a simple maven project with few dependencies.
  2. downloaded graalvm-jdk-21
  3. Built maven project using mvn clean package
  4. Generated native binary using command
    1. graalvm-jdk-21.0.8+12.1/Contents/Home/bin/native-image -cp target/classes demo.Fortune -o target/fortune

  5. Scanned native binary directly and also tried from docker image

Sample Output

{
            "id": "31911a4b68121b97",
            "name": "com.fasterxml.jackson.core/jackson-annotations",
            "version": "2.19.1",
            "type": "UnknownPackage",
            "foundBy": "graalvm-native-image-cataloger",
            "locations": [ ],
            "licenses": [ ],
            "language": "",
            "cpes": [
              {
                "cpe": "cpe:2.3:a:annotations:annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:annotations:jackson-annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:annotations:jackson:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:annotations:jackson_annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:core:annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:core:jackson-annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:core:jackson:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:core:jackson_annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:fasterxml:annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:fasterxml:jackson-annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:fasterxml:jackson:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:fasterxml:jackson_annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson-annotations:annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson-annotations:jackson-annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson-annotations:jackson:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson-annotations:jackson_annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson:annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson:jackson-annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson:jackson:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              },
              {
                "cpe": "cpe:2.3:a:jackson:jackson_annotations:2.19.1:*:*:*:*:*:*:*",
                "source": "declared"
              }
            ],
            "purl": ""
          },

Problem,

  1. Type is returned as `UnknownPackage`
  2. PURL is empty

am I doing anything wrong? is there any way we can have proper values for type and PURL?

Update:

Files inside the binary

There are 32 section headers, starting at offset 0xed83768:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400318  00000318
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.gnu.pr[...] NOTE             0000000000400338  00000338
       0000000000000020  0000000000000000   A       0     0     8
  [ 3] .note.gnu.bu[...] NOTE             0000000000400358  00000358
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .note.ABI-tag     NOTE             000000000040037c  0000037c
       0000000000000020  0000000000000000   A       0     0     4
  [ 5] .gnu.hash         GNU_HASH         00000000004003a0  000003a0
       00000000000001dc  0000000000000000   A       6     0     8
  [ 6] .dynsym           DYNSYM           0000000000400580  00000580
       00000000000018d8  0000000000000018   A       7     1     8
  [ 7] .dynstr           STRTAB           0000000000401e58  00001e58
       000000000000125b  0000000000000000   A       0     0     1
  [ 8] .gnu.version      VERSYM           00000000004030b4  000030b4
       0000000000000212  0000000000000002   A       6     0     2
  [ 9] .gnu.version_r    VERNEED          00000000004032c8  000032c8
       00000000000000e0  0000000000000000   A       7     1     8
  [10] .rela.dyn         RELA             00000000004033a8  000033a8
       0000000000000738  0000000000000018   A       6     0     8
  [11] .rela.plt         RELA             0000000000403ae0  00003ae0
       00000000000010e0  0000000000000018  AI       6    25     8
  [12] .init             PROGBITS         0000000000405000  00005000
       000000000000001b  0000000000000000  AX       0     0     4
  [13] .plt              PROGBITS         0000000000405020  00005020
       0000000000000b50  0000000000000010  AX       0     0     16
  [14] .text             PROGBITS         0000000000406000  00006000
       00000000077279fb  0000000000000000  AX       0     0     4096
  [15] .fini             PROGBITS         0000000007b2d9fc  0772d9fc
       000000000000000d  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         0000000007b2e000  0772e000
       000000000002f4de  0000000000000000   A       0     0     4096
  [17] .svm_heap         PROGBITS         0000000007b5e000  0775e000
       0000000007619000  0000000000000000   A       0     0     4096
  [18] .eh_frame_hdr     PROGBITS         000000000f177000  0ed77000
       0000000000000d5c  0000000000000000   A       0     0     4
  [19] .eh_frame         PROGBITS         000000000f177d60  0ed77d60
       0000000000004314  0000000000000000   A       0     0     8
  [20] .init_array       INIT_ARRAY       000000000f17ddc0  0ed7cdc0
       0000000000000008  0000000000000008  WA       0     0     8
  [21] .fini_array       FINI_ARRAY       000000000f17ddc8  0ed7cdc8
       0000000000000008  0000000000000008  WA       0     0     8
  [22] .data.rel.ro      PROGBITS         000000000f17ddd0  0ed7cdd0
       0000000000000008  0000000000000000  WA       0     0     8
  [23] .dynamic          DYNAMIC          000000000f17ddd8  0ed7cdd8
       00000000000001e0  0000000000000010  WA       7     0     8
  [24] .got              PROGBITS         000000000f17dfb8  0ed7cfb8
       0000000000000048  0000000000000008  WA       0     0     8
  [25] .got.plt          PROGBITS         000000000f17e000  0ed7d000
       00000000000005b8  0000000000000008  WA       0     0     8
  [26] .data             PROGBITS         000000000f17f000  0ed7e000
       0000000000005330  0000000000000000  WA       0     0     4096
  [27] .bss              NOBITS           000000000f184340  0ed83330
       0000000000000698  0000000000000000  WA       0     0     32
  [28] .comment          PROGBITS         0000000000000000  0ed83330
       0000000000000072  0000000000000001  MS       0     0     1
  [29] .annobin.notes    PROGBITS         0000000000000000  0ed833a2
       000000000000013e  0000000000000001  MS       0     0     1
  [30] .gnu.build.a[...] NOTE             000000000f1869d8  0ed834e0
       0000000000000144  0000000000000000           0     0     4
  [31] .shstrtab         STRTAB           0000000000000000  0ed83624
       0000000000000142  0000000000000000           0     0     1

I believe the GraalVM native images have embedded SBOMs. Can you extract that and have a look at the contents? I suspect there’s an CycloneDX SBOM with no PURL. Syft is decoding this package and because it does not have a PURL is unable to determine the package type, which is why it is unknown. I don’t know how the SBOM is being generated in the first place when it is embedded in the executable, do you know what the --enable-sbom does in detail?

Sorry updated the command. The flag –enable-sbom is not used at all. Also provided preview of native-binary.

Looks like syft is generating SBOM from graalvm-binary using the below cataloger

Yes, but you will see these functions, such as decompressSbom, these are decompressing an SBOM that was embedded in the executable. The original SBOM generator that was used to create the embedded SBOM seems as though it may not be setting the PURL. At least having a look at what that SBOM contains will help us understand where the problem is.

SBOM from inspection of binary

santhoshs-MacBook-Pro:maven-plugin smuraris$ ~/Downloads/softwares/graalvm-jdk-21.0.8+12.1/Contents/Home/bin/native-image-inspect --sbom target/fortune {"bomFormat":"CycloneDX","specVersion":"1.4","version":1,"components":[{"type":"library","group":"com.oracle.svm","name":"svm","version":"21.0.8+12-LTS","properties":[{"name":"syft:cpe23","value":"cpe:2.3:a:oracle:graalvm-native-image:21.0.8+12-LTS:*:*:*:*:*:*:*"}]}, {"type":"library","group":"org.graalvm","name":"collections","version":"21.0.8+12-LTS","properties":[{"name":"syft:cpe23","value":"cpe:2.3:a:collections:collections:21.0.8+12-LTS:*:*:*:*:*:*:*"}, {"name":"syft:cpe23","value":"cpe:2.3:a:graalvm:collections:21.0.8+12-LTS:*:*:*:*:*:*:*"}]}, {"type":"library","group":"org.graalvm","name":"nativeimage","version":"21.0.8+12-LTS","properties":[{"name":"syft:cpe23","value":"cpe:2.3:a:graalvm:nativeimage:21.0.8+12-LTS:*:*:*:*:*:*:*"}, {"name":"syft:cpe23","value":"cpe:2.3:a:nativeimage:nativeimage:21.0.8+12-LTS:*:*:*:*:*:*:*"}]}, {"type":"library","group":"org.graalvm","name":"word","version":"21.0.8+12-LTS","properties":[{"name":"syft:cpe23","value":"cpe:2.3:a:graalvm:word:21.0.8+12-LTS:*:*:*:*:*:*:*"}, {"name":"syft:cpe23","value":"cpe:2.3:a:word:word:21.0.8+12-LTS:*:*:*:*:*:*:*"}]}],"serialNumber":"urn:uuid:de0f5e74-f1db-3838-9d6f-1622f1166f34"}

But syft report still does not show PURL

{ "artifacts": [ { "id": "fb02c38642a3a165", "name": "com.oracle.svm/svm", "version": "21.0.8+12-LTS", "type": "UnknownPackage", "foundBy": "graalvm-native-image-cataloger", "locations": [ ], "licenses": [ ], "language": "", "cpes": [ { "cpe": "cpe:2.3:a:oracle:graalvm-native-image:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" } ], "purl": "" }, { "id": "b57b1eba47360de7", "name": "org.graalvm/collections", "version": "21.0.8+12-LTS", "type": "UnknownPackage", "foundBy": "graalvm-native-image-cataloger", "locations": [ ], "licenses": [ ], "language": "", "cpes": [ { "cpe": "cpe:2.3:a:collections:collections:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" }, { "cpe": "cpe:2.3:a:graalvm:collections:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" } ], "purl": "" }, { "id": "7981999a9203a9e9", "name": "org.graalvm/nativeimage", "version": "21.0.8+12-LTS", "type": "UnknownPackage", "foundBy": "graalvm-native-image-cataloger", "locations": [ ], "licenses": [ ], "language": "", "cpes": [ { "cpe": "cpe:2.3:a:graalvm:nativeimage:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" }, { "cpe": "cpe:2.3:a:nativeimage:nativeimage:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" } ], "purl": "" }, { "id": "9a3b9a8f59327f52", "name": "org.graalvm/word", "version": "21.0.8+12-LTS", "type": "UnknownPackage", "foundBy": "graalvm-native-image-cataloger", "locations": [ ], "licenses": [ ], "language": "", "cpes": [ { "cpe": "cpe:2.3:a:graalvm:word:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" }, { "cpe": "cpe:2.3:a:word:word:21.0.8\\+12-LTS:*:*:*:*:*:*:*", "source": "declared" } ], "purl": "" } ], "artifactRelationships": [ { "parent": "6862081b89c5dca7d5eacb116a2e809e5c206ec6cc7e638062dd2ae52a651d0b", "child": "7981999a9203a9e9", "type": "contains" }, { "parent": "6862081b89c5dca7d5eacb116a2e809e5c206ec6cc7e638062dd2ae52a651d0b", "child": "9a3b9a8f59327f52", "type": "contains" }, { "parent": "6862081b89c5dca7d5eacb116a2e809e5c206ec6cc7e638062dd2ae52a651d0b", "child": "b57b1eba47360de7", "type": "contains" }, { "parent": "6862081b89c5dca7d5eacb116a2e809e5c206ec6cc7e638062dd2ae52a651d0b", "child": "fb02c38642a3a165", "type": "contains" } ], "files": [ { "id": "827dac43f669d84f", "location": { "path": "/fortune" }, "executable": { "format": "macho", "hasExports": true, "hasEntrypoint": true, "importedLibraries": [ "/usr/lib/libSystem.B.dylib", "/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation", "/usr/lib/libz.1.dylib", "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation", "/usr/lib/libobjc.A.dylib" ] }, "unknowns": [ "unknowns-labeler: no package identified in executable file" ] } ], "source": { "id": "6862081b89c5dca7d5eacb116a2e809e5c206ec6cc7e638062dd2ae52a651d0b", "name": "fortune", "version": "sha256:b3627eca7c071ccf3f3e432975f6307c3cf6ad71d4cbf982115516333186806d", "type": "file", "metadata": { "path": "target/fortune", "digests": [ { "algorithm": "sha256", "value": "b3627eca7c071ccf3f3e432975f6307c3cf6ad71d4cbf982115516333186806d" } ], "mimeType": "application/x-mach-binary" } }, "distro": { }, "descriptor": { "name": "syft", "version": "1.31.0", "configuration": { "catalogers": { "requested": { "default": [ "directory", "file" ] }, "used": [ "alpm-db-cataloger", "apk-db-cataloger", "binary-classifier-cataloger", "cargo-auditable-binary-cataloger", "cocoapods-cataloger", "conan-cataloger", "dart-pubspec-cataloger", "dart-pubspec-lock-cataloger", "deb-archive-cataloger", "dotnet-deps-binary-cataloger", "dotnet-packages-lock-cataloger", "dpkg-db-cataloger", "elf-binary-package-cataloger", "elixir-mix-lock-cataloger", "erlang-otp-application-cataloger", "erlang-rebar-lock-cataloger", "file-content-cataloger", "file-digest-cataloger", "file-executable-cataloger", "file-metadata-cataloger", "github-action-workflow-usage-cataloger", "github-actions-usage-cataloger", "go-module-binary-cataloger", "go-module-file-cataloger", "graalvm-native-image-cataloger", "haskell-cataloger", "homebrew-cataloger", "java-archive-cataloger", "java-gradle-lockfile-cataloger", "java-jvm-cataloger", "java-pom-cataloger", "javascript-lock-cataloger", "linux-kernel-cataloger", "lua-rock-cataloger", "nix-cataloger", "opam-cataloger", "pe-binary-package-cataloger", "php-composer-lock-cataloger", "php-interpreter-cataloger", "php-pear-serialized-cataloger", "portage-cataloger", "python-installed-package-cataloger", "python-package-cataloger", "r-package-cataloger", "rpm-archive-cataloger", "rpm-db-cataloger", "ruby-gemfile-cataloger", "ruby-gemspec-cataloger", "rust-cargo-lock-cataloger", "swift-package-manager-cataloger", "swipl-pack-cataloger", "terraform-lock-cataloger", "wordpress-plugins-cataloger" ] }, "data-generation": { "generate-cpes": true }, "files": { "content": { "globs": null, "skip-files-above-size": 0 }, "hashers": [ "sha-1", "sha-256" ], "selection": "owned-by-package" }, "licenses": { "coverage": 75, "include-content": "none" }, "packages": { "binary": [ "python-binary", "python-binary-lib", "pypy-binary-lib", "go-binary", "julia-binary", "helm", "redis-binary", "nodejs-binary", "go-binary-hint", "busybox-binary", "util-linux-binary", "haproxy-binary", "perl-binary", "php-composer-binary", "httpd-binary", "memcached-binary", "traefik-binary", "arangodb-binary", "postgresql-binary", "mysql-binary", "mysql-binary", "mysql-binary", "xtrabackup-binary", "mariadb-binary", "rust-standard-library-linux", "rust-standard-library-macos", "ruby-binary", "erlang-binary", "erlang-alpine-binary", "erlang-library", "swipl-binary", "dart-binary", "haskell-ghc-binary", "haskell-cabal-binary", "haskell-stack-binary", "consul-binary", "hashicorp-vault-binary", "nginx-binary", "bash-binary", "openssl-binary", "gcc-binary", "fluent-bit-binary", "wordpress-cli-binary", "curl-binary", "lighttpd-binary", "proftpd-binary", "zstd-binary", "xz-binary", "gzip-binary", "sqlcipher-binary", "jq-binary", "chrome-binary", "java-binary", "java-jdb-binary" ], "dotnet": { "dep-packages-must-claim-dll": true, "dep-packages-must-have-dll": false, "propagate-dll-claims-to-parents": true, "relax-dll-claims-when-bundling-detected": true }, "golang": { "local-mod-cache-dir": "/Users/smuraris/go/pkg/mod", "local-vendor-dir": "", "main-module-version": { "from-build-settings": true, "from-contents": false, "from-ld-flags": true }, "no-proxy": [ "*.oci.oraclecorp.com" ], "proxies": [ "``https://proxy.golang.org``", "direct" ], "search-local-mod-cache-licenses": false, "search-local-vendor-licenses": false, "search-remote-licenses": false }, "java-archive": { "include-indexed-archives": true, "include-unindexed-archives": false, "maven-base-url": " Central Repository: ", "maven-localrepository-dir": "/Users/smuraris/.m2/repository", "max-parent-recursive-depth": 0, "resolve-transitive-dependencies": false, "use-maven-localrepository": false, "use-network": false }, "javascript": { "include-dev-dependencies": false, "npm-base-url": "``https://registry.npmjs.org``", "search-remote-licenses": false }, "linux-kernel": { "catalog-modules": true }, "nix": { "capture-owned-files": false }, "python": { "guess-unpinned-requirements": false } }, "relationships": { "exclude-binary-packages-with-file-ownership-overlap": true, "package-file-ownership": true, "package-file-ownership-overlap": true }, "search": { "scope": "squashed" } } }, "schema": { "version": "16.0.37", "url": "``https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-16.0.37.json``" } }

Thanks for your response. We found that Graalvm-jdk-21 does not include PURL in the embedded SBOM. Its only included from release > 24

1 Like