logging: Add string validation to detect %p misuse
Logging shall not use character pointers with %p because in certain configurations it may lead to memory faults. A compile time detection is added. If faulty usage is detected then message is replaced with error message which indicates which message failed and what shall be done (casting to a pointer of different type). Validation is enabled only for configurations which remove strings from binary as otherwise it may impact CI execution time. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
aa2e315ab0
commit
465446e5aa
|
@ -190,6 +190,30 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
|
||||
#define Z_LOG_INST(_inst) COND_CODE_1(CONFIG_LOG, (_inst), NULL)
|
||||
|
||||
/* If strings are removed from the binary then there is a risk of creating invalid
|
||||
* cbprintf package if %p is used with character pointer which is interpreted as
|
||||
* string. A compile time check is performed (since format string is known at
|
||||
* compile time) and check fails logging message is not created but error is
|
||||
* emitted instead. String check may increase compilation time so it is not
|
||||
* always performed (could significantly increase CI time).
|
||||
*/
|
||||
#if CONFIG_LOG_FMT_STRING_VALIDATE
|
||||
#define LOG_STRING_WARNING(_mode, _src, ...) \
|
||||
Z_LOG_MSG_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \
|
||||
Z_LOG_LOCAL_DOMAIN_ID, _src, LOG_LEVEL_ERR, NULL, 0, \
|
||||
"char pointer used for %%p, cast to void *:\"%s\"", \
|
||||
GET_ARG_N(1, __VA_ARGS__))
|
||||
|
||||
#define LOG_POINTERS_VALIDATE(string_ok, ...) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
|
||||
string_ok = Z_CBPRINTF_POINTERS_VALIDATE(__VA_ARGS__); \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define LOG_POINTERS_VALIDATE(string_ok, ...) string_ok = true
|
||||
#define LOG_STRING_WARNING(_mode, _src, ...)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Macros for standard logging ******************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -234,6 +258,12 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
int _mode; \
|
||||
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
|
||||
(void *)_dsource : (void *)_source; \
|
||||
bool string_ok; \
|
||||
LOG_POINTERS_VALIDATE(string_ok, __VA_ARGS__); \
|
||||
if (!string_ok) { \
|
||||
LOG_STRING_WARNING(_mode, _src, __VA_ARGS__); \
|
||||
break; \
|
||||
} \
|
||||
Z_LOG_MSG_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \
|
||||
Z_LOG_LOCAL_DOMAIN_ID, _src, _level, NULL,\
|
||||
0, __VA_ARGS__); \
|
||||
|
|
|
@ -70,6 +70,15 @@ config LOG_FMT_SECTION_STRIP
|
|||
depends on LOG_FMT_SECTION
|
||||
depends on LINKER_DEVNULL_SUPPORT
|
||||
imply LINKER_DEVNULL_MEMORY
|
||||
imply LOG_FMT_STRING_VALIDATE
|
||||
|
||||
config LOG_FMT_STRING_VALIDATE
|
||||
bool "Validate logging strings"
|
||||
help
|
||||
Logging strings cannot use %p with character pointers. They should be
|
||||
casted to the pointer of another type (e.g. void *). With this feature
|
||||
enabled, at compile time, the preprocessor detects strings with %p
|
||||
without casting and reports an error at runtime.
|
||||
|
||||
config LOG_USE_TAGGED_ARGUMENTS
|
||||
bool "Using tagged arguments for packaging"
|
||||
|
|
Loading…
Reference in a new issue