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 SBOM generation inconsistency #61

Merged
merged 1 commit into from
Oct 11, 2023

Conversation

damdo
Copy link
Contributor

@damdo damdo commented Sep 10, 2023

Currently SBOMs may have inconsistent hashing of the configuration file.

The representation of the config file in fact may differ at certain stages of the gok commands lifecycle, where at packer running time for example, extra InternalCompatibilityFlags would be added in memory (while that not being the case at gok sbom time), resulting in a differing config and as such differing SBOM hashes. The same would happen due to the differing pointer addresses in the config that resulted in differing hashing results.

This is now fixed by removing the InternalCompatibilityFlags from the config prior to its hashing, as well as converting the config into a string before performing the hash computation, to avoid hashing pointers problems.

@stapelberg
Copy link
Contributor

Currently SBOMs may have inconsistent hashing of the configuration file.

Can you elaborate about where you ran into this?

This is now fixed by removing the InternalCompatibilityFlags from the config prior to its hashing, as well as converting the config into a string before performing the hash computation, to avoid hashing pointers problems.

This approach has the downside of being destructive with regards to InternalCompatibilityFlags, though, right? If I change the config.json and just add another flag in InternalCompatibilityFlags, it would show up as the same SBOM? That does not sound good.

Maybe this should be fixed in a different place instead?

@damdo
Copy link
Contributor Author

damdo commented Oct 3, 2023

Currently SBOMs may have inconsistent hashing of the configuration file.

Can you elaborate about where you ran into this?

Sure. It is 100% of the time reproducible for me.

# create a gaf disk for the instance
root@00a1d367c15f:~/gokrazy/test# GOARCH=amd64 ../../gok -i test --parent_dir="./.." overwrite --gaf /tmp/disk.gaf 2>&1 >/dev/null

# extract the sbom.json and read the hash
root@00a1d367c15f:~/gokrazy/test# unzip -p /tmp/disk.gaf sbom.json | jq -r '.sbom_hash'
955b4c96886d1e109d8a82e1f2054c67948d4afaab34c374d0c4b09b8ca32d8b

# invoke gok sbom directly
root@00a1d367c15f:~/gokrazy/test# GOARCH=amd64 ../../gok -i test --parent_dir="./.." sbom | jq -r '.sbom_hash'
865418423a176b1caad2e2fae11cc5238ac986a61bed1a15cc3385384c0ba462

# the two hashes differ (while always both staying consistent in value on multiple runs)

Aside from the pointers (which cause diff in the byte representation of the formattedCfg but that can be easily rectified by reconverting that to a string representation before formatting it in hexadecimal. As fixed in the PR (let me know if you are happy with this))

The remaining diff is caused by the InternalCompatibilityFlags.
This can be seen by dumping the stringyfied formattedCfg to disk both during sbom generation, and run the overwrite (to gaf) and the sbom separately, inspecting the output.

