From 2b2a0e04b259e282fd6c022b5778d9f4b67ed943 Mon Sep 17 00:00:00 2001 From: Christophe Dufaza Date: Mon, 22 Jul 2024 16:31:27 +0200 Subject: [PATCH] west: blobs: verify fetched blobs after downloading Running 'west blobs fetch' does not verify the digest of downloaded files: 1. if the checksum of the previously downloaded file does match that in the blob metadata (status BLOB_PRESENT), do nothing 2. if the checksum of the previously downloaded file does not match that in the blob metadata (status BLOB_OUTDATED), download the "up to date" file 3. if the blob has not yet been downloaded (status BLOB_NOT_PRESENT), download it None of the 2) and 3) code paths will verify that the checksum of the file just downloaded actually matches the digest in the blob's metadata. In the event that the metadata of a module is incorrect, then the user will not notice anything, and may rely on an unexpected binary, e.g. a static library for a different architecture. According to the Binary Blobs documentation [1], the expected behavior is to check the blob digest after downloading. [1] Fetching blobs, Zephyr 3.6.0 (still applies to Zephyr 3.7.0rc3) docs.zephyrproject.org/3.6.0/contribute/bin_blobs.html#fetching-blobs Signed-off-by: Christophe Dufaza --- scripts/west_commands/blobs.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/scripts/west_commands/blobs.py b/scripts/west_commands/blobs.py index 2c841efac5f..2574b26056d 100644 --- a/scripts/west_commands/blobs.py +++ b/scripts/west_commands/blobs.py @@ -119,6 +119,29 @@ class Blobs(WestCommand): self.ensure_folder(path) inst.fetch(url, path) + # Compare the checksum of a file we've just downloaded + # to the digest in blob metadata, warn user if they differ. + def verify_blob(self, blob): + log.dbg('Verifying blob {module}: {abspath}'.format(**blob)) + + status = zephyr_module.get_blob_status(blob['abspath'], blob['sha256']) + if status == zephyr_module.BLOB_OUTDATED: + log.err(textwrap.dedent( + f'''\ + The checksum of the downloaded file does not match that + in the blob metadata: + - if it is not certain that the download was successful, + try running 'west blobs fetch {blob['module']}' + to re-download the file + - if the error persists, please consider contacting + the maintainers of the module so that they can check + the corresponding blob metadata + + Module: {blob['module']} + Blob: {blob['path']} + URL: {blob['url']} + Info: {blob['description']}''')) + def fetch(self, args): blobs = self.get_blobs(args) for blob in blobs: @@ -127,6 +150,7 @@ class Blobs(WestCommand): continue log.inf('Fetching blob {module}: {abspath}'.format(**blob)) self.fetch_blob(blob['url'], blob['abspath']) + self.verify_blob(blob) def clean(self, args): blobs = self.get_blobs(args)