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: 3b34851de1
(cherry picked from commit 278563ef8f)
This commit is contained in:
Lasse Collin 2024-04-30 22:22:45 +03:00
parent 882eadc5b8
commit bfe9be7a46
2 changed files with 25 additions and 7 deletions

View File

@ -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) extern LZMA_API(lzma_bool)
lzma_filter_decoder_is_supported(lzma_vli id) 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) const lzma_filter *options)
{ {
return lzma_raw_coder_init(next, allocator, 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) extern LZMA_API(uint64_t)
lzma_raw_decoder_memusage(const lzma_filter *filters) lzma_raw_decoder_memusage(const lzma_filter *filters)
{ {
return lzma_raw_coder_memusage( return lzma_raw_coder_memusage(&coder_find, filters);
(lzma_filter_find)(&decoder_find), filters);
} }

View File

@ -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) extern LZMA_API(lzma_bool)
lzma_filter_encoder_is_supported(lzma_vli id) 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) const lzma_filter *filters)
{ {
return lzma_raw_coder_init(next, allocator, 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_raw_encoder(lzma_stream *strm, const lzma_filter *filters)
{ {
lzma_next_strm_init(lzma_raw_coder_init, strm, 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_RUN] = true;
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = 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) extern LZMA_API(uint64_t)
lzma_raw_encoder_memusage(const lzma_filter *filters) lzma_raw_encoder_memusage(const lzma_filter *filters)
{ {
return lzma_raw_coder_memusage( return lzma_raw_coder_memusage(&coder_find, filters);
(lzma_filter_find)(&encoder_find), filters);
} }