Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler-rt][ubsan] Implicit Conversion Sanitizer - integer truncati…
…on - compiler-rt part Summary: This is a compiler-rt part. The clang part is D48958. See [[ https://bugs.llvm.org/show_bug.cgi?id=21530 | PR21530 ]], google/sanitizers#940. Reviewers: #sanitizers, samsonov, vsk, rsmith, pcc, eugenis, kcc, filcab Reviewed By: #sanitizers, vsk, filcab Subscribers: llvm-commits, eugenis, filcab, kubamracek, dberris, #sanitizers, regehr Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D48959 llvm-svn: 338287
- Loading branch information
Showing
12 changed files
with
213 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
|
||
// Test for signed-integer-overflow. | ||
#include <assert.h> | ||
#include <climits> | ||
#include <cstddef> | ||
#include <cstdint> | ||
#include <cstdlib> | ||
#include <iostream> | ||
|
||
static volatile int Sink; | ||
static unsigned char Large = UINT8_MAX; | ||
|
||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { | ||
assert(Data); | ||
if (Size > 0 && Data[0] == 'H') { | ||
Sink = 1; | ||
if (Size > 1 && Data[1] == 'i') { | ||
Sink = 2; | ||
if (Size > 2 && Data[2] == '!') { | ||
Large = Large + 1; // 'char overflow'. | ||
} | ||
} | ||
} | ||
return 0; | ||
} |
5 changes: 5 additions & 0 deletions
5
compiler-rt/test/fuzzer/fuzzer-implicit-integer-truncation.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
RUN: rm -f %t-ImplicitIntegerTruncationTest-Ubsan | ||
RUN: %cpp_compiler -fsanitize=implicit-integer-truncation -fno-sanitize-recover=all %S/ImplicitIntegerTruncationTest.cpp -o %t-ImplicitIntegerTruncationTest-Ubsan | ||
RUN: not %run %t-ImplicitIntegerTruncationTest-Ubsan 2>&1 | FileCheck %s | ||
CHECK: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'unsigned char' changed the value to 0 (8-bit, unsigned) | ||
CHECK: Test unit written to ./crash- |
15 changes: 15 additions & 0 deletions
15
compiler-rt/test/ubsan/TestCases/ImplicitCast/integer-truncation-blacklist.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// RUN: rm -f %tmp | ||
// RUN: echo "[implicit-integer-truncation]" >> %tmp | ||
// RUN: echo "fun:*implicitTruncation*" >> %tmp | ||
// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | ||
// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | ||
// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | ||
// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | ||
|
||
unsigned char implicitTruncation(unsigned int argc) { | ||
return argc; // BOOM | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
return implicitTruncation(~0U); | ||
} |
13 changes: 13 additions & 0 deletions
13
compiler-rt/test/ubsan/TestCases/ImplicitCast/integer-truncation-summary.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// RUN: %clangxx -fsanitize=implicit-integer-truncation %s -o %t | ||
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE | ||
// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE | ||
// REQUIRES: !ubsan-standalone && !ubsan-standalone-static | ||
|
||
#include <stdint.h> | ||
|
||
int main() { | ||
uint8_t t0 = (~(uint32_t(0))); | ||
// CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:16 | ||
// CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-integer-truncation {{.*}}summary.cpp:[[@LINE-2]]:16 | ||
return 0; | ||
} |
63 changes: 63 additions & 0 deletions
63
compiler-rt/test/ubsan/TestCases/ImplicitCast/integer-truncation.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK | ||
// RUN: %clangxx -x c++ -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK | ||
|
||
#include <stdint.h> | ||
|
||
#if !defined(__cplusplus) | ||
#define bool _Bool | ||
#endif | ||
|
||
int main() { | ||
// CHECK-NOT: integer-truncation.c | ||
|
||
// Negative tests. Even if they produce unexpected results, this sanitizer does not care. | ||
int8_t n0 = (~((uint32_t)0)); // ~0 -> -1, but do not warn. | ||
uint8_t n2 = 128; | ||
uint8_t n3 = 255; | ||
// Bools do not count | ||
bool b0 = (~((uint32_t)0)); | ||
bool b1 = 255; | ||
|
||
// Explicit and-ing of bits will silence it. | ||
uint8_t nc0 = (~((uint32_t)0)) & 255; | ||
|
||
// Explicit casts | ||
uint8_t i0 = (uint8_t)(~((uint32_t)0)); | ||
|
||
#if defined(__cplusplus) | ||
uint8_t i1 = uint8_t(~(uint32_t(0))); | ||
uint8_t i2 = static_cast<uint8_t>(~(uint32_t(0))); | ||
#endif | ||
|
||
// Positive tests. | ||
|
||
uint8_t t_b0 = (~((uint16_t)(0))); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) | ||
|
||
uint8_t t_b1 = (~((uint32_t)0)); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) | ||
uint16_t t_b2 = (~((uint32_t)0)); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned) | ||
|
||
uint8_t t_b3 = ~((uint64_t)0); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) | ||
uint16_t t_b4 = ~((uint64_t)0); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned) | ||
uint32_t t_b5 = ~((uint64_t)0); | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint32_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) | ||
|
||
int8_t t1 = 255; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 255 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -1 (8-bit, signed) | ||
uint8_t t2 = 256; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) | ||
int8_t t3 = 256; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 0 (8-bit, signed) | ||
uint8_t t4 = 257; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 1 (8-bit, unsigned) | ||
int8_t t5 = 257; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 1 (8-bit, signed) | ||
int8_t t6 = 128; | ||
// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 128 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -128 (8-bit, signed) | ||
|
||
return 0; | ||
} |
24 changes: 24 additions & 0 deletions
24
compiler-rt/test/ubsan_minimal/TestCases/implicit-integer-truncation.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// RUN: %clang -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK | ||
|
||
#include <stdint.h> | ||
|
||
int main() { | ||
// CHECK-NOT: integer-truncation.c | ||
|
||
// Negative tests. Even if they produce unexpected results, this sanitizer does not care. | ||
int8_t n0 = (~((uint32_t)(0))); // ~0 -> -1, but do not warn. | ||
uint8_t n2 = 128; | ||
uint8_t n3 = 255; | ||
// Bools do not count | ||
_Bool b0 = (~((uint32_t)(0))); | ||
_Bool b1 = 255; | ||
|
||
// Explicit and-ing of bits will silence it. | ||
uint8_t nc0 = ((~((uint32_t)(0))) & 255); | ||
|
||
// Positive tests. | ||
uint8_t t0 = (~((uint32_t)(0))); | ||
// CHECK: implicit-conversion | ||
|
||
return 0; | ||
} |