|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Bounded, fail-closed XZ/LZMA2 decoding over the vendored xz-embedded. More...
#include <stddef.h>#include <stdint.h>#include "ra8_decomp_limits.h"#include "ra8_err.h"#include "unarch_io.h"Go to the source code of this file.
Data Structures | |
| struct | unarch_xz_stream_t |
| One multi-call XZ decode session (opaque decoder + liveness flag). More... | |
Enumerations | |
| enum | unarch_xz_dims_t : uint32_t { k_unarch_xz_state_reserve = 64U * 1024U , k_unarch_xz_sig_len = 6U } |
| Scratch sizing constants for the XZ decoder wrappers. More... | |
Functions | |
| bool | unarch_xz_magic (const uint8_t *sig, size_t sig_len) |
Whether sig begins with the XZ stream header magic. | |
| ra8_err_t | unarch_xz_stream_begin (unarch_xz_stream_t *xs, void *scratch, uint32_t scratch_len) |
| Begin a multi-call XZ decode session over a caller scratch. | |
| ra8_err_t | unarch_xz_stream_run (unarch_xz_stream_t *xs, const uint8_t *in, size_t in_len, size_t *in_used, uint8_t *out, size_t out_cap, size_t *out_used, bool *end) |
| Feed one input chunk through a live session, producing output. | |
| void | unarch_xz_stream_end (unarch_xz_stream_t *xs) |
| End a session: free the decoder and release the allocation pool. | |
| ra8_err_t | unarch_xz_unwrap (unarch_read_fn read, void *ctx, uint64_t size, uint8_t *out, size_t out_cap, void *scratch, uint32_t scratch_len, const ra8_decomp_limits_t *limits, size_t *out_len) |
| Decode one whole XZ stream from a read seam into a caller arena. | |
Bounded, fail-closed XZ/LZMA2 decoding over the vendored xz-embedded.
The XZ leg of the archive-hardening subsystem, wrapping the vendored SOUP decoder (apps/shared_libs/third_party/xz_embedded/, decode-only, 0BSD) behind two bounded shapes:
Integrity is verified by the decoder (CRC32 and the xz(1) default CRC64); a stream using an unsupported check or filter (SHA-256, BCJ, delta) is rejected cleanly, never mis-decoded. Trailing bytes after the stream footer are rejected (no multi-stream concatenation).
Definition in file unarch_xz.h.
| enum unarch_xz_dims_t : uint32_t |
Scratch sizing constants for the XZ decoder wrappers.
k_unarch_xz_state_reserve is the slice of a streaming session's scratch reserved for xz-embedded's decoder state (struct xz_dec plus the LZMA2 state, ~30 KiB measured; reserved with margin); the remainder becomes the preallocated LZMA2 dictionary, so scratch_len - reserve is the largest dictionary a stream may declare. k_unarch_xz_sig_len is the length of the XZ stream header magic used for container detection.
| Enumerator | |
|---|---|
| k_unarch_xz_state_reserve | Decoder-state slice of the scratch. |
| k_unarch_xz_sig_len | XZ stream header magic length. |
Definition at line 70 of file unarch_xz.h.
|
nodiscard |
Whether sig begins with the XZ stream header magic.
Pure signature probe over the six magic bytes (FD 37 7A 58 5A 00) so open paths can route a wrapped archive without constructing a decoder.
| [in] | sig | Leading archive bytes (may be NULL). |
| [in] | sig_len | Readable length of sig in bytes. |
| true | The six magic bytes match. |
| false | sig is NULL, too short, or not XZ. |
sig holds sig_len readable bytes when non-NULL. sig_len is the true readable length (untrusted values are safe). Definition at line 77 of file unarch_xz.c.
References k_unarch_xz_sig_len, k_xz_magic_b0, k_xz_magic_b1, k_xz_magic_b2, k_xz_magic_b3, k_xz_magic_b4, k_xz_magic_b5, and memeq.
Referenced by comic_open_wrapped(), and internal_open_unwrapped().
|
nodiscard |
Begin a multi-call XZ decode session over a caller scratch.
Installs scratch as the XZ allocation arena and creates an XZ_PREALLOC decoder whose dictionary budget is scratch_len - k_unarch_xz_state_reserve: the dictionary is allocated once at init and never grows, and a stream declaring a larger dictionary is rejected during _run (no growth, no fallback).
| [out] | xs | Session to bind (non-NULL). |
| [in] | scratch | Scratch buffer (non-NULL, 8-byte aligned). |
| [in] | scratch_len | Scratch length, > k_unarch_xz_state_reserve. |
| k_ra8_ok | Session live; feed it via _run. |
| k_ra8_err_null_ptr | xs or scratch was NULL. |
| k_ra8_err_invalid_size | Scratch too small or misaligned. |
| k_ra8_err_busy | Another XZ session is in flight. |
| k_ra8_err_no_mem | Decoder-state allocation failed. |
scratch out-lives the session. xs is dead.Definition at line 96 of file unarch_xz.c.
References unarch_xz_stream_t::dec, k_ra8_err_invalid_size, k_ra8_err_no_mem, k_ra8_ok, k_unarch_xz_state_reserve, unarch_xz_stream_t::live, RA8_CHECK_NULL_PTR, s_tag_xz, unarch_xz_pool_install(), and unarch_xz_pool_reset().
Referenced by unarch_xz_unwrap().
| void unarch_xz_stream_end | ( | unarch_xz_stream_t * | xs | ) |
End a session: free the decoder and release the allocation pool.
Safe on a NULL or never-begun session (teardown paths call it unconditionally). After this the caller's scratch is dead storage again and a new session may begin.
| [in,out] | xs | Session to end (may be NULL). |
xs, when live, owns the installed pool. xs. Definition at line 212 of file unarch_xz.c.
References unarch_xz_stream_t::dec, unarch_xz_stream_t::live, and unarch_xz_pool_reset().
Referenced by unarch_xz_unwrap().
|
nodiscard |
Feed one input chunk through a live session, producing output.
One xz_dec_run pass: consumes up to in_len input bytes and writes up to out_cap output bytes, reporting both counts and whether the stream ended. The caller loops – charging its own ra8_decomp_budget_t per pass – until *end or an error. Returning with zero consumed and zero produced is legal decoder behaviour on tiny buffers; the caller's iteration budget bounds the loop regardless (the decoder itself also reports a stuck stream as a validation failure).
| [in,out] | xs | Live session (non-NULL). |
| [in] | in | Input chunk (non-NULL when in_len > 0). |
| [in] | in_len | Input bytes available. |
| [out] | in_used | Receives input bytes consumed (non-NULL). |
| [out] | out | Output chunk buffer (non-NULL). |
| [in] | out_cap | Output capacity in bytes. |
| [out] | out_used | Receives output bytes produced (non-NULL). |
| [out] | end | Receives true when the stream verified and ended (non-NULL). |
| k_ra8_ok | Pass completed; inspect the counts. |
| k_ra8_err_null_ptr | A required pointer was NULL. |
| k_ra8_err_invalid_state | xs is not live. |
| k_ra8_err_no_mem | Declared dictionary exceeds the session's scratch budget. |
| k_ra8_err_not_supported | Unsupported format/check/filter. |
| k_ra8_err_validation_failed | Corrupt / truncated stream, a failed integrity check, or a stuck stream. |
xs. out holds out_cap writable bytes. Definition at line 168 of file unarch_xz.c.
References unarch_xz_stream_t::dec, internal_xz_map_err(), k_ra8_err_invalid_state, k_ra8_ok, unarch_xz_stream_t::live, RA8_CHECK_NULL_PTR, and s_tag_xz.
Referenced by internal_unwrap_pass().
|
nodiscard |
Decode one whole XZ stream from a read seam into a caller arena.
Runs a full streaming session over [0, size) of the backing: input is fetched in small fixed chunks, each decode pass is charged against limits (iteration budget, output cap, ratio bound), and the stream's integrity check is verified before success. Fail-closed on everything else: truncation, corruption, an unsupported check/filter, a dictionary larger than the scratch budget, output overrun, and trailing bytes after the stream footer.
| [in] | read | Byte reader over the XZ stream (non-NULL). |
| [in] | ctx | Context passed to read. |
| [in] | size | Stream length in bytes (> 0). |
| [out] | out | Destination arena (non-NULL, out_cap bytes). |
| [in] | out_cap | Capacity of out in bytes (> 0). |
| [in] | scratch | Session scratch (non-NULL, 8-byte aligned, > k_unarch_xz_state_reserve bytes). |
| [in] | scratch_len | Scratch length in bytes. |
| [in] | limits | Policy to enforce, or NULL for the default. |
| [out] | out_len | Receives the decoded byte count (non-NULL). |
| k_ra8_ok | Stream decoded and verified. |
| k_ra8_err_null_ptr | A required pointer was NULL. |
| k_ra8_err_invalid_size | size / out_cap is 0, or the scratch is undersized / misaligned. |
| k_ra8_err_invalid_arg | limits has a zero field. |
| k_ra8_err_busy | Another XZ session is in flight. |
| k_ra8_err_no_mem | Decoder-state allocation failed, the declared dictionary exceeds the scratch budget, or out is too small for the stream. |
| k_ra8_err_not_supported | Not an XZ stream, or one using an unsupported check/filter. |
| k_ra8_err_validation_failed | Corrupt / truncated / trailing-byte stream or a failed integrity check. |
| k_ra8_err_decomp_output_cap | Output exceeds the policy cap. |
| k_ra8_err_decomp_ratio | Output breached the ratio bound. |
| k_ra8_err_decomp_iterations | The decode loop budget ran out. |
read serves offsets [0, size) of the stream. Definition at line 351 of file unarch_xz.c.
References xz_unwrap_state_t::budget, xz_unwrap_state_t::ctx, xz_unwrap_state_t::in_off, internal_unwrap_pass(), internal_unwrap_reject_null(), k_ra8_err_invalid_size, k_ra8_err_validation_failed, k_ra8_ok, xz_unwrap_state_t::out, xz_unwrap_state_t::out_cap, ra8_decomp_budget_init(), xz_unwrap_state_t::read, xz_unwrap_state_t::size, xz_unwrap_state_t::total_out, unarch_xz_stream_begin(), unarch_xz_stream_end(), and xz_unwrap_state_t::xs.
Referenced by internal_unwrap().