On 06/17/2014 04:24 PM, Trevor Saunders wrote:
On Tue, Jun 17, 2014 at 02:41:38PM +0200, Florian Weimer wrote:
On 06/12/2014 12:04 PM, Jonathan Wakely wrote:
What can we do about it?
How common is it to use std::vector with qsort, rather than
std::sort(vec.begin(), vec.end()), which does the right thing?
Our very own vec::qsort has the same problem, so I'd wager that it's fairly
common.
template<typename T, typename A>
inline void
vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))
{
if (length () > 1)
::qsort (address (), length (), sizeof (T), cmp);
}
So I don't think it does.
Ah, I looked at the wrong branch. It was fixed in r206709, apparently
for performance reasons, see PR46590.
We could make vector::data() guarantee a non-null pointer with
_FORTIFY_SOURCE, but I'd rather not do so in "unfortified" code. Some
users would object to the extra check needed.
Or we could remove the nonnull attributes, so that the additional checks are
not necessary.
I'm not that familiar with the exact requirements of std::vector, could
we use the same trick as
http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275
that is instead of pointing at null point at a global header used for
all empty vectors?
For std::vector, we could use reinterpret_cast<T*>(alignof(T)) or
reinterpret_cast<T*>(sizeof(T)) if those are sufficiently well-defined
as far as GCC is concerned. The smaller constant is easier to load, and
no relocation is required.
--
Florian Weimer / Red Hat Product Security Team