# output of gok sbom
(string) (len=799) "{\n    \"Hostname\": \"gokrazy-dummy\",\n    \"Update\": {\n        \"Hostname\": \"192.168.64.2\",\n        \"HTTPPort\": \"80\",\n        \"HTTPPassword\":
 \"OMITTED\"\n    },\n    \"Packages\": [\n        \"github.com/gokrazy/serial-busybox\",\n        \"github.com/gokrazy/breakglass\"\n    ],\n    \"PackageConfig\":
 {\n        \"github.com/gokrazy/breakglass\": {\n            \"CommandLineFlags\": [\n                \"-authorized_keys=/etc/breakglass.authorized_keys\"\n            ],\n
        \"ExtraFilePaths\": {\n                \"/etc/breakglass.authorized_keys\": \"breakglass.authorized_keys\"\n            }\n        }\n    },\n    \"SerialConsole\": \"tt
yS0,115200\",\n    \"KernelPackage\": \"github.com/rtr7/kernel\",\n    \"FirmwarePackage\": \"github.com/rtr7/kernel\",\n    \"EEPROMPackage\": \"\",\n    \"InternalCompatibilit
yFlags\": {}\n}\n"

# output of gok overwrite --gaf
(string) (len=827) "{\n    \"Hostname\": \"gokrazy-dummy\",\n    \"Update\": {\n        \"Hostname\": \"192.168.64.2\",\n        \"HTTPPort\": \"80\",\n        \"HTTPPassword\":
 \"OMITTED\"\n    },\n    \"Packages\": [\n        \"github.com/gokrazy/serial-busybox\",\n        \"github.com/gokrazy/breakglass\"\n    ],\n    \"PackageConfig\":
 {\n        \"github.com/gokrazy/breakglass\": {\n            \"CommandLineFlags\": [\n                \"-authorized_keys=/etc/breakglass.authorized_keys\"\n            ],\n
        \"ExtraFilePaths\": {\n                \"/etc/breakglass.authorized_keys\": \"breakglass.authorized_keys\"\n            }\n        }\n    },\n    \"SerialConsole\": \"tt
yS0,115200\",\n    \"KernelPackage\": \"github.com/rtr7/kernel\",\n    \"FirmwarePackage\": \"github.com/rtr7/kernel\",\n    \"EEPROMPackage\": \"\",\n    \"InternalCompatibilit
yFlags\": {\n        \"Sudo\": \"auto\"\n    }\n}\n"

As you can see the difference is in the InternalCompatibilityFlags:{"Sudo": "auto"} setting, defined during overwrite, but not during sbom.

This happens because in the gok packer logic we dynamically set the flag:

if cfg.InternalCompatibilityFlags.Sudo == "" {
cfg.InternalCompatibilityFlags.Sudo = "auto"
}

This approach has the downside of being destructive with regards to InternalCompatibilityFlags, though, right? If I change the config.json and just add another flag in InternalCompatibilityFlags, it would show up as the same SBOM? That does not sound good.

Yes good point, given those are internal flags for migrating from gokr-packer to gok (and configure the CLI meta options), I figured they wouldn't necessarily mean anything from an image build perspective, but I see your point.

What would you suggest then? Should we set InternalCompatibilityFlags:{"Sudo": "auto"} also at gok sbom invocation to avoid diff?

@stapelberg
Copy link
Contributor

Thanks for the details.

I think in this particular case it would actually be best to:

  1. introduce a SudoOrDefault() accessor to config.InternalCompatibilityFlags that returns "auto" or sudo if non-empty
  2. switch the code from .Sudo to .SudoOrDefault()
  3. remove the lines that set the option to "auto"

…and avoid the diff that way.

@damdo
Copy link
Contributor Author

damdo commented Oct 9, 2023

Yes, that makes sense to me.

I've created a PR for the accessor change here: gokrazy/internal#18
And updated this PR accordingly.

Once the accessor PR merges we'll need to remove. the replace directive before merging this PR.

@damdo damdo force-pushed the fix-sbom-generation-inconsistency branch from 2b0f193 to 04180ad Compare October 10, 2023 19:02
prior to this commit SBOMs would have inconsistency in their hashing on
the configuration file.

The representation of the config file in fact would differ at certain
stages of the gok commands lifecycle, where at packer running time,
an extra InternalCompatibilityFlag, Sudo, would be added in memory
(while that not being the case at `gok sbom` time),
resulting in a differing config and as such differing SBOM hashes, same
goes for the differing pointer addresses that were skew the hashing
results.

This is now fixed by removing the InternalCompatibilityFlag set (using
an accessor) from the
config prior to its hashing, as well as converting the config into a
string before performing the hash computation, to avoid differing pointer problems.
@damdo damdo force-pushed the fix-sbom-generation-inconsistency branch from 04180ad to 0344caa Compare October 11, 2023 06:15
@damdo
Copy link
Contributor Author

damdo commented Oct 11, 2023

Replace directive removed and newest gokrazy/internal referenced.
Ready a review @stapelberg :)

@stapelberg stapelberg merged commit 84c24f7 into gokrazy:main Oct 11, 2023
1 check passed
@damdo damdo mentioned this pull request Oct 22, 2023
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.

2 participants