[Development] QtCS 2017 QtCore sessions
Thiago Macieira
thiago.macieira at intel.com
Wed Nov 1 17:29:35 CET 2017
On quarta-feira, 1 de novembro de 2017 08:58:35 PDT Konstantin Tokarev wrote:
> > There are also no pathological cases since there is no overflow.
>
> There is overflow, try e.g. QByteArray::fromBase64() with array of size
> larger than INT_MAX / 3
Everywhere where they may be overflow, you need to be careful and detect said
overflow. Using signed or unsigned makes no difference: overflowing is bad.
> If size was unsigned such bugs wouldn't lead to crashes or potential
> security issues
Or they would. In QUtf8::convertFromUnicode:
QByteArray result(len * 3, Qt::Uninitialized);
If size() were unsigned and larger than UINT_MAX / 3, then that multiplication
would overflow. The result could potentially be a very small number.
uchar *dst = reinterpret_cast<uchar *>(const_cast<char
*>(result.constData()));
const ushort *src = reinterpret_cast<const ushort *>(uc);
const ushort *const end = src + len;
while (src != end) {
...
}
That loop never rechecks the size of the allocation. It simply assumes that
the destination buffer is large enough to encode the worst case of the UTF-8
This means the use of unsigned would not prevent issues. The loop would still
corrupt memory and could crash.
What's more, the unsigned overflow is not wrong. So you can't flag down the
issue by using a sanitiser. If we keep it as signed, then that multiplication
can be flagged and fixed.
qnumeric_p.h has add_overflow and mul_overflow for unsigned types. For a proper
signed check, you really need help from the compiler. But we can add them on
top of the unsigned ones for the ones that don't help (MSVC), by using the
implementation-defined behaviour of how an unsigned number gets converted to
signed.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
More information about the Development
mailing list