|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
sfnt (TrueType/OpenType) table-directory bounds guard for stb_truetype. More...
#include <stddef.h>#include <stdint.h>Go to the source code of this file.
Functions | |
| bool | ra8_stbtt_sfnt_dir_in_bounds (const uint8_t *data, size_t len, uint32_t fontstart) |
| Verify that a font's sfnt table directory lies within its buffer. | |
sfnt (TrueType/OpenType) table-directory bounds guard for stb_truetype.
The vendored stb_truetype (apps/shared_libs/third_party/stb/stb_truetype.h) parses the sfnt table directory using the numTables count and the per-table offset/length fields read straight out of the font file, with no check that those values stay inside the supplied buffer. stbtt_InitFont() -> stbtt__find_table() therefore walks past the end of a crafted font and performs an out-of-bounds read (SEGV under AddressSanitizer). stb_truetype never takes a buffer length, so it cannot self-defend.
The e-reader feeds stbtt_InitFont() fully attacker-controlled bytes: the @font-face fonts embedded in an EPUB (via reflow_register_face() / reflow_bind_font()) and the book font attached with epub_set_font(). An attacker-supplied EPUB can thus reach the unguarded parse on-device.
ra8_stbtt_sfnt_dir_in_bounds validates the full offset table + table directory against the buffer length before stbtt_InitFont() is invoked, so the firmware rejects a malformed font cleanly instead of dereferencing past its buffer. It is a pure, heap-free byte validator: it includes no stb_truetype internals and touches no hardware.
[Ring 4 / Reflow] {World: NS}
Definition in file ra8_stbtt_guard.h.
| bool ra8_stbtt_sfnt_dir_in_bounds | ( | const uint8_t * | data, |
| size_t | len, | ||
| uint32_t | fontstart ) |
Verify that a font's sfnt table directory lies within its buffer.
Mirrors exactly the reads stbtt_InitFont() / stbtt__find_table() make while walking the sfnt offset table, table directory, and the table-internal fields InitFont reads, and confirms each one stays inside [0, len):
All arithmetic is performed in uint64_t so that a hostile fontstart (up to UINT32_MAX, e.g. a crafted TrueType-collection sub-font offset) or a hostile per-table offset/length cannot overflow the bound computation. The function bounds every read stbtt_InitFont() itself issues. It does NOT bound the deeper reads the glyph-lookup / rasterisation path makes after init (stbtt_FindGlyphIndex following an attacker-controlled cmap subtable offset, then the loca / glyf outline walk); stb_truetype does not bound those against the buffer either, so a crafted font can still drive an out-of-bounds read there. Hardening that deeper path is tracked separately as parser hardening (issue #179); it is a much larger change than this directory pre-check.
| [in] | data | Pointer to the first byte of the font buffer. |
| [in] | len | Length of the font buffer, bytes. |
| [in] | fontstart | Byte offset of this font's sfnt offset table within data (0 for a bare TTF/OTF; the sub-font offset for a TrueType collection). This is the same value passed as the offset argument to stbtt_InitFont(). |
| true | The directory is in bounds; stbtt_InitFont() may safely walk it. |
| false | data is nullptr, or the offset table / directory / any table record / a cmap-head-maxp internal read extends past len – reject the font. |
data references at least len readable bytes (or is nullptr). len is the true byte length of the buffer data points to. data and the buffer it points to are unmodified (pure read). Definition at line 204 of file ra8_stbtt_guard.c.
References internal_rd_be_u16(), internal_rd_be_u32(), internal_table_internal_in_bounds(), k_sfnt_num_tables_off, k_sfnt_offset_table_bytes, k_sfnt_record_length_off, k_sfnt_record_offset_off, k_sfnt_record_tag_off, and k_sfnt_table_record_bytes.
Referenced by internal_font_init(), reflow_bind_font(), and reflow_register_face().