CTSRD-CHERI / clang

DO NOT USE. Use llvm-project instead
Other
9 stars 8 forks source link

parser crash in libpng_sb.c #157

Closed brooksdavis closed 6 years ago

brooksdavis commented 7 years ago

reduced test case from creduce_crash_testcase.py:

// RUN: %cheri_cc1 -emit-obj -mrelocation-model pic -pic-level 2 -mthread-model posix 128 -target-abi n64 -mllvm -mips-ssection-threshold=0 -sys-header-deps -O2 -std=gnu99 -fconst-strings -ftls-model=initial-exec -vectorize-loops -vectorize-slp -cheri-linker -mllvm -cheri-exact-equals -mllvm -cheri128 -x c -o - -emit-llvm %s | FileCheck %s
#define a(b)                                                                   \
  {                                                                            \
    typedef __typeof__(b) c;                                                   \
    __capability c d
e() {          int *pipv = (a(pip)

Note: The -mthread-model posix 128 produces error output as well, but the crash doesn't really vary if you remove it.

brooksdavis commented 7 years ago

Another case in compress.c:

// RUN: %cheri_cc1 -emit-obj -mrelocation-model pic -pic-level 2 -mthread-model posix 128 -target-abi n64 -mllvm -mips-ssection-threshold=0 -sys-header-deps -D HAS_snprintf -D HAS_vsnprintf -D SYMBOL_VERSIONING -D POSTINC -O2 -std=gnu99 -ftls-model=initial-exec -vectorize-loops -vectorize-slp -cheri-linker -mllvm -cheri-exact-equals -mllvm -cheri128 -x c -o - -emit-llvm %s | FileCheck %s
#  define ZEXPORT
#  define FAR
typedef unsigned char  Byte;
#  define Bytef Byte FAR
#define cheri_ptr_to_bounded_cap(ptr)   __extension__({ \
        typedef __typeof__(ptr) __ptr_type;             \
        typedef __capability __ptr_type __cap_type;     \
 z_stream;
 typedef __capability z_stream FAR *z_streamp;
      int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)     Bytef *dest;
       {
          z_stream stream;
          z_streamp stream_cap = cheri_ptr_to_bounded_cap(&stream);

In this case creduce_crash_testcase.py goes off into the weeds to start making the file bigger which isn't very helpful.

arichardson commented 7 years ago

This only appears to happen if the compiler does typo-correction internally: in both these test cases it will replace the invalid typeof() argument with the correct value (zstreamp and pipv) and then continue processing. In HandleCHERICapabilityAttr() it then tries to call CurType = S.Context.getTypedefType(TT->getDecl(), QualType(), true); and create a typedeftype for the decl. However, for some reason it then asserts in that function because the context doesn't match the expected context.

I am not sure how to detect an autocorrected AST node and error in that case

test case with simplified RUN line:

// RUN: %cheri_cc1 -target-abi n64 -fsyntax-only %s
#define a(b)                                                                   \
  {                                                                            \
    typedef __typeof__(b) c;                                                   \
    __capability c d
e() {          int *pipv =       (a(pip)

If we remove the __capability qualifier we get the expected error:

/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:1: warning: type specifier missing, defaults to 'int'
e() {          int *pipv =       (a(pip)
^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:37: error: use of undeclared identifier 'pip'; did you mean 'pipv'?
e() {          int *pipv =       (a(pip)
                                    ^~~
                                    pipv
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:4:24: note: expanded from macro 'a'
    typedef __typeof__(b) c;                                                   \
                       ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:21: note: 'pipv' declared here
e() {          int *pipv =       (a(pip)
                    ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:41: error: expected ';' at end of declaration
e() {          int *pipv =       (a(pip)
                                        ^
                                        ;
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:41: error: expected '}'
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:35: note: to match this '{'
e() {          int *pipv =       (a(pip)
                                  ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:3:3: note: expanded from macro 'a'
  {                                                                            \
  ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:41: error: expected ')'
e() {          int *pipv =       (a(pip)
                                        ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:34: note: to match this '('
e() {          int *pipv =       (a(pip)
                                 ^
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:21: error: initializing 'int *' with an expression of incompatible type 'void'
e() {          int *pipv =       (a(pip)
                    ^            ~~~~~~~
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:41: error: expected ';' at end of declaration
e() {          int *pipv =       (a(pip)
                                        ^
                                        ;
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:41: error: expected '}'
/Users/alex/cheri/llvm/tools/clang/test/Sema/cheri-capability-attr-invalid-type.c:6:5: note: to match this '{'
e() {          int *pipv =       (a(pip)