Index: patches/nss-rc4-invalid-read.patch |
=================================================================== |
--- patches/nss-rc4-invalid-read.patch (revision 0) |
+++ patches/nss-rc4-invalid-read.patch (revision 0) |
@@ -0,0 +1,66 @@ |
+Index: nss/lib/freebl/arcfour.c |
+=================================================================== |
+--- nss/lib/freebl/arcfour.c (revision 197511) |
++++ nss/lib/freebl/arcfour.c (working copy) |
+@@ -372,7 +372,6 @@ |
+ register Stype tmpSi, tmpSj; |
+ register PRUint8 tmpi = cx->i; |
+ register PRUint8 tmpj = cx->j; |
+- unsigned int byteCount; |
+ unsigned int bufShift, invBufShift; |
+ unsigned int i; |
+ const unsigned char *finalIn; |
+@@ -390,7 +389,7 @@ |
+ *outputLen = inputLen; |
+ pInWord = (const WORD *)(input - inOffset); |
+ pOutWord = (WORD *)(output - outOffset); |
+- if (inOffset < outOffset) { |
++ if (inOffset <= outOffset) { |
+ bufShift = 8*(outOffset - inOffset); |
+ invBufShift = 8*WORDSIZE - bufShift; |
+ } else { |
+@@ -406,7 +405,7 @@ |
+ /* least one partial word of input should ALWAYS be loaded. */ |
+ /*****************************************************************/ |
+ if (outOffset) { |
+- byteCount = WORDSIZE - outOffset; |
++ unsigned int byteCount = WORDSIZE - outOffset; |
+ for (i = 0; i < byteCount; i++) { |
+ ARCFOUR_NEXT_BYTE(); |
+ output[i] = cx->S[t] ^ input[i]; |
+@@ -466,10 +465,6 @@ |
+ inWord = 0; |
+ } |
+ } |
+- /* Output buffer is aligned, inOffset is now measured relative to |
+- * outOffset (and not a word boundary). |
+- */ |
+- inOffset = (inOffset + WORDSIZE - outOffset) % WORDSIZE; |
+ /*****************************************************************/ |
+ /* Step 2: main loop */ |
+ /* At this point the output buffer is word-aligned. Any unused */ |
+@@ -477,8 +472,13 @@ |
+ /* the input buffer is unaligned relative to the output buffer, */ |
+ /* shifting has to be done. */ |
+ /*****************************************************************/ |
+- if (inOffset) { |
+- for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { |
++ if (bufShift) { |
++ /* preloadedByteCount is the number of input bytes pre-loaded |
++ * in inWord. |
++ */ |
++ unsigned int preloadedByteCount = bufShift/8; |
++ for (; inputLen >= preloadedByteCount + WORDSIZE; |
++ inputLen -= WORDSIZE) { |
+ nextInWord = *pInWord++; |
+ inWord |= nextInWord RSH bufShift; |
+ nextInWord = nextInWord LSH invBufShift; |
+@@ -492,7 +492,7 @@ |
+ cx->j = tmpj; |
+ return SECSuccess; |
+ } |
+- finalIn = (const unsigned char *)pInWord - WORDSIZE + inOffset; |
++ finalIn = (const unsigned char *)pInWord - preloadedByteCount; |
+ } else { |
+ for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { |
+ inWord = *pInWord++; |