Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap use-after-free still exists in the bit_copy_chain #497

Open
0xdd96 opened this issue Jun 17, 2022 · 1 comment
Open

Heap use-after-free still exists in the bit_copy_chain #497

0xdd96 opened this issue Jun 17, 2022 · 1 comment
Assignees
Labels
bug Something isn't working fuzzing Intentional illegal input

Comments

@0xdd96
Copy link

0xdd96 commented Jun 17, 2022

Vulnerability description

version: 0.12.4.4608 & latest commit f2dea29
poc: poc
command: ./dwgrewrite poc

This is similar to issue #364 and others, but it seems that the patch e95cc1e has not fully fixed them.

Here is the trace reported by ASAN:

==28024==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ffff3b65800 at pc 0x5555564f67f6 bp 0x7fffffff6760 sp 0x7fffffff6750
READ of size 1 at 0x7ffff3b65800 thread T0
    #0 0x5555564f67f5 in bit_read_RC libredwg/src/bits.c:317
    #1 0x5555564f67f5 in bit_copy_chain libredwg/src/bits.c:3352
    #2 0x555556105ec6 in obj_flush_hdlstream libredwg/src/encode.c:833
    #3 0x555556105ec6 in dwg_encode_PLANESURFACE_private libredwg/src/dwg.spec:9150
    #4 0x5555563a57df in dwg_encode_PLANESURFACE libredwg/src/dwg.spec:9136
    #5 0x5555563a57df in dwg_encode_variable_type libredwg/src/classes.inc:247
    #6 0x5555563ab3d0 in dwg_encode_add_object libredwg/src/encode.c:4432
    #7 0x5555563c914c in dwg_encode libredwg/src/encode.c:2769
    #8 0x55555575ca00 in dwg_write_file libredwg/src/dwg.c:429
    #9 0x555555758a3f in main libredwg/programs/dwgrewrite.c:350
    #10 0x7ffff726f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
    #11 0x55555575924d in _start (libredwg/build-ASAN/dwgrewrite+0x20524d)

0x7ffff3b65800 is located 0 bytes inside of 208896-byte region [0x7ffff3b65800,0x7ffff3b98800)
freed by thread T0 here:
    #0 0x7ffff7699ffe in __interceptor_realloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dffe)
    #1 0x5555564f532c in bit_chain_alloc_size libredwg/src/bits.c:3046
    #2 0x5555564f532c in bit_chain_alloc libredwg/src/bits.c:3062
    #3 0x5555564f532c in bit_copy_chain libredwg/src/bits.c:3339
    #4 0x1900000105  (<unknown module>)

previously allocated by thread T0 here:
    #0 0x7ffff7699ffe in __interceptor_realloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dffe)
    #1 0x5555564f396f in bit_chain_alloc_size libredwg/src/bits.c:3046
    #2 0x5555564f396f in bit_chain_alloc libredwg/src/bits.c:3062
    #3 0x31fff  (<unknown module>)

Vulnerability analysis

When running to bit_copy_chain, both dat->chain and tmp_dat->chain point to 0x7ffff3b65800 (see the gdb output below).

This will lead to use-after-free, since line 3339 calls realloc, which frees the chunk 0x7ffff3b65800, and line 3352 ties to read from the freed chunk.

Also note that the comment says bit_copy_chain Copy the whole content of tmp_data to dat, and reset tmp_dat, so why dat->chain = tmp_dat->chain in this PoC should be further investigated.

libredwg/src/bits.c

Lines 3333 to 3360 in f2dea29

void bit_copy_chain (Bit_Chain *restrict dat, Bit_Chain *restrict tmp_dat)
{
unsigned long i;
unsigned long dat_bits = bit_position (tmp_dat);
unsigned long size = tmp_dat->byte;
while (dat->byte + size > dat->size)
bit_chain_alloc (dat);
// check if dat is byte aligned, tmp_dat always is. we can use memcpy then.
if (!dat->bit)
{
assert(!tmp_dat->bit);
memcpy (&dat->chain[dat->byte], &tmp_dat->chain[0], size);
dat->byte += size;
}
else
{
bit_set_position (tmp_dat, 0);
for (i = 0; i < size; i++)
{
bit_write_RC (dat, bit_read_RC (tmp_dat));
}
for (i = 0; i < dat_bits % 8; i++)
{
bit_write_B (dat, bit_read_B (tmp_dat));
}
}
bit_set_position (tmp_dat, 0);
}

pwndbg> p *dat
$6 = {
  chain = 0x7ffff3b65800,
  size = 208896,
  byte = 204890,
  bit = 6 '\006',
  opts = 1 '\001',
  version = R_2000,
  from_version = R_2004,
  fh = 0x0
}

pwndbg> p *tmp_dat
$10 = {
  chain = 0x7ffff3b65800,
  size = 208896,
  byte = 204882,
  bit = 6 '\006',
  opts = 1 '\001',
  version = R_2000,
  from_version = R_2004,
  fh = 0x0
}
@rurban rurban self-assigned this Aug 15, 2022
@rurban rurban added bug Something isn't working fuzzing Intentional illegal input labels Aug 15, 2022
@rurban
Copy link
Contributor

rurban commented Aug 15, 2022

I think I found some thinkos in the obj_flush_hdlstream logic

rurban added a commit that referenced this issue Aug 15, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Aug 15, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Sep 5, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Oct 16, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Nov 25, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 1, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 11, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 12, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 12, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 12, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 12, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 13, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 14, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 14, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 15, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 15, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 16, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)
rurban added a commit that referenced this issue Dec 16, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 17, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 17, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 19, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 20, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 25, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Dec 26, 2022
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 26, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 26, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 26, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 27, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 27, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 29, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue Apr 29, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 2, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 4, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 4, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 5, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 5, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 7, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 7, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 7, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 7, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 8, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 8, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 10, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 10, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 11, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 11, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 11, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 12, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 12, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 13, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 13, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 17, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 17, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
rurban added a commit that referenced this issue May 19, 2023
don't free non-temp hdl_dat chain, when it's the dat->chain really.
(on old DWG's)

TODO dwgadd still broken
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fuzzing Intentional illegal input
Projects
Status: 🔖 Ready
Development

No branches or pull requests

2 participants