fix: zero-init struct tm before gmtime_r; replace strcpy with memcpy#2753
fix: zero-init struct tm before gmtime_r; replace strcpy with memcpy#2753stark256-spec wants to merge 1 commit into
Conversation
Two independent static-analysis findings addressed in one commit since they touch disjoint files and carry the same risk category. 1. cfe_time_api.c — CFE_TIME_Print (fixes nasa#2735) gmtime_r() returns NULL when the input time_t is outside the range representable by struct tm (overflow or platform-specific limits). The subsequent strftime() then reads from an uninitialised struct, producing undefined behaviour. Zero-initialise tm with memset before calling gmtime_r() so that a failed conversion yields a deterministic epoch-like formatted string rather than garbage or a crash. 2. cfe_assert_init.c + cfe_tbl_internal.c — strcpy (fixes nasa#2737) Both sites append a known, fixed-length literal ('.tmp' and '(*)') into a buffer where available space has already been verified by the surrounding bounds check. Replace strcpy with memcpy(dst, literal, sizeof(literal)) which copies exactly the required bytes including the NUL terminator without relying on runtime null-termination scanning.
|
Thank you @stark256-spec for this contribution! Can you provide some more context behind this solution and steps you followed to verify it? |
|
Sure, happy to give more detail. Context for the changes: All three are static-analysis findings (the "uninitialized read" / "unbounded strcpy" kind that show up in Coverity/cppcheck-style scans):
How I verified it: Built this branch with unit tests enabled (
On the gmtime_r path specifically - I didn't add a new test for the "gmtime_r returns NULL" branch itself, on purpose. |
Fixes #2735 and #2737.
#2735 —
gmtime_r()returns NULL for out-of-rangetime_tvalues, leavingstruct tmuninitialised.strftime()on uninitialised memory is UB. Zero-initialisetmwithmemset()before callinggmtime_r()so a failed conversion produces a deterministic epoch-like string.#2737 — Both
strcpysites incfe_assert_init.candcfe_tbl_internal.cappend a fixed-length literal into a buffer where space was already verified. Replace withmemcpy(dst, literal, sizeof(literal))to copy exactly the required bytes including the NUL terminator.