Thread: BUG #18925: Heap-buffer-overflow: pglz_compress with pglz_stategy_always
BUG #18925: Heap-buffer-overflow: pglz_compress with pglz_stategy_always
From
PG Bug reporting form
Date:
The following bug has been logged on the website: Bug reference: 18925 Logged by: Stanislav Osipov Email address: stasos24@gmail.com PostgreSQL version: 17.5 Operating system: Ubuntu 22 Description: Although pglz_compress is not used with pglz_stategy_always. It might be useful in future Source code: ``` #include "postgres.h" #include "common/pg_lzcompress.h" #include "mb/pg_wchar.h" #include "utils/memutils.h" #include "utils/memdebug.h" #include "miscadmin.h" extern pg_stack_base_t set_stack_base(void); int FuzzerInitialize(char *dbname, char ***argv); extern bool log_checkpoints; int LLVMFuzzerInitialize(int *argc, char ***argv) { FuzzerInitialize("compress_db", argv); return 0; } /* ** Main entry point. The fuzzer invokes this function with each ** fuzzed input. */ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size < 1) return 1; log_checkpoints = false; sigjmp_buf local_sigjmp_buf; char *buffer; char *comp; char *decomp; int comp_bytes; buffer = (char *) calloc(size+1, sizeof(char)); memcpy(buffer, data, size); comp = (char *) calloc(size+1, sizeof(char)); decomp = (char *) calloc(size+1, sizeof(char)); MemoryContextInit(); set_stack_base(); if(!sigsetjmp(local_sigjmp_buf,0)){ error_context_stack = NULL; comp_bytes = pglz_compress(buffer, size + 1, comp, PGLZ_strategy_always); pglz_decompress(comp, comp_bytes, decomp, size+1, false); } free(buffer); free(comp); free(decomp); FlushErrorState(); MemoryContextReset(TopMemoryContext); TopMemoryContext->ident = NULL; TopMemoryContext->methods->delete_context(TopMemoryContext); VALGRIND_DESTROY_MEMPOOL(TopMemoryContext); return 0; } ``` Input: ``` ZZZ▒ZC ``` Asan Report: ==7101==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000011a3a at pc 0x000002593c29 bp 0x7fff7277f850 sp 0x7fff7277f848 WRITE of size 1 at 0x602000011a3a thread T0 #0 0x2593c28 in pglz_compress /db/src/common/pg_lzcompress.c:656:4 #1 0x5751c1 in LLVMFuzzerTestOneInput (/fuzz/compress_fuzzer+0x5751c1) #2 0x4a8d23 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/fuzz/compress_fuzzer+0x4a8d23) #3 0x491b6f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/fuzz/compress_fuzzer+0x491b6f) #4 0x497df0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/fuzz/compress_fuzzer+0x497df0) #5 0x4c3962 in main (/fuzz/compress_fuzzer+0x4c3962) #6 0x7f5b2bf55d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #7 0x7f5b2bf55e3f in __libc_start_main csu/../csu/libc-start.c:392:3 #8 0x48beb4 in _start (/fuzz/compress_fuzzer+0x48beb4) 0x602000011a3a is located 0 bytes to the right of 10-byte region [0x602000011a30,0x602000011a3a) allocated by thread T0 here: #0 0x540922 in __interceptor_calloc (/fuzz/compress_fuzzer+0x540922) #1 0x5750a1 in LLVMFuzzerTestOneInput (/fuzz/compress_fuzzer+0x5750a1) #2 0x4a8d23 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/fuzz/compress_fuzzer+0x4a8d23) #3 0x491b6f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/fuzz/compress_fuzzer+0x491b6f) #4 0x497df0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/fuzz/compress_fuzzer+0x497df0) #5 0x4c3962 in main (/fuzz/compress_fuzzer+0x4c3962) #6 0x7f5b2bf55d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 SUMMARY: AddressSanitizer: heap-buffer-overflow /db/src/common/pg_lzcompress.c:656:4 in pglz_compress Shadow bytes around the buggy address: 0x0c047fffa2f0: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x0c047fffa300: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x0c047fffa310: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x0c047fffa320: fa fa 00 04 fa fa 00 05 fa fa 00 03 fa fa 00 00 0x0c047fffa330: fa fa 00 00 fa fa 00 00 fa fa 00 01 fa fa 00 01 =>0x0c047fffa340: fa fa 00 02 fa fa 00[02]fa fa 00 02 fa fa fa fa 0x0c047fffa350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fffa360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fffa370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fffa380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fffa390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 ==7101==ABORTING
On Tue, May 13, 2025 at 7:34 PM PG Bug reporting form <noreply@postgresql.org> wrote: > > The following bug has been logged on the website: > > Bug reference: 18925 > Logged by: Stanislav Osipov > Email address: stasos24@gmail.com > PostgreSQL version: 17.5 > Operating system: Ubuntu 22 > Description: > > Although pglz_compress is not used with pglz_stategy_always. > It might be useful in future > Source code: > ``` > #include "postgres.h" > #include "common/pg_lzcompress.h" > #include "mb/pg_wchar.h" > #include "utils/memutils.h" > #include "utils/memdebug.h" > #include "miscadmin.h" > extern pg_stack_base_t set_stack_base(void); > int FuzzerInitialize(char *dbname, char ***argv); > extern bool log_checkpoints; > int LLVMFuzzerInitialize(int *argc, char ***argv) { > FuzzerInitialize("compress_db", argv); > return 0; > } > /* > ** Main entry point. The fuzzer invokes this function with each > ** fuzzed input. > */ > int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { > if (size < 1) return 1; > log_checkpoints = false; > sigjmp_buf local_sigjmp_buf; > char *buffer; > char *comp; > char *decomp; > int comp_bytes; > buffer = (char *) calloc(size+1, sizeof(char)); > memcpy(buffer, data, size); > comp = (char *) calloc(size+1, sizeof(char)); > decomp = (char *) calloc(size+1, sizeof(char)); > MemoryContextInit(); > set_stack_base(); > if(!sigsetjmp(local_sigjmp_buf,0)){ > error_context_stack = NULL; > comp_bytes = pglz_compress(buffer, size + 1, comp, > PGLZ_strategy_always); > pglz_decompress(comp, comp_bytes, decomp, > size+1, false); > } > free(buffer); > free(comp); > free(decomp); > FlushErrorState(); > MemoryContextReset(TopMemoryContext); > TopMemoryContext->ident = NULL; > TopMemoryContext->methods->delete_context(TopMemoryContext); > VALGRIND_DESTROY_MEMPOOL(TopMemoryContext); > return 0; > } > ``` > Input: > ``` > ZZZ▒ZC > ``` > Asan Report: > ==7101==ERROR: AddressSanitizer: heap-buffer-overflow on address > 0x602000011a3a at pc 0x000002593c29 bp 0x7fff7277f850 sp 0x7fff7277f848 > WRITE of size 1 at 0x602000011a3a thread T0 > #0 0x2593c28 in pglz_compress /db/src/common/pg_lzcompress.c:656:4 > #1 0x5751c1 in LLVMFuzzerTestOneInput (/fuzz/compress_fuzzer+0x5751c1) > #2 0x4a8d23 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, > unsigned long) (/fuzz/compress_fuzzer+0x4a8d23) > #3 0x491b6f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned > long) (/fuzz/compress_fuzzer+0x491b6f) > #4 0x497df0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char > const*, unsigned long)) (/fuzz/compress_fuzzer+0x497df0) > #5 0x4c3962 in main (/fuzz/compress_fuzzer+0x4c3962) > #6 0x7f5b2bf55d8f in __libc_start_call_main > csu/../sysdeps/nptl/libc_start_call_main.h:58:16 > #7 0x7f5b2bf55e3f in __libc_start_main csu/../csu/libc-start.c:392:3 > #8 0x48beb4 in _start (/fuzz/compress_fuzzer+0x48beb4) > 0x602000011a3a is located 0 bytes to the right of 10-byte region > [0x602000011a30,0x602000011a3a) > allocated by thread T0 here: > #0 0x540922 in __interceptor_calloc (/fuzz/compress_fuzzer+0x540922) > #1 0x5750a1 in LLVMFuzzerTestOneInput (/fuzz/compress_fuzzer+0x5750a1) > #2 0x4a8d23 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, > unsigned long) (/fuzz/compress_fuzzer+0x4a8d23) > #3 0x491b6f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned > long) (/fuzz/compress_fuzzer+0x491b6f) > #4 0x497df0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char > const*, unsigned long)) (/fuzz/compress_fuzzer+0x497df0) > #5 0x4c3962 in main (/fuzz/compress_fuzzer+0x4c3962) > #6 0x7f5b2bf55d8f in __libc_start_call_main > csu/../sysdeps/nptl/libc_start_call_main.h:58:16 > SUMMARY: AddressSanitizer: heap-buffer-overflow > /db/src/common/pg_lzcompress.c:656:4 in pglz_compress > Shadow bytes around the buggy address: > 0x0c047fffa2f0: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 > 0x0c047fffa300: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 > 0x0c047fffa310: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 > 0x0c047fffa320: fa fa 00 04 fa fa 00 05 fa fa 00 03 fa fa 00 00 > 0x0c047fffa330: fa fa 00 00 fa fa 00 00 fa fa 00 01 fa fa 00 01 > =>0x0c047fffa340: fa fa 00 02 fa fa 00[02]fa fa 00 02 fa fa fa fa > 0x0c047fffa350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fffa360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fffa370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fffa380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fffa390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 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 > ==7101==ABORTING > Do you have a reproducible test case or steps to hit this issue? -- Regards, Dilip Kumar EnterpriseDB: http://www.enterprisedb.com
Re: BUG #18925: Heap-buffer-overflow: pglz_compress with pglz_stategy_always
From
Daniel Gustafsson
Date:
> On 13 May 2025, at 10:22, Dilip Kumar <dilipbalaut@gmail.com> wrote: > On Tue, May 13, 2025 at 7:34 PM PG Bug reporting form > <noreply@postgresql.org> wrote: >> Although pglz_compress is not used with pglz_stategy_always. >> It might be useful in future > Do you have a reproducible test case or steps to hit this issue? The way I read it there is now way to reproduce this as the codepath used in the fuzzer ins't present in postgres (PGLZ_strategy_always is not used by any callsite). Whether or not there is a bug in the compression code, or PGLZ_strategy_always being incorrectly defined, or none of the above, remains to be seen. -- Daniel Gustafsson