Project: libsass (sass/libsass), language: c++
Vulnerability instance: libsass.cve-2019-18798
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/sass/libsass/issues/2999
## Description:
Issue: sass/libsass#2999
Title: Heap Buffer Overflow in sassc
State: closed
Created by: c0d3xpl0it
Created at: 2019-10-07 14:36:59+00:00
Labels: Dev - Needs Test, Bug - Confirmed, Fuzzy

Issue Body:
We found Heap Buffer Overflow in sassc binary and sassc is complied with clang enabling ASAN.

**Machine Setup**
```
Machine : Ubuntu 16.04.3 LTS
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
Commit : 4da7c4b
Command : sassc POC
```
**Complilation** : CC=afl-clang-fast CXX=afl-clang-fast++ AFL_USE_ASAN=1 make -C sassc -j4
**POC** : [POC.scss.zip](https://github.com/sass/libsass/files/3697908/POC.scss.zip)

**ASAN Output**
```
fuzzer@fuzzer:~/victim/libsass/sassc/bin$ ./sassc -v
sassc: 3.6.1-5-g507f0
libsass: 3.6.2
sass2scss: 1.1.1
sass: 3.5
fuzzer@fuzzer:~/victim/libsass/sassc/bin$

fuzzer@fuzzer:~/victim/libsass/sassc/bin$ ./sassc in/POC.scss
compound selectors may no longer be extended.
Consider `@extend ${compound.components.join(', ')}` instead.
See http://bit.ly/ExtendCompound for details.
=================================================================
==6456==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000009f40 at pc 0x000000e459db bp 0x7fff865ed280 sp 0x7fff865ed278
READ of size 8 at 0x604000009f40 thread T0
    #0 0xe459da in std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >::~vector() /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:424:61
    #1 0xe459da in void __gnu_cxx::new_allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > >::destroy<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > >(std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >*) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/ext/new_allocator.h:124
    #2 0xe459da in void std::allocator_traits<std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > >::destroy<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > >(std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > >&, std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >*) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/alloc_traits.h:542
    #3 0xe459da in std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > >::_M_erase(__gnu_cxx::__normal_iterator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >*, std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > >) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/vector.tcc:147
    #4 0xe24b59 in std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > >::erase(__gnu_cxx::__normal_iterator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > const*, std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > >) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:1147:16
    #5 0xe24b59 in Sass::weaveParents(std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >) /home/fuzzer/victim/libsass/src/ast_sel_weave.cpp:579
    #6 0xe1c4e9 in Sass::weave(std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > const&) /home/fuzzer/victim/libsass/src/ast_sel_weave.cpp:494:28
    #7 0xdb5482 in Sass::unifyComplex(std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > const&) /home/fuzzer/victim/libsass/src/ast_sel_unify.cpp:51:12
    #8 0xb3d264 in Sass::Extender::extendCompound(Sass::SharedImpl<Sass::CompoundSelector> const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&, Sass::SharedImpl<Sass::CssMediaRule> const&, bool) /home/fuzzer/victim/libsass/src/extender.cpp:829:21
    #9 0xb2b0ad in Sass::Extender::extendComplex(Sass::SharedImpl<Sass::ComplexSelector> const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&, Sass::SharedImpl<Sass::CssMediaRule> const&) /home/fuzzer/victim/libsass/src/extender.cpp:574:52
    #10 0xb14d35 in Sass::Extender::extendList(Sass::SharedImpl<Sass::SelectorList> const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&, Sass::SharedImpl<Sass::CssMediaRule> const&) /home/fuzzer/victim/libsass/src/extender.cpp:510:9
    #11 0xb28233 in Sass::Extender::extendExistingStyleRules(std::unordered_set<Sass::SharedImpl<Sass::SelectorList>, Sass::ObjPtrHash, Sass::ObjPtrEquality, std::allocator<Sass::SharedImpl<Sass::SelectorList> > > const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&) /home/fuzzer/victim/libsass/src/extender.cpp:389:29
    #12 0xb2267b in Sass::Extender::addExtension(Sass::SharedImpl<Sass::SelectorList> const&, Sass::SharedImpl<Sass::SimpleSelector> const&, Sass::SharedImpl<Sass::CssMediaRule> const&, bool) /home/fuzzer/victim/libsass/src/extender.cpp:369:7
    #13 0xa87cd3 in Sass::Expand::operator()(Sass::ExtendRule*) /home/fuzzer/victim/libsass/src/expand.cpp:692:15
    #14 0xa98870 in Sass::Expand::append_block(Sass::Block*) /home/fuzzer/victim/libsass/src/expand.cpp:838:27
    #15 0xa4a082 in Sass::Expand::operator()(Sass::Block*) /home/fuzzer/victim/libsass/src/expand.cpp:140:5
    #16 0xa4dfd1 in Sass::Expand::operator()(Sass::Ruleset*) /home/fuzzer/victim/libsass/src/expand.cpp:196:27
    #17 0xa98870 in Sass::Expand::append_block(Sass::Block*) /home/fuzzer/victim/libsass/src/expand.cpp:838:27
    #18 0xa4a082 in Sass::Expand::operator()(Sass::Block*) /home/fuzzer/victim/libsass/src/expand.cpp:140:5
    #19 0x5b711b in Sass::Context::compile() /home/fuzzer/victim/libsass/src/context.cpp:650:12
    #20 0x5b1cf9 in Sass::File_Context::parse() /home/fuzzer/victim/libsass/src/context.cpp:579:12
    #21 0x55195e in Sass::sass_parse_block(Sass_Compiler*) /home/fuzzer/victim/libsass/src/sass_context.cpp:180:22
    #22 0x55195e in sass_compiler_parse /home/fuzzer/victim/libsass/src/sass_context.cpp:434
    #23 0x5503d4 in sass_compile_context(Sass_Context*, Sass::Context*) /home/fuzzer/victim/libsass/src/sass_context.cpp:317:7
    #24 0x550ac1 in sass_compile_file_context /home/fuzzer/victim/libsass/src/sass_context.cpp:421:12
    #25 0x53f1ce in compile_file /home/fuzzer/victim/libsass/sassc/sassc.c:173:5
    #26 0x540284 in main /home/fuzzer/victim/libsass/sassc/sassc.c:387:18
    #27 0x7f31bd73782f in __libc_start_main /build/glibc-LK5gWL/glibc-2.23/csu/../csu/libc-start.c:291
    #28 0x46d1d8 in _start (/home/fuzzer/victim/libsass/sassc/bin/sassc+0x46d1d8)

0x604000009f40 is located 0 bytes to the right of 48-byte region [0x604000009f10,0x604000009f40)
allocated by thread T0 here:
    #0 0x50d308 in __interceptor_malloc (/home/fuzzer/victim/libsass/sassc/bin/sassc+0x50d308)
    #1 0x7f31be1a9e77 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x8de77)

SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:424:61 in std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >::~vector()
Shadow bytes around the buggy address:
  0x0c087fff9390: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00 00
  0x0c087fff93a0: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 00
  0x0c087fff93b0: fa fa 00 00 00 00 00 00 fa fa fd fd fd fd fd fd
  0x0c087fff93c0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
  0x0c087fff93d0: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 00
=>0x0c087fff93e0: fa fa 00 00 00 00 00 00[fa]fa 00 00 00 00 00 00
  0x0c087fff93f0: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fd
  0x0c087fff9400: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 fa
  0x0c087fff9410: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 fa
  0x0c087fff9420: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x0c087fff9430: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fd
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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==6456==ABORTING
fuzzer@fuzzer:~/victim/libsass/sassc/bin$
```


Comments:
Comment by mgreter on 2019-11-02 23:59:52+00:00:
Note that this crashes in dart sass too

```scss 
xx|x:not(>x:noT(>:not(>%e>)>|c~~z,,~**:x|bhz,0~j*:xxx*	,**:xx)#x>):xxxCeeeeeee:rrrrrrrrrrrrrrrrx9	***:not(>%e>)V|c~~z,,~**:xgchz,~j:zx\`c~~z,,~**:xxxCxf{
; @extend*;
  food3weiSht: Tole&
}
```

---

Comment by nluedtke on 2019-11-12 12:35:03+00:00:
Being tracked as [CVE-2019-18798](https://nvd.nist.gov/vuln/detail/CVE-2019-18798).

Attachments:
https://github.com/sass/libsass/files/3697908/POC.scss.zip

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
export BUILD='static'
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool
RUN git clone https://github.com/sass/libsass libsass
RUN git -C libsass checkout 081bbbffe01b589f507a4aa0129e067944815914
WORKDIR $SRC/libsass
COPY build.sh $SRC/

Additional files:
filename: data_context_fuzzer.cc
content: #include "sass.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  char* sass_data = (char*) malloc(sizeof(char) * size + 1);
  if (sass_data == NULL) return 0;

  memcpy(sass_data, data, size);
  sass_data[size] = '\0';

  struct Sass_Data_Context* ctx = sass_make_data_context(sass_data);
  if (ctx == NULL) {
    free(sass_data);
    return 0;
  }

  struct Sass_Options* options = sass_make_options();
  if (options == NULL) {
    sass_delete_data_context(ctx);
    return 0;
  }

  sass_option_set_output_style(options, SASS_STYLE_NESTED);
  sass_option_set_precision(options, 5);

  sass_data_context_set_options(ctx, options);
  sass_compile_data_context(ctx);

  sass_delete_data_context(ctx);
  sass_delete_options(options);

  return 0;
}