]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
liblzma: Fix incorrect function type error from sanitizer
authorLasse Collin <lasse.collin@tukaani.org>
Tue, 30 Apr 2024 19:22:45 +0000 (22:22 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Tue, 21 May 2024 21:12:07 +0000 (00:12 +0300)
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
src/liblzma/common/filter_encoder.c

index fa53f5bdbad02ac894c231957eebb9e935c09c25..7090e9eacc792b141b7a1e09fb78f418d231d1d0 100644 (file)
@@ -143,6 +143,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)
 {
@@ -155,7 +165,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);
 }
 
 
@@ -174,8 +184,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);
 }
 
 
index c7777dfef8ebc0bc749f206a54942723a197385e..2def78ac3b7057a11f73158099c9f61fb7d80055 100644 (file)
@@ -183,6 +183,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)
 {
@@ -222,7 +232,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);
 }
 
 
@@ -230,7 +240,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;
@@ -243,8 +253,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);
 }