Recent security fixes

Florian Weimer fweimer at redhat.com
Wed Oct 21 16:22:16 EDT 2015


On 10/19/2015 06:38 AM, ellie timoney wrote:

> On Mon, Oct 5, 2015, at 08:09 PM, Florian Weimer wrote:
>> Hi,
>>
>> Martin Prpic pointed out that you apparently fixed a security issue:
>>
>> <http://openwall.com/lists/oss-security/2015/09/29/2>
>>
>> This is great, thanks.  I think this is the relevant commit:
>>
>> <https://cyrus.foundation/cyrus-imapd/commit/?id=07de4ff1bf2fa340b9d77b8e7de8d43d47a33921>
>>
>> However, I wonder if the fix is complete.  Could n turn negative
>> (possibly after truncation)?  Then the range checks seem incomplete.
> 
> Good catch.  For some reason n is declared as int, even though
> everything that uses it expects some sort of unsigned value (unsigned,
> unsigned long, size_t).  But if the message being fetched is larger than
> the maximum value of an int (unlikely, but I guess not impossible), then
> n can wrap around to negative and "else if (start_octet + n > size)"
> will be incorrect.
> 
> I guess the fix will be to make n an unsigned type, probably unsigned
> long for consistency with the parameters to index_urlfetch, though it'd
> be nice to fix all this to use size_t.

Yes, that's probably the best approach if the code already uses unsigned
variables elsewhere.  Overflow checking for additions is also easier
with unsigned types.

> Looking closer, and assuming n has already been made unsigned, I can
> also see a case where if n is towards the upper end of values that fit
> in an unsigned long, such that start_octet + n wraps around, then we
> have a problem there too.
> 
> Changing this check to something like:
> 
>      else if (n > size || start_octet + n > size)
> 
> ... protects us from that sort of thing iff n is greater than size, but
> if size was already toward the upper limit itself, then start_octet + n
> could wrap around even if n alone is less than size.
> 
> So maybe something like:
> 
>      else if (n > size || start_octet + n < start_octet || start_octet +
>      n > size)
> 
> That seems like it'll protect us from:
>    * n is too big regardless of start_octet
>    * start_octet + n overflows and wraps around
>    * start_octet + n is bigger than size (original case)

I think if n > size, and start_octet + n does not overflow, then
start_octet + n > size.  So the n > size condition seems redundant.

But I may have missed something, I'm not familiar with this code at all.

>> https://cyrus.foundation/cyrus-imapd/commit/?id=c21e179c1f6b968fe69bebe079176714e511587b
> 
> This commit is part of the same fix as the "n" one discussed above, so I
> guess it should be tracked or not tracked as per that one.

Oh, I wasn't ware of that.  Are there any other commits missing, apart
from the follow-up fix discussed above?

Florian



More information about the Cyrus-devel mailing list