]> 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:34:26 +0000 (00:34 +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)
(cherry picked from commit 64e0a5f726c483bdda2ee35ed7ae5f515278272f)

src/liblzma/common/filter_decoder.c
src/liblzma/common/filter_encoder.c

index c75b0a89c30fdad2bd78eded2135e9e497e5f0ed..d19cc033767e5c5eddd2ed40d2eceab212ffa675 100644 (file)
@@ -129,6 +129,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)
 {
@@ -141,7 +151,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);
 }
 
 
@@ -160,8 +170,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 6e7399295e1c0b5b1bb1009ce50e70f173986368..388eb6ec09ec5bd919d275bf27b7edc9cced634d 100644 (file)
@@ -164,6 +164,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)
 {
@@ -203,7 +213,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);
 }
 
 
@@ -211,7 +221,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;
@@ -224,8 +234,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);
 }