From bfe9be7a46cfd3b3069c15f7ba1432192bca1f5b Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Tue, 30 Apr 2024 22:22:45 +0300 Subject: [PATCH] liblzma: Fix incorrect function type error from sanitizer Clang 17 with -fsanitize=address,undefined: src/liblzma/common/filter_common.c:366:8: runtime error: call to function encoder_find through pointer to incorrect function type 'const lzma_filter_coder *(*)(unsigned long)' src/liblzma/common/filter_encoder.c:187: note: encoder_find defined here Use a wrapper function to get the correct type neatly. This reduces the number of casts needed too. This issue could be a problem with control flow integrity (CFI) methods that check the function type on indirect function calls. Fixes: 3b34851de1eaf358cf9268922fa0eeed8278d680 (cherry picked from commit 278563ef8f2b8d98d7f2c85e1a64ec1bc21d26d8) --- src/liblzma/common/filter_decoder.c | 15 ++++++++++++--- src/liblzma/common/filter_encoder.c | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/liblzma/common/filter_decoder.c b/src/liblzma/common/filter_decoder.c index 77441e54..cbdeb585 100644 --- a/src/liblzma/common/filter_decoder.c +++ b/src/liblzma/common/filter_decoder.c @@ -150,6 +150,16 @@ decoder_find(lzma_vli id) } +// lzma_filter_coder begins with the same members as lzma_filter_decoder. +// This function is a wrapper with a type that is compatible with the +// typedef of lzma_filter_find in filter_common.h. +static const lzma_filter_coder * +coder_find(lzma_vli id) +{ + return (const lzma_filter_coder *)decoder_find(id); +} + + extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id) { @@ -162,7 +172,7 @@ lzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *options) { return lzma_raw_coder_init(next, allocator, - options, (lzma_filter_find)(&decoder_find), false); + options, &coder_find, false); } @@ -181,8 +191,7 @@ lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options) extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters) { - return lzma_raw_coder_memusage( - (lzma_filter_find)(&decoder_find), filters); + return lzma_raw_coder_memusage(&coder_find, filters); } diff --git a/src/liblzma/common/filter_encoder.c b/src/liblzma/common/filter_encoder.c index 523d3731..bc394448 100644 --- a/src/liblzma/common/filter_encoder.c +++ b/src/liblzma/common/filter_encoder.c @@ -193,6 +193,16 @@ encoder_find(lzma_vli id) } +// lzma_filter_coder begins with the same members as lzma_filter_encoder. +// This function is a wrapper with a type that is compatible with the +// typedef of lzma_filter_find in filter_common.h. +static const lzma_filter_coder * +coder_find(lzma_vli id) +{ + return (const lzma_filter_coder *)encoder_find(id); +} + + extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id) { @@ -232,7 +242,7 @@ lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *filters) { return lzma_raw_coder_init(next, allocator, - filters, (lzma_filter_find)(&encoder_find), true); + filters, &coder_find, true); } @@ -240,7 +250,7 @@ extern LZMA_API(lzma_ret) lzma_raw_encoder(lzma_stream *strm, const lzma_filter *filters) { lzma_next_strm_init(lzma_raw_coder_init, strm, filters, - (lzma_filter_find)(&encoder_find), true); + &coder_find, true); strm->internal->supported_actions[LZMA_RUN] = true; strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true; @@ -253,8 +263,7 @@ lzma_raw_encoder(lzma_stream *strm, const lzma_filter *filters) extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters) { - return lzma_raw_coder_memusage( - (lzma_filter_find)(&encoder_find), filters); + return lzma_raw_coder_memusage(&coder_find, filters); }