Skip to content

ref(download): Use download service for objectstore requests - #1928

Draft
jjbayer wants to merge 9 commits into
masterfrom
ref/apple-download-2
Draft

ref(download): Use download service for objectstore requests#1928
jjbayer wants to merge 9 commits into
masterfrom
ref/apple-download-2

Conversation

@jjbayer

@jjbayer jjbayer commented Apr 14, 2026

Copy link
Copy Markdown
Member

Follow up to #1924: Using the existing service would have prevented the bug in the first place.

Base automatically changed from fix/apple-download-rewind to master April 14, 2026 11:04
jjbayer added a commit that referenced this pull request Apr 14, 2026
Downloads from objectstore did not rewind the `File` object after
downloading, leading to seemingly empty crash reports. This did not
cause an issue for minidumps because they are mapped as `ByteView`.

Follow-up: Use the existing download service
(#1928).

Fixes #1884.
Dav1dde added a commit that referenced this pull request May 6, 2026
Ideally we'd be using the download service directly (as noted in the
comment), there is an attempt in #1928 but requires a bit more thought
and work.

Right now we do see some download failures which can be mitigated with
retries. So while it's not great and makes the `GenericErrorHandler`
public with a helper fn, it's what we got.
@jjbayer jjbayer closed this Jun 9, 2026
@jjbayer

jjbayer commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

Closed the wrong PR.

@jjbayer jjbayer reopened this Jun 9, 2026
Comment on lines +31 to +36
fetch_file(
download_svc,
RemoteFile::Http(http_remote_file),
&mut temp_file,
)
.await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remote minidump attachment decompression has no effective CPU bound despite 15GiB output cap

An attacker-controlled storage URL can serve a tiny zstd/gzip/zlib/zip/CAB payload that fetch_file synchronously inflates into a temporary file after the download timeout has ended. Although output is capped at the default 15GiB, the decompression and subsequent minidump processing have no decompression-specific CPU budget; the outer request timeout cannot preempt this synchronous block, allowing substantial CPU and disk exhaustion on the shared worker pool.

Evidence
  • /symbolicate-any accepts attacker-controlled storage_url values and constructs AttachmentFile::Remote; process_minidump passes them to download_attachment (crates/symbolicator/src/endpoints/symbolicate_any.rs:42-72, crates/symbolicator-native/src/symbolication/process_minidump.rs:602-634).
  • download_attachment calls fetch_file (crates/symbolicator-native/src/symbolication/attachments.rs:23-36), which invokes DownloadService::download and then synchronously calls maybe_decompress_file after the download timeout (crates/symbolicator-service/src/download/fetch_file.rs:18-37).
  • maybe_decompress_file uses take(max_uncompressed_size + 1) but still copies up to the configured limit into a temporary file before checking its size; the shipped default is 15GiB and no CPU or decompression-time budget exists (crates/symbolicator-service/src/download/compression.rs:31-145, crates/symbolicator-service/src/config.rs:553-556,670-674).
  • The resulting file is mapped and parsed before minidump stackwalking (crates/symbolicator-native/src/symbolication/process_minidump.rs:628-634,491); processing runs on the CPU pool and the default request admission limit allows 200 concurrent requests (crates/symbolicator/src/service.rs:242-259,428-518).

Identified by Warden · wrdn-dos-review · MZN-DLX

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.

1 participant