[PR19351, C++] Fix heap overflow in operator new[]
Richard Guenther
richard.guenther@gmail.com
Mon May 30 03:27:00 GMT 2011
On Sun, May 29, 2011 at 9:02 PM, Florian Weimer <fw@deneb.enyo.de> wrote:
> * Jason Merrill:
>
>> Sorry it's taken so long to review this.
>
> Same here. *sigh* Thanks for your comments.
>
>> On 02/21/2011 04:05 PM, Florian Weimer wrote:
>>> build_operator_new_call (tree fnname, VEC(tree,gc) **args,
>>> - tree *size, tree *cookie_size,
>>> + tree *size, tree size_with_cookie, tree *cookie_size,
>>
>> We don't need both size_with_cookie and cookie_size here. Let's
>> change the cookie_size parameter to be size_with_cookie instead (and
>> adjust the places in build_new_1 that check for cookie_size being set
>> or not).
>
> Okay.
>
>>> + if (!flag_new_overflow_check)
>>> + return result;
>>
>> Let's check for constant results here. If we have a TREE_CONSTANT
>> result that overflows, we can handle it even if we aren't emitting the
>> checks for non-constant values.
>
> I assume I can report an error in this case?
Only a warning. The code is only undefined at runtime. But you
could convert the allocation to __builtin_trap () (hmm, what
about exceptions? Is such an allocation required to throw?)
Richard.
>> And if we have a TREE_CONSTANT result that doesn't overflow, we
>> don't have to bother building up the complicated trees in order to
>> fold them away.
>
> Understood. This is sort-of needed ...
>
>>> + nelts = maybe_build_size_mult_saturated
>>> + (convert (sizetype, nelts),
>>> + convert (sizetype, array_type_nelts_top (elt_type)),
>>> + NULL_TREE);
>>
>> It seems unfortunate to do this runtime checking more than once for
>> multi-dimensional new. Since the element size and all but one of the
>> array dimensions are going to be constant in most cases, let's try to
>> multiply the element size with the constant dimensions before we bring
>> in the potentially non-constant dimension.
>
> ... to implement this anyway. I plan to accumulate constant and
> variable factors separately, and multiply them together in the end.
> VARIABLE * VARIABLE will still incur an expensive overflow check
> (involving integer division, even), but there's currently no way
> around that.
>
> I already have something in that direction, but it is still rather
> messy. Hopefully, it will be a temporary measure only, and this
> burden can go away when the middle-end learns about saturating
> arithmetic, or we implement std::bad_array_new_length from C++0X (and
> have removed VLA support).
>
>>> I still need some guidance where to put the test case. There don't
>>> seem to be any direct tests for operator new[] funcionality.
>>
>> Let's put it in g++.dg/init.
>
> Okay. Curiously, the test suite has rather poor coverage of operator
> new[] right now. Multi-dimensional new is also extremely rare in the
> C++ code bases I looked at.
>
More information about the Gcc-patches
mailing list