middle-end/70090: Dynamic sizes for -fsanitize=object-size
Use __builtin_dynamic_object_size to get object sizes for ubsan. gcc/ChangeLog: PR middle-end/70090 * ubsan.cc (ubsan_expand_objsize_ifn): Allow non-constant SIZE. (instrument_object_size): Get dynamic object size expression. gcc/testsuite/ChangeLog: PR middle-end/70090 * gcc.dg/ubsan/object-size-dyn.c: New test. Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
This commit is contained in:
parent
bb2921ab84
commit
28896b38fa
45
gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c
Normal file
45
gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
|
||||
/* { dg-options "-fsanitize=undefined" } */
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
dyn (int size, int i)
|
||||
{
|
||||
__builtin_printf ("dyn\n");
|
||||
fflush (stdout);
|
||||
int *alloc = __builtin_calloc (size, sizeof (int));
|
||||
int ret = alloc[i];
|
||||
__builtin_free (alloc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
off (int size, int i, int ret)
|
||||
{
|
||||
char *mem = __builtin_alloca (size);
|
||||
mem += size - 1;
|
||||
|
||||
return (int) mem[i] & ret;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int ret = dyn (2, 2);
|
||||
|
||||
ret |= off (4, 4, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* { dg-output "load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "\[^\n\r]*\\^" } */
|
13
gcc/ubsan.cc
13
gcc/ubsan.cc
@ -942,8 +942,8 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
|
||||
gimple *g;
|
||||
|
||||
/* See if we can discard the check. */
|
||||
if (TREE_CODE (size) != INTEGER_CST
|
||||
|| integer_all_onesp (size))
|
||||
if (TREE_CODE (size) == INTEGER_CST
|
||||
&& integer_all_onesp (size))
|
||||
/* Yes, __builtin_object_size couldn't determine the
|
||||
object size. */;
|
||||
else if (TREE_CODE (offset) == INTEGER_CST
|
||||
@ -2162,14 +2162,14 @@ instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
|
||||
if (decl_p)
|
||||
base_addr = build1 (ADDR_EXPR,
|
||||
build_pointer_type (TREE_TYPE (base)), base);
|
||||
if (compute_builtin_object_size (base_addr, 0, &sizet))
|
||||
if (compute_builtin_object_size (base_addr, OST_DYNAMIC, &sizet))
|
||||
;
|
||||
else if (optimize)
|
||||
{
|
||||
if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
|
||||
loc = input_location;
|
||||
/* Generate __builtin_object_size call. */
|
||||
sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
|
||||
/* Generate __builtin_dynamic_object_size call. */
|
||||
sizet = builtin_decl_explicit (BUILT_IN_DYNAMIC_OBJECT_SIZE);
|
||||
sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
|
||||
integer_zero_node);
|
||||
sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
|
||||
@ -2226,7 +2226,8 @@ instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
|
||||
&& !TREE_ADDRESSABLE (base))
|
||||
mark_addressable (base);
|
||||
|
||||
if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
|
||||
if (bos_stmt
|
||||
&& gimple_call_builtin_p (bos_stmt, BUILT_IN_DYNAMIC_OBJECT_SIZE))
|
||||
ubsan_create_edge (bos_stmt);
|
||||
|
||||
/* We have to emit the check. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user