[GH-ISSUE #313] stack-buffer-overflow in worksheet_insert_image_buffer_opt #253

Closed
opened 2026-05-05 12:02:40 -06:00 by gitea-mirror · 8 comments
Owner

Originally created by @MrBeanc on GitHub (Nov 6, 2020).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/313

Originally assigned to: @jmcnamara on GitHub.

I think I found a stack overflow vulnerability,Here are the details

==21786==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffcee11968 at pc 0x00000046ee11 bp 0x7fffcee118d0 sp 0x7fffcee11098
READ of size 10 at 0x7fffcee11968 thread T0
    #0 0x46ee10 in fwrite (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x46ee10)
    #1 0x55a6ba in worksheet_insert_image_buffer_opt /home/mimic/vul-dig/bin-file/libxlsxwriter-master/src/worksheet.c:8688:9
    #2 0x4fd480 in LLVMFuzzerTestOneInput /home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/fuzz.c:18:5
    #3 0x43b851 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x43b851)
    #4 0x423d47 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x423d47)
    #5 0x429d21 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x429d21)
    #6 0x455d82 in main (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x455d82)
    #7 0x7f9a0f6d9bf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310
    #8 0x41e139 in _start (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x41e139)

Address 0x7fffcee11968 is located in stack of thread T0 at offset 40 in frame
    #0 0x4fd2ef in LLVMFuzzerTestOneInput /home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/fuzz.c:3

  This frame has 1 object(s):
    [32, 40) 'data.addr' <== Memory access at offset 40 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x46ee10) in fwrite
Shadow bytes around the buggy address:
  0x100079dba2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100079dba320: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00[f3]f3 f3
  0x100079dba330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079dba370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==21786==ABORTING

You can reproduce it in the following ways
Add special options when compiling libxlsxwriter

cd libxlsxwriter-master
cmake . -DCMAKE_C_COMPILER=clang-9  -DCMAKE_C_FLAGS="-O2 -fno-omit-frame-pointer -g -fsanitize=address -fsanitize=fuzzer-no-link"

then compile test file

clang-9 fuzz.c -lxlsxwriter -fsanitize=address -lz -fsanitize=fuzzer -g -o fuzz

then

./fuzz crash-892c3965551aa65297eaacf07935ab3adcacf2c0

You can also find a crash in the following ways

./fuzz

i put test file and crash in zip。
fuzz.zip

Originally created by @MrBeanc on GitHub (Nov 6, 2020). Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/313 Originally assigned to: @jmcnamara on GitHub. I think I found a stack overflow vulnerability,Here are the details ``` ==21786==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffcee11968 at pc 0x00000046ee11 bp 0x7fffcee118d0 sp 0x7fffcee11098 READ of size 10 at 0x7fffcee11968 thread T0 #0 0x46ee10 in fwrite (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x46ee10) #1 0x55a6ba in worksheet_insert_image_buffer_opt /home/mimic/vul-dig/bin-file/libxlsxwriter-master/src/worksheet.c:8688:9 #2 0x4fd480 in LLVMFuzzerTestOneInput /home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/fuzz.c:18:5 #3 0x43b851 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x43b851) #4 0x423d47 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x423d47) #5 0x429d21 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x429d21) #6 0x455d82 in main (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x455d82) #7 0x7f9a0f6d9bf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310 #8 0x41e139 in _start (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x41e139) Address 0x7fffcee11968 is located in stack of thread T0 at offset 40 in frame #0 0x4fd2ef in LLVMFuzzerTestOneInput /home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/fuzz.c:3 This frame has 1 object(s): [32, 40) 'data.addr' <== Memory access at offset 40 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/mimic/vul-dig/bin-file/libxlsxwriter-master/fuzz-test/a.out+0x46ee10) in fwrite Shadow bytes around the buggy address: 0x100079dba2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x100079dba320: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00[f3]f3 f3 0x100079dba330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100079dba370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==21786==ABORTING ``` You can reproduce it in the following ways **Add special options when compiling libxlsxwriter** ``` cd libxlsxwriter-master cmake . -DCMAKE_C_COMPILER=clang-9 -DCMAKE_C_FLAGS="-O2 -fno-omit-frame-pointer -g -fsanitize=address -fsanitize=fuzzer-no-link" ``` **then compile test file** ``` clang-9 fuzz.c -lxlsxwriter -fsanitize=address -lz -fsanitize=fuzzer -g -o fuzz ``` **then** ``` ./fuzz crash-892c3965551aa65297eaacf07935ab3adcacf2c0 ``` **You can also find a crash in the following ways** ``` ./fuzz ``` **i put test file and crash in zip。** [fuzz.zip](https://github.com/jmcnamara/libxlsxwriter/files/5501345/fuzz.zip)
Author
Owner

@jmcnamara commented on GitHub (Nov 6, 2020):

For reference, here is the attached program:

#include "xlsxwriter.h"
#include<stdio.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){

    /* Create a new workbook and add a worksheet. */
    lxw_workbook  *workbook  = workbook_new("demo.xlsx");
    lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);

    /* Add a format. */
    lxw_format *format = workbook_add_format(workbook);

    /* Set the bold property for the format */
    format_set_bold(format);

    /* Change the column width for clarity. */
    worksheet_set_column(worksheet, 0, 0, 20, NULL);
    //worksheet_write_number(worksheet, 3, 0, size, NULL);
    worksheet_insert_image_buffer(worksheet, 0, 0, &data,size);
    workbook_close(workbook);
    //printf("success!\n");
    return 0;
}

<!-- gh-comment-id:723095544 --> @jmcnamara commented on GitHub (Nov 6, 2020): For reference, here is the attached program: ```C #include "xlsxwriter.h" #include<stdio.h> int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){ /* Create a new workbook and add a worksheet. */ lxw_workbook *workbook = workbook_new("demo.xlsx"); lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); /* Add a format. */ lxw_format *format = workbook_add_format(workbook); /* Set the bold property for the format */ format_set_bold(format); /* Change the column width for clarity. */ worksheet_set_column(worksheet, 0, 0, 20, NULL); //worksheet_write_number(worksheet, 3, 0, size, NULL); worksheet_insert_image_buffer(worksheet, 0, 0, &data,size); workbook_close(workbook); //printf("success!\n"); return 0; } ```
Author
Owner

@jmcnamara commented on GitHub (Nov 6, 2020):

Can you submit a complete program that demonstrates the issue. You can base it on this: http://libxlsxwriter.github.io/image_buffer_8c-example.html

I presume that if the size is larger than the actual data size you can get a stack overflow. Do you have any suggested mitigation?

<!-- gh-comment-id:723097959 --> @jmcnamara commented on GitHub (Nov 6, 2020): Can you submit a complete program that demonstrates the issue. You can base it on this: http://libxlsxwriter.github.io/image_buffer_8c-example.html I presume that if the size is larger than the actual data size you can get a stack overflow. Do you have any suggested mitigation?
Author
Owner

@MrBeanc commented on GitHub (Nov 8, 2020):

test4.zip
I think you should check whether the size of image_buffer is consistent with that of image_size, otherwise it will cause overflow. The examples in the document can illustrate the problem.

<!-- gh-comment-id:723586771 --> @MrBeanc commented on GitHub (Nov 8, 2020): [test4.zip](https://github.com/jmcnamara/libxlsxwriter/files/5506519/test4.zip) I think you should check whether the size of image_buffer is consistent with that of image_size, otherwise it will cause overflow. The examples in the document can illustrate the problem.
Author
Owner

@MrBeanc commented on GitHub (Nov 18, 2020):

#include "xlsxwriter.h"


unsigned char image_buffer[] = {
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
    0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
    0x08, 0x02, 0x00, 0x00, 0x00, 0xfc, 0x18, 0xed, 0xa3, 0x00, 0x00, 0x00,
    0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
    0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc,
    0x61, 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00,
    0x7a, 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00,
    0x80, 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00,
    0x3a, 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00,
    0x00, 0x46, 0x49, 0x44, 0x41, 0x54, 0x48, 0x4b, 0x63, 0xfc, 0xcf, 0x40,
    0x63, 0x00, 0xb4, 0x80, 0xa6, 0x88, 0xb6, 0xa6, 0x83, 0x82, 0x87, 0xa6,
    0xce, 0x1f, 0xb5, 0x80, 0x98, 0xe0, 0x1d, 0x8d, 0x03, 0x82, 0xa1, 0x34,
    0x1a, 0x44, 0xa3, 0x41, 0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45,
    0xa3, 0x41, 0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45, 0xa3, 0x41,
    0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45, 0x03, 0x1f, 0x44, 0x00,
    0xaa, 0x35, 0xdd, 0x4e, 0xe6, 0xd5, 0xa1, 0x22, 0x00, 0x00, 0x00, 0x00,
    0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};

unsigned int image_size = 500;

int main() {

    lxw_workbook  *workbook  = workbook_new("test_image82.xlsx");
    lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);

    worksheet_insert_image_buffer(worksheet, CELL("E9"), image_buffer, image_size);

    return workbook_close(workbook);
}
<!-- gh-comment-id:729537692 --> @MrBeanc commented on GitHub (Nov 18, 2020): ``` #include "xlsxwriter.h" unsigned char image_buffer[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x02, 0x00, 0x00, 0x00, 0xfc, 0x18, 0xed, 0xa3, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, 0x46, 0x49, 0x44, 0x41, 0x54, 0x48, 0x4b, 0x63, 0xfc, 0xcf, 0x40, 0x63, 0x00, 0xb4, 0x80, 0xa6, 0x88, 0xb6, 0xa6, 0x83, 0x82, 0x87, 0xa6, 0xce, 0x1f, 0xb5, 0x80, 0x98, 0xe0, 0x1d, 0x8d, 0x03, 0x82, 0xa1, 0x34, 0x1a, 0x44, 0xa3, 0x41, 0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45, 0xa3, 0x41, 0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45, 0xa3, 0x41, 0x44, 0x30, 0x04, 0x08, 0x2a, 0x18, 0x4d, 0x45, 0x03, 0x1f, 0x44, 0x00, 0xaa, 0x35, 0xdd, 0x4e, 0xe6, 0xd5, 0xa1, 0x22, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; unsigned int image_size = 500; int main() { lxw_workbook *workbook = workbook_new("test_image82.xlsx"); lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); worksheet_insert_image_buffer(worksheet, CELL("E9"), image_buffer, image_size); return workbook_close(workbook); } ```
Author
Owner

@MrBeanc commented on GitHub (Nov 18, 2020):

Uncontrollable input image_size can cause overflow

<!-- gh-comment-id:729538436 --> @MrBeanc commented on GitHub (Nov 18, 2020): Uncontrollable input image_size can cause overflow
Author
Owner

@jmcnamara commented on GitHub (Mar 27, 2021):

Merged into #323

<!-- gh-comment-id:808802448 --> @jmcnamara commented on GitHub (Mar 27, 2021): Merged into #323
Author
Owner

@ANaumann85 commented on GitHub (Apr 5, 2021):

In the example, the user creates a buffer on the heap, but gives the wrong buffer size to the function "worksheet_insert_image_buffer". Inside the function, are have very small chances to detect that mistake. In my optinion, that is is not a bug in the library, but a wrong usage.

<!-- gh-comment-id:813283940 --> @ANaumann85 commented on GitHub (Apr 5, 2021): In the example, the user creates a buffer on the heap, but gives the wrong buffer size to the function "worksheet_insert_image_buffer". Inside the function, are have very small chances to detect that mistake. In my optinion, that is is not a bug in the library, but a wrong usage.
Author
Owner

@jmcnamara commented on GitHub (Apr 7, 2021):

I agree that this is wrong usage. If the user passes an incorrect buffer size then there isn't much (anything?) that libxlsxwriter can do about that.

I am going to keep this issue closed. If anyone has a different opinion/analysis, let me know.

<!-- gh-comment-id:815318324 --> @jmcnamara commented on GitHub (Apr 7, 2021): I agree that this is wrong usage. If the user passes an incorrect buffer size then there isn't much (anything?) that libxlsxwriter can do about that. I am going to keep this issue closed. If anyone has a different opinion/analysis, let me know.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/libxlsxwriter#253
No description provided.