Skip to content

Commit c307085

Browse files
committed
Revert "Use the counted_by attribute of pointers in array bound checker." due to PR120929
This reverts commit 9d579c5.
1 parent 3e34c54 commit c307085

File tree

7 files changed

+16
-549
lines changed

7 files changed

+16
-549
lines changed

gcc/c-family/c-gimplify.cc

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,6 @@ along with GCC; see the file COPYING3. If not see
6666
walk back up, we check that they fit our constraints, and copy them
6767
into temporaries if not. */
6868

69-
70-
/* Check whether TP is an address computation whose base is a call to
71-
.ACCESS_WITH_SIZE. */
72-
73-
static bool
74-
is_address_with_access_with_size (tree tp)
75-
{
76-
if (TREE_CODE (tp) == POINTER_PLUS_EXPR
77-
&& (TREE_CODE (TREE_OPERAND (tp, 0)) == INDIRECT_REF)
78-
&& (is_access_with_size_p (TREE_OPERAND (TREE_OPERAND (tp, 0), 0))))
79-
return true;
80-
return false;
81-
}
82-
8369
/* Callback for c_genericize. */
8470

8571
static tree
@@ -135,20 +121,6 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
135121
walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
136122
walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
137123
}
138-
else if (TREE_CODE (*tp) == INDIRECT_REF
139-
&& is_address_with_access_with_size (TREE_OPERAND (*tp, 0)))
140-
{
141-
ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), false);
142-
/* Make sure ubsan_maybe_instrument_array_ref is not called again on
143-
the POINTER_PLUS_EXPR, so ensure it is not walked again and walk
144-
its subtrees manually. */
145-
tree aref = TREE_OPERAND (*tp, 0);
146-
pset->add (aref);
147-
*walk_subtrees = 0;
148-
walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
149-
}
150-
else if (is_address_with_access_with_size (*tp))
151-
ubsan_maybe_instrument_array_ref (tp, true);
152124
return NULL_TREE;
153125
}
154126

gcc/c-family/c-ubsan.cc

Lines changed: 16 additions & 300 deletions
Original file line numberDiff line numberDiff line change
@@ -554,322 +554,38 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
554554
*index, bound);
555555
}
556556

557-
558-
/* Instrument array bounds for the pointer array address which is
559-
an INDIRECT_REF to the call to .ACCESS_WITH_SIZE. We create special
560-
builtin, that gets expanded in the sanopt pass, and make an array
561-
dimention of it. POINTER_ADDR is the pointer array's base address.
562-
*INDEX is an index to the array.
563-
IGNORE_OFF_BY_ONE is true if the POINTER_ADDR is not inside an
564-
INDIRECT_REF.
565-
Return NULL_TREE if no instrumentation is emitted. */
566-
567-
tree
568-
ubsan_instrument_bounds_pointer_address (location_t loc, tree pointer_addr,
569-
tree *index,
570-
bool ignore_off_by_one)
571-
{
572-
gcc_assert (TREE_CODE (pointer_addr) == INDIRECT_REF);
573-
tree call = TREE_OPERAND (pointer_addr, 0);
574-
if (!is_access_with_size_p (call))
575-
return NULL_TREE;
576-
tree bound = get_bound_from_access_with_size (call);
577-
578-
if (ignore_off_by_one)
579-
bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
580-
build_int_cst (TREE_TYPE (bound),
581-
1));
582-
583-
/* Don't emit instrumentation in the most common cases. */
584-
tree idx = NULL_TREE;
585-
if (TREE_CODE (*index) == INTEGER_CST)
586-
idx = *index;
587-
else if (TREE_CODE (*index) == BIT_AND_EXPR
588-
&& TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
589-
idx = TREE_OPERAND (*index, 1);
590-
if (idx
591-
&& TREE_CODE (bound) == INTEGER_CST
592-
&& tree_int_cst_sgn (idx) >= 0
593-
&& tree_int_cst_lt (idx, bound))
594-
return NULL_TREE;
595-
596-
*index = save_expr (*index);
597-
598-
/* Create an array_type for the corresponding pointer array. */
599-
tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
600-
/* The array's element type can be get from the return type of the call to
601-
.ACCESS_WITH_SIZE. */
602-
tree element_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
603-
tree array_type = build_array_type (element_type, itype);
604-
/* Create a "(T *) 0" tree node to describe the array type. */
605-
tree zero_with_type = build_int_cst (build_pointer_type (array_type), 0);
606-
return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
607-
void_type_node, 3, zero_with_type,
608-
*index, bound);
609-
}
610-
611-
/* This structure is to combine a factor with its parent and its position
612-
* in its parent tree. */
613-
struct factor_t
614-
{
615-
tree factor;
616-
tree parent; /* the parent tree of this factor. */
617-
int pos; /* the position of this factor in its parent tree. */
618-
};
619-
620-
/* for a multiply expression like:
621-
((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
622-
623-
locate all the factors, the parents of the factor and the position of
624-
the factor in its parent, and put them to VEC_FACTORS. */
625-
626-
static void
627-
get_factors_from_mul_expr (tree mult_expr, tree parent,
628-
int pos, auto_vec<factor_t> *vec_factors)
629-
{
630-
struct factor_t mult_factor = {0, 0, -1};
631-
mult_factor.factor = mult_expr;
632-
mult_factor.parent = parent;
633-
mult_factor.pos = pos;
634-
635-
while (CONVERT_EXPR_CODE_P (TREE_CODE (mult_expr)))
636-
{
637-
mult_factor.parent = mult_expr;
638-
mult_factor.pos = 0;
639-
mult_expr = TREE_OPERAND (mult_expr, 0);
640-
mult_factor.factor = mult_expr;
641-
}
642-
if (TREE_CODE (mult_expr) != MULT_EXPR)
643-
vec_factors->safe_push (mult_factor);
644-
else
645-
{
646-
get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 0), mult_expr,
647-
0, vec_factors);
648-
get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 1), mult_expr,
649-
1, vec_factors);
650-
}
651-
}
652-
653-
/* Given an OFFSET expression, and the ELEMENT_SIZE,
654-
get the index expression from OFFSET and return it.
655-
For example:
656-
OFFSET:
657-
((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
658-
ELEMENT_SIZE:
659-
(sizetype) SAVE_EXPR <n> * 4
660-
get the index as (long unsigned int) m, and return it.
661-
The INDEX_P holds the pointer to the parent tree of the index,
662-
INDEX_N holds the position of the index in its parent. */
663-
664-
static tree
665-
get_index_from_offset (tree offset, tree *index_p,
666-
int *index_n, tree element_size)
667-
{
668-
if (TREE_CODE (offset) != MULT_EXPR)
669-
return NULL_TREE;
670-
671-
auto_vec<factor_t> e_factors, o_factors;
672-
get_factors_from_mul_expr (element_size, NULL, -1, &e_factors);
673-
get_factors_from_mul_expr (offset, *index_p, *index_n, &o_factors);
674-
675-
if (e_factors.is_empty () || o_factors.is_empty ())
676-
return NULL_TREE;
677-
678-
bool all_found = true;
679-
for (unsigned i = 0; i < e_factors.length (); i++)
680-
{
681-
factor_t e_size_factor = e_factors[i];
682-
bool found = false;
683-
for (unsigned j = 0; j < o_factors.length ();)
684-
{
685-
factor_t o_exp_factor = o_factors[j];
686-
if (operand_equal_p (e_size_factor.factor, o_exp_factor.factor))
687-
{
688-
o_factors.unordered_remove (j);
689-
found = true;
690-
break;
691-
}
692-
else
693-
j++;
694-
}
695-
if (!found)
696-
all_found = false;
697-
}
698-
699-
if (!all_found)
700-
return NULL_TREE;
701-
702-
if (o_factors.length () != 1)
703-
return NULL_TREE;
704-
705-
*index_p = o_factors[0].parent;
706-
*index_n = o_factors[0].pos;
707-
return o_factors[0].factor;
708-
}
709-
710-
/* For an pointer + offset computation expression, such as,
711-
*.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
712-
+ (sizetype) ((long unsigned int) index * 4
713-
Return the index of this pointer array reference,
714-
set the parent tree of INDEX to *INDEX_P.
715-
set the operand position of the INDEX in the parent tree to *INDEX_N.
716-
If failed, return NULL_TREE. */
717-
718-
static tree
719-
get_index_from_pointer_addr_expr (tree pointer, tree *index_p, int *index_n)
720-
{
721-
*index_p = NULL_TREE;
722-
*index_n = -1;
723-
if (TREE_CODE (TREE_OPERAND (pointer, 0)) != INDIRECT_REF)
724-
return NULL_TREE;
725-
tree call = TREE_OPERAND (TREE_OPERAND (pointer, 0), 0);
726-
if (!is_access_with_size_p (call))
727-
return NULL_TREE;
728-
729-
/* Get the pointee type of the call to .ACCESS_WITH_SIZE.
730-
This should be the element type of the pointer array. */
731-
tree pointee_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
732-
tree pointee_size = TYPE_SIZE_UNIT (pointee_type);
733-
734-
tree index_exp = TREE_OPERAND (pointer, 1);
735-
*index_p = pointer;
736-
*index_n = 1;
737-
738-
if (!(TREE_CODE (index_exp) != MULT_EXPR
739-
&& tree_int_cst_equal (pointee_size, integer_one_node)))
740-
{
741-
while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
742-
{
743-
*index_p = index_exp;
744-
*index_n = 0;
745-
index_exp = TREE_OPERAND (index_exp, 0);
746-
}
747-
index_exp = get_index_from_offset (index_exp, index_p,
748-
index_n, pointee_size);
749-
750-
if (!index_exp)
751-
return NULL_TREE;
752-
}
753-
754-
while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
755-
{
756-
*index_p = index_exp;
757-
*index_n = 0;
758-
index_exp = TREE_OPERAND (index_exp, 0);
759-
}
760-
761-
return index_exp;
762-
}
763-
764-
/* Return TRUE when the EXPR is a pointer array address that could be
765-
instrumented.
766-
We only instrument an address computation similar as the following:
767-
*.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
768-
+ (sizetype) ((long unsigned int) index * 4)
769-
if the EXPR is instrumentable, return TRUE and
770-
set the index to *INDEX.
771-
set the *.ACCESS_WITH_SIZE to *BASE.
772-
set the parent tree of INDEX to *INDEX_P.
773-
set the operand position of the INDEX in the parent tree to INDEX_N. */
774-
775-
static bool
776-
is_instrumentable_pointer_array_address (tree expr, tree *base,
777-
tree *index, tree *index_p,
778-
int *index_n)
779-
{
780-
/* For a poiner array address as:
781-
(*.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
782-
+ (sizetype) ((long unsigned int) index * 4)
783-
op0 is the call to *.ACCESS_WITH_SIZE;
784-
op1 is the index. */
785-
if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
786-
return false;
787-
788-
tree op0 = TREE_OPERAND (expr, 0);
789-
if (TREE_CODE (op0) != INDIRECT_REF)
790-
return false;
791-
if (!is_access_with_size_p (TREE_OPERAND (op0, 0)))
792-
return false;
793-
tree op1 = get_index_from_pointer_addr_expr (expr, index_p, index_n);
794-
if (op1 != NULL_TREE)
795-
{
796-
*base = op0;
797-
*index = op1;
798-
return true;
799-
}
800-
return false;
801-
}
802-
803-
/* Return true iff T is an array or an indirect reference that was
804-
instrumented by SANITIZE_BOUNDS. */
557+
/* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
805558

806559
bool
807-
ubsan_array_ref_instrumented_p (tree t)
560+
ubsan_array_ref_instrumented_p (const_tree t)
808561
{
809-
if (TREE_CODE (t) != ARRAY_REF
810-
&& TREE_CODE (t) != MEM_REF)
562+
if (TREE_CODE (t) != ARRAY_REF)
811563
return false;
812564

813-
bool is_array = (TREE_CODE (t) == ARRAY_REF);
814-
tree op0 = NULL_TREE;
815-
tree op1 = NULL_TREE;
816-
tree index_p = NULL_TREE;
817-
int index_n = 0;
818-
if (is_array)
819-
{
820-
op1 = TREE_OPERAND (t, 1);
821-
return TREE_CODE (op1) == COMPOUND_EXPR
822-
&& TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
823-
&& CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
824-
&& CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
825-
}
826-
else if (is_instrumentable_pointer_array_address (t, &op0, &op1,
827-
&index_p, &index_n))
828-
return TREE_CODE (op1) == COMPOUND_EXPR
829-
&& TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
830-
&& CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
831-
&& CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
832-
833-
return false;
565+
tree op1 = TREE_OPERAND (t, 1);
566+
return TREE_CODE (op1) == COMPOUND_EXPR
567+
&& TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
568+
&& CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
569+
&& CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
834570
}
835571

836-
/* Instrument an ARRAY_REF or an address computation whose base address is
837-
a call to .ACCESS_WITH_SIZE, if it hasn't already been instrumented.
838-
IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR, or the
839-
address computation is not inside a INDIRECT_REF. */
572+
/* Instrument an ARRAY_REF, if it hasn't already been instrumented.
573+
IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
840574

841575
void
842576
ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
843577
{
844-
tree e = NULL_TREE;
845-
tree op0 = NULL_TREE;
846-
tree op1 = NULL_TREE;
847-
tree index_p = NULL_TREE; /* the parent tree of INDEX. */
848-
int index_n = 0; /* the operand position of INDEX in the parent tree. */
849-
850578
if (!ubsan_array_ref_instrumented_p (*expr_p)
851579
&& sanitize_flags_p (SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT)
852580
&& current_function_decl != NULL_TREE)
853581
{
854-
if (TREE_CODE (*expr_p) == ARRAY_REF)
855-
{
856-
op0 = TREE_OPERAND (*expr_p, 0);
857-
op1 = TREE_OPERAND (*expr_p, 1);
858-
index_p = *expr_p;
859-
index_n = 1;
860-
e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0,
861-
&op1, ignore_off_by_one);
862-
}
863-
else if (is_instrumentable_pointer_array_address (*expr_p, &op0, &op1,
864-
&index_p, &index_n))
865-
e = ubsan_instrument_bounds_pointer_address (EXPR_LOCATION (*expr_p),
866-
op0, &op1,
867-
ignore_off_by_one);
868-
869-
/* Replace the original INDEX with the instrumented INDEX. */
582+
tree op0 = TREE_OPERAND (*expr_p, 0);
583+
tree op1 = TREE_OPERAND (*expr_p, 1);
584+
tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
585+
ignore_off_by_one);
870586
if (e != NULL_TREE)
871-
TREE_OPERAND (index_p, index_n)
872-
= build2 (COMPOUND_EXPR, TREE_TYPE (op1), e, op1);
587+
TREE_OPERAND (*expr_p, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
588+
e, op1);
873589
}
874590
}
875591

0 commit comments

Comments
 (0)