Index: net/libutp/files/patch-CVE-2012-6129 =================================================================== --- /dev/null +++ net/libutp/files/patch-CVE-2012-6129 @@ -0,0 +1,52 @@ +Index: utp.cpp +=================================================================== +--- utp.cpp (revision 13645) ++++ utp.cpp (revision 13646) +@@ -1487,6 +1487,8 @@ size_t UTPSocket::selective_ack_bytes(uint base, c + return acked_bytes; + } + ++enum { MAX_EACK = 128 }; ++ + void UTPSocket::selective_ack(uint base, const byte *mask, byte len) + { + if (cur_window_packets == 0) return; +@@ -1499,7 +1501,7 @@ void UTPSocket::selective_ack(uint base, const byt + // resends is a stack of sequence numbers we need to resend. Since we + // iterate in reverse over the acked packets, at the end, the top packets + // are the ones we want to resend +- int resends[32]; ++ int resends[MAX_EACK]; + int nr = 0; + + LOG_UTPV("0x%08x: Got EACK [%032b] base:%u", this, *(uint32*)mask, base); +@@ -1572,6 +1574,12 @@ void UTPSocket::selective_ack(uint base, const byt + if (((v - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE && + count >= DUPLICATE_ACKS_BEFORE_RESEND && + duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) { ++ // resends is a stack, and we're mostly interested in the top of it ++ // if we're full, just throw away the lower half ++ if (nr >= MAX_EACK - 2) { ++ memmove(resends, &resends[MAX_EACK/2], MAX_EACK/2 * sizeof(resends[0])); ++ nr -= MAX_EACK / 2; ++ } + resends[nr++] = v; + LOG_UTPV("0x%08x: no ack for %u", this, v); + } else { +@@ -1580,13 +1588,12 @@ void UTPSocket::selective_ack(uint base, const byt + } + } while (--bits >= -1); + +- if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) < 256 && +- count >= DUPLICATE_ACKS_BEFORE_RESEND && +- duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) { ++ if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE && ++ count >= DUPLICATE_ACKS_BEFORE_RESEND) { + // if we get enough duplicate acks to start + // resending, the first packet we should resend + // is base-1 +- resends[nr++] = base - 1; ++ resends[nr++] = (base - 1) & ACK_NR_MASK; + } else { + LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u", + this, base - 1, count, duplicate_ack, fast_resend_seq_nr);