From: Siddhesh Poyarekar Date: Tue, 10 May 2022 07:21:42 +0000 (+0530) Subject: middle-end/70090: Dynamic sizes for -fsanitize=object-size X-Git-Tag: basepoints/gcc-14~6985 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28896b38fabce818e59266b0063a46b3bc1b700f;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c b/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c new file mode 100644 index 00000000000..0159f5b9820 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-fsanitize=undefined" } */ +#include + +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]*\\^" } */ diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc index 0f5b372b195..f74929d0f17 100644 --- a/gcc/ubsan.cc +++ b/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. */