You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
6.0 KiB
160 lines
6.0 KiB
// Cross-DSO diagnostics.
|
|
// The rules are:
|
|
// * If the library needs diagnostics, the main executable must request at
|
|
// least some diagnostics as well (to link the diagnostic runtime).
|
|
// * -fsanitize-trap on the caller side overrides everything.
|
|
// * otherwise, the callee decides between trap/recover/norecover.
|
|
|
|
// Full-recover.
|
|
// RUN: %clangxx_cfi_dso_diag -g -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so
|
|
// RUN: %clangxx_cfi_dso_diag -g %s -o %t %ld_flags_rpath_exe
|
|
|
|
// RUN: %t icv 2>&1 | FileCheck %s --check-prefix=ICALL-DIAG --check-prefix=CAST-DIAG \
|
|
// RUN: --check-prefix=VCALL-DIAG --check-prefix=ALL-RECOVER
|
|
|
|
// RUN: %t i_v 2>&1 | FileCheck %s --check-prefix=ICALL-DIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-DIAG --check-prefix=ALL-RECOVER
|
|
|
|
// RUN: %t _cv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-DIAG \
|
|
// RUN: --check-prefix=VCALL-DIAG --check-prefix=ALL-RECOVER
|
|
|
|
// RUN: %t ic_ 2>&1 | FileCheck %s --check-prefix=ICALL-DIAG --check-prefix=CAST-DIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=ALL-RECOVER
|
|
|
|
// Trap on icall, no-recover on cast.
|
|
// RUN: %clangxx_cfi_dso_diag -fsanitize-trap=cfi-icall -fno-sanitize-recover=cfi-unrelated-cast \
|
|
// RUN: -g -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so
|
|
// RUN: %clangxx_cfi_dso_diag -fsanitize-trap=cfi-icall -fno-sanitize-recover=cfi-unrelated-cast \
|
|
// RUN: -g %s -o %t %ld_flags_rpath_exe
|
|
|
|
// RUN: %expect_crash %t icv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=ICALL-FATAL
|
|
|
|
// RUN: not %t _cv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-DIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=CAST-FATAL
|
|
|
|
// RUN: %t __v 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-DIAG
|
|
|
|
// Callee: trap on icall, no-recover on cast.
|
|
// Caller: recover on everything.
|
|
// The same as in the previous case, behaviour is decided by the callee.
|
|
// RUN: %clangxx_cfi_dso_diag -fsanitize-trap=cfi-icall -fno-sanitize-recover=cfi-unrelated-cast \
|
|
// RUN: -g -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so
|
|
// RUN: %clangxx_cfi_dso_diag \
|
|
// RUN: -g %s -o %t %ld_flags_rpath_exe
|
|
|
|
// RUN: %expect_crash %t icv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=ICALL-FATAL
|
|
|
|
// RUN: not %t _cv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-DIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=CAST-FATAL
|
|
|
|
// RUN: %t __v 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-DIAG
|
|
|
|
// Caller in trapping mode, callee with full diagnostic+recover.
|
|
// Caller wins.
|
|
// cfi-nvcall is non-trapping in the main executable to link the diagnostic runtime library.
|
|
// RUN: %clangxx_cfi_dso_diag \
|
|
// RUN: -g -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so
|
|
// RUN: %clangxx_cfi_dso -fno-sanitize-trap=cfi-nvcall \
|
|
// RUN: -g %s -o %t %ld_flags_rpath_exe
|
|
|
|
// RUN: %expect_crash %t icv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=ICALL-FATAL
|
|
|
|
// RUN: %expect_crash %t _cv 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=CAST-FATAL
|
|
|
|
// RUN: %expect_crash %t __v 2>&1 | FileCheck %s --check-prefix=ICALL-NODIAG --check-prefix=CAST-NODIAG \
|
|
// RUN: --check-prefix=VCALL-NODIAG --check-prefix=VCALL-FATAL
|
|
|
|
// REQUIRES: cxxabi
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
void *create_B();
|
|
|
|
#ifdef SHARED_LIB
|
|
|
|
#include "../../utils.h"
|
|
struct B {
|
|
virtual void f();
|
|
};
|
|
void B::f() {}
|
|
|
|
void *create_B() {
|
|
create_derivers<B>();
|
|
return (void *)(new B());
|
|
}
|
|
|
|
#else
|
|
|
|
void A::f() {}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
assert(argc == 2);
|
|
assert(strlen(argv[1]) == 3);
|
|
|
|
// ICALL-FATAL: =0=
|
|
// CAST-FATAL: =0=
|
|
// VCALL-FATAL: =0=
|
|
// ALL-RECOVER: =0=
|
|
fprintf(stderr, "=0=\n");
|
|
|
|
void *p;
|
|
if (argv[1][0] == 'i') {
|
|
// ICALL-DIAG: runtime error: control flow integrity check for type 'void *(int)' failed during indirect function call
|
|
// ICALL-DIAG-NEXT: note: create_B() defined here
|
|
// ICALL-NODIAG-NOT: runtime error: control flow integrity check {{.*}} during indirect function call
|
|
p = ((void *(*)(int))create_B)(42);
|
|
} else {
|
|
p = create_B();
|
|
}
|
|
|
|
// ICALL-FATAL-NOT: =1=
|
|
// CAST-FATAL: =1=
|
|
// VCALL-FATAL: =1=
|
|
// ALL-RECOVER: =1=
|
|
fprintf(stderr, "=1=\n");
|
|
|
|
A *a;
|
|
if (argv[1][1] == 'c') {
|
|
// CAST-DIAG: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
|
|
// CAST-DIAG-NEXT: note: vtable is of type '{{(struct )?}}B'
|
|
// CAST-NODIAG-NOT: runtime error: control flow integrity check {{.*}} during cast to unrelated type
|
|
a = (A*)p;
|
|
} else {
|
|
// Invisible to CFI.
|
|
memcpy(&a, &p, sizeof(a));
|
|
}
|
|
|
|
// ICALL-FATAL-NOT: =2=
|
|
// CAST-FATAL-NOT: =2=
|
|
// VCALL-FATAL: =2=
|
|
// ALL-RECOVER: =2=
|
|
fprintf(stderr, "=2=\n");
|
|
|
|
// VCALL-DIAG: runtime error: control flow integrity check for type 'A' failed during virtual call
|
|
// VCALL-DIAG-NEXT: note: vtable is of type '{{(struct )?}}B'
|
|
// VCALL-NODIAG-NOT: runtime error: control flow integrity check {{.*}} during virtual call
|
|
if (argv[1][2] == 'v') {
|
|
a->f(); // UB here
|
|
}
|
|
|
|
// ICALL-FATAL-NOT: =3=
|
|
// CAST-FATAL-NOT: =3=
|
|
// VCALL-FATAL-NOT: =3=
|
|
// ALL-RECOVER: =3=
|
|
fprintf(stderr, "=3=\n");
|
|
|
|
}
|
|
#endif
|