[elinks-dev] parse_bencoding_integer does not detect all overflows

Kalle Olavi Niemitalo kon at iki.fi
Sat Jan 26 04:14:11 PST 2008


In src/protocol/bittorrent/bencoding.c, parse_bencoding_integer does:

	off_t integer = 0;
...
	for (; pos < length && isdigit(string[pos]); pos++) {
		if (integer > (off_t) integer * 10)
			return 0;
		integer = (off_t) integer * 10 + string[pos] - '0';
	}

The check (integer > (off_t) integer * 10) does not detect all
overflows.  Examples with 32-bit off_t:

integer = 0x1C71C71D (0x100000000/9 rounded up)
integer * 10 = 0x11C71C722, wraps to 0x1C71C722 which is > integer

integer = 0x73333333
integer * 10 = 0x47FFFFFFE, wraps to 0x7FFFFFFE which is > integer

Examples with 64-bit off_t:

integer = 0x1C71C71C71C71C72 (0x10000000000000000/9 rounded up)
integer * 10 = 0x11C71C71C71C71C74, wraps to 0x1C71C71C71C71C74
which is > integer

integer = 0x7333333333333333
integer * 10 = 0x47FFFFFFFFFFFFFFE, wraps to 0x7FFFFFFFFFFFFFFE
which is > integer

So if the overflow check is necessary, it should be corrected.
If overflows can be assumed to wrap (C does not guarantee that),
then I think the following is correct and the simplest solution:

	for (; pos < length && isdigit(string[pos]); pos++) {
                off_t newint = integer * 10 + string[pos] - '0';

                if (newint / 10 != integer)
                        return 0; /* overflow */
                integer = newint;
        }

OTOH, if overflows instead trap or saturate, then this won't work.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 188 bytes
Desc: not available
URL: <http://lists.linuxfromscratch.org/pipermail/elinks-dev/attachments/20080126/c22cba97/attachment.sig>


More information about the elinks-dev mailing list