Skip to content

Fix DATA_FORMAT printf/scanf for 32-bit architectures with 64-bit off_t#411

Open
daichifukui wants to merge 1 commit into
linux-application-whitelisting:mainfrom
daichifukui:dfukui/fix-data-format
Open

Fix DATA_FORMAT printf/scanf for 32-bit architectures with 64-bit off_t#411
daichifukui wants to merge 1 commit into
linux-application-whitelisting:mainfrom
daichifukui:dfukui/fix-data-format

Conversation

@daichifukui

Copy link
Copy Markdown
Contributor

On 32-bit architectures where _FILE_OFFSET_BITS=64 is defined (e.g. by a distribution's build system), off_t is 64-bit while size_t remains 32-bit. The trust database format macros DATA_FORMAT and DATA_FORMAT_IN used %zu, which expects a size_t-sized argument. Passing off_t values with %zu causes two distinct problems:

  • printf/snprintf: a 64-bit off_t argument misaligns the variadic argument stack on 32-bit ARM, causing the subsequent %s to be read from the wrong location and producing corrupt output.
  • scanf/sscanf: %zu writes only 4 bytes into an 8-byte off_t, leaving the upper half corrupted, which can cause file size comparisons to fail.

This fix changes DATA_FORMAT and DATA_FORMAT_IN to use %llu, and updates all call sites to cast file size values to unsigned long long for printf-family calls and to use an intermediate unsigned long long ull_size variable for scanf-family calls before assigning back to off_t.

This issue was originally identified as a build failure (FTBFS) on armhf in Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1132273. The root cause is that Debian injects -D_FILE_OFFSET_BITS=64 via dpkg-buildflags for all packages on 32-bit architectures. Any other distribution or build environment that defines _FILE_OFFSET_BITS=64 on a 32-bit target will encounter the same issue, so this fix is beneficial beyond Debian.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the handling of file sizes across the codebase to use unsigned long long (ull_size) when parsing database records, preventing potential overflow and formatting issues. However, several review comments point out that the size variable (of type off_t) has become redundant in multiple functions (such as do_dump_db, handle_record, main in trustdb_format_test.c, and test_data_format_round_trip) and can be safely removed. Additionally, casting ull_size to off_t on 32-bit systems without _FILE_OFFSET_BITS=64 can cause sign extension issues when printing, which can be avoided by using ull_size directly.

Comment thread src/cli/fapolicyd-cli.c Outdated
Comment thread src/cli/fapolicyd-cli.c Outdated
Comment thread src/library/database.c Outdated
Comment thread src/library/database.c Outdated
Comment thread src/tests/trustdb_format_test.c Outdated
Comment thread src/tests/trustdb_format_test.c Outdated
Comment thread src/tests/trustdb_lmdb_test.c Outdated
Comment thread src/tests/trustdb_lmdb_test.c Outdated
On 32-bit architectures built with _FILE_OFFSET_BITS=64, off_t is 64-bit
but size_t is 32-bit. Using %zu for an off_t field causes scanf to write
only 4 bytes into an 8-byte off_t, corrupting the upper half.

Switch to %llu with explicit casts throughout.
@daichifukui daichifukui force-pushed the dfukui/fix-data-format branch from af7f790 to a62e190 Compare May 29, 2026 04:44
@stevegrubb

Copy link
Copy Markdown
Member

32 bit architecture is not a priority for this project.

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