diff options
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch')
-rw-r--r-- | gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch new file mode 100644 index 0000000000..cd98d0b28b --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch @@ -0,0 +1,266 @@ + changeset: 312063:88bea96c802a + user: Andrea Marchesini <amarchesini@mozilla.com> + Date: Tue May 10 10:52:19 2016 +0200 + summary: Bug 1267130 - Improve the URL segment calculation, r=valentin a=ritu + +diff -r 28dcecced055 -r 88bea96c802a netwerk/base/nsStandardURL.cpp +--- a/netwerk/base/nsStandardURL.cpp Wed May 18 11:55:29 2016 +1200 ++++ b/netwerk/base/nsStandardURL.cpp Tue May 10 10:52:19 2016 +0200 +@@ -475,19 +475,28 @@ + } + + uint32_t +-nsStandardURL::AppendSegmentToBuf(char *buf, uint32_t i, const char *str, URLSegment &seg, const nsCString *escapedStr, bool useEscaped) ++nsStandardURL::AppendSegmentToBuf(char *buf, uint32_t i, const char *str, ++ const URLSegment &segInput, URLSegment &segOutput, ++ const nsCString *escapedStr, ++ bool useEscaped, int32_t *diff) + { +- if (seg.mLen > 0) { ++ MOZ_ASSERT(segInput.mLen == segOutput.mLen); ++ ++ if (diff) *diff = 0; ++ ++ if (segInput.mLen > 0) { + if (useEscaped) { +- seg.mLen = escapedStr->Length(); +- memcpy(buf + i, escapedStr->get(), seg.mLen); ++ MOZ_ASSERT(diff); ++ segOutput.mLen = escapedStr->Length(); ++ *diff = segOutput.mLen - segInput.mLen; ++ memcpy(buf + i, escapedStr->get(), segOutput.mLen); ++ } else { ++ memcpy(buf + i, str + segInput.mPos, segInput.mLen); + } +- else +- memcpy(buf + i, str + seg.mPos, seg.mLen); +- seg.mPos = i; +- i += seg.mLen; ++ segOutput.mPos = i; ++ i += segOutput.mLen; + } else { +- seg.mPos = i; ++ segOutput.mPos = i; + } + return i; + } +@@ -598,6 +607,20 @@ + } + } + ++ // We must take a copy of every single segment because they are pointing to ++ // the |spec| while we are changing their value, in case we must use ++ // encoded strings. ++ URLSegment username(mUsername); ++ URLSegment password(mPassword); ++ URLSegment host(mHost); ++ URLSegment path(mPath); ++ URLSegment filepath(mFilepath); ++ URLSegment directory(mDirectory); ++ URLSegment basename(mBasename); ++ URLSegment extension(mExtension); ++ URLSegment query(mQuery); ++ URLSegment ref(mRef); ++ + // + // generate the normalized URL string + // +@@ -607,9 +630,10 @@ + char *buf; + mSpec.BeginWriting(buf); + uint32_t i = 0; ++ int32_t diff = 0; + + if (mScheme.mLen > 0) { +- i = AppendSegmentToBuf(buf, i, spec, mScheme); ++ i = AppendSegmentToBuf(buf, i, spec, mScheme, mScheme); + net_ToLowerCase(buf + mScheme.mPos, mScheme.mLen); + i = AppendToBuf(buf, i, "://", 3); + } +@@ -619,15 +643,22 @@ + + // append authority + if (mUsername.mLen > 0) { +- i = AppendSegmentToBuf(buf, i, spec, mUsername, &encUsername, useEncUsername); +- if (mPassword.mLen >= 0) { ++ i = AppendSegmentToBuf(buf, i, spec, username, mUsername, ++ &encUsername, useEncUsername, &diff); ++ ShiftFromPassword(diff); ++ if (password.mLen >= 0) { + buf[i++] = ':'; +- i = AppendSegmentToBuf(buf, i, spec, mPassword, &encPassword, useEncPassword); ++ i = AppendSegmentToBuf(buf, i, spec, password, mPassword, ++ &encPassword, useEncPassword, &diff); ++ ShiftFromHost(diff); + } + buf[i++] = '@'; + } +- if (mHost.mLen > 0) { +- i = AppendSegmentToBuf(buf, i, spec, mHost, &encHost, useEncHost); ++ if (host.mLen > 0) { ++ i = AppendSegmentToBuf(buf, i, spec, host, mHost, &encHost, useEncHost, ++ &diff); ++ ShiftFromPath(diff); ++ + net_ToLowerCase(buf + mHost.mPos, mHost.mLen); + MOZ_ASSERT(mPort >= -1, "Invalid negative mPort"); + if (mPort != -1 && mPort != mDefaultPort) { +@@ -652,21 +683,23 @@ + } + else { + uint32_t leadingSlash = 0; +- if (spec[mPath.mPos] != '/') { ++ if (spec[path.mPos] != '/') { + LOG(("adding leading slash to path\n")); + leadingSlash = 1; + buf[i++] = '/'; + // basename must exist, even if empty (bugs 113508, 429347) + if (mBasename.mLen == -1) { +- mBasename.mPos = i; +- mBasename.mLen = 0; ++ mBasename.mPos = basename.mPos = i; ++ mBasename.mLen = basename.mLen = 0; + } + } + + // record corrected (file)path starting position + mPath.mPos = mFilepath.mPos = i - leadingSlash; + +- i = AppendSegmentToBuf(buf, i, spec, mDirectory, &encDirectory, useEncDirectory); ++ i = AppendSegmentToBuf(buf, i, spec, directory, mDirectory, ++ &encDirectory, useEncDirectory, &diff); ++ ShiftFromBasename(diff); + + // the directory must end with a '/' + if (buf[i-1] != '/') { +@@ -674,7 +707,9 @@ + mDirectory.mLen++; + } + +- i = AppendSegmentToBuf(buf, i, spec, mBasename, &encBasename, useEncBasename); ++ i = AppendSegmentToBuf(buf, i, spec, basename, mBasename, ++ &encBasename, useEncBasename, &diff); ++ ShiftFromExtension(diff); + + // make corrections to directory segment if leadingSlash + if (leadingSlash) { +@@ -687,18 +722,24 @@ + + if (mExtension.mLen >= 0) { + buf[i++] = '.'; +- i = AppendSegmentToBuf(buf, i, spec, mExtension, &encExtension, useEncExtension); ++ i = AppendSegmentToBuf(buf, i, spec, extension, mExtension, ++ &encExtension, useEncExtension, &diff); ++ ShiftFromQuery(diff); + } + // calculate corrected filepath length + mFilepath.mLen = i - mFilepath.mPos; + + if (mQuery.mLen >= 0) { + buf[i++] = '?'; +- i = AppendSegmentToBuf(buf, i, spec, mQuery, &encQuery, useEncQuery); ++ i = AppendSegmentToBuf(buf, i, spec, query, mQuery, ++ &encQuery, useEncQuery, ++ &diff); ++ ShiftFromRef(diff); + } + if (mRef.mLen >= 0) { + buf[i++] = '#'; +- i = AppendSegmentToBuf(buf, i, spec, mRef, &encRef, useEncRef); ++ i = AppendSegmentToBuf(buf, i, spec, ref, mRef, &encRef, useEncRef, ++ &diff); + } + // calculate corrected path length + mPath.mLen = i - mPath.mPos; +@@ -953,6 +994,39 @@ + #undef GOT_PREF + } + ++#define SHIFT_FROM(name, what) \ ++void \ ++nsStandardURL::name(int32_t diff) \ ++{ \ ++ if (!diff) return; \ ++ if (what.mLen >= 0) { \ ++ CheckedInt<int32_t> pos = what.mPos; \ ++ pos += diff; \ ++ MOZ_ASSERT(pos.isValid()); \ ++ what.mPos = pos.value(); \ ++ } ++ ++#define SHIFT_FROM_NEXT(name, what, next) \ ++ SHIFT_FROM(name, what) \ ++ next(diff); \ ++} ++ ++#define SHIFT_FROM_LAST(name, what) \ ++ SHIFT_FROM(name, what) \ ++} ++ ++SHIFT_FROM_NEXT(ShiftFromAuthority, mAuthority, ShiftFromUsername) ++SHIFT_FROM_NEXT(ShiftFromUsername, mUsername, ShiftFromPassword) ++SHIFT_FROM_NEXT(ShiftFromPassword, mPassword, ShiftFromHost) ++SHIFT_FROM_NEXT(ShiftFromHost, mHost, ShiftFromPath) ++SHIFT_FROM_NEXT(ShiftFromPath, mPath, ShiftFromFilepath) ++SHIFT_FROM_NEXT(ShiftFromFilepath, mFilepath, ShiftFromDirectory) ++SHIFT_FROM_NEXT(ShiftFromDirectory, mDirectory, ShiftFromBasename) ++SHIFT_FROM_NEXT(ShiftFromBasename, mBasename, ShiftFromExtension) ++SHIFT_FROM_NEXT(ShiftFromExtension, mExtension, ShiftFromQuery) ++SHIFT_FROM_NEXT(ShiftFromQuery, mQuery, ShiftFromRef) ++SHIFT_FROM_LAST(ShiftFromRef, mRef) ++ + //---------------------------------------------------------------------------- + // nsStandardURL::nsISupports + //---------------------------------------------------------------------------- +diff -r 28dcecced055 -r 88bea96c802a netwerk/base/nsStandardURL.h +--- a/netwerk/base/nsStandardURL.h Wed May 18 11:55:29 2016 +1200 ++++ b/netwerk/base/nsStandardURL.h Tue May 10 10:52:19 2016 +0200 +@@ -77,6 +77,7 @@ + + URLSegment() : mPos(0), mLen(-1) {} + URLSegment(uint32_t pos, int32_t len) : mPos(pos), mLen(len) {} ++ URLSegment(const URLSegment& aCopy) : mPos(aCopy.mPos), mLen(aCopy.mLen) {} + void Reset() { mPos = 0; mLen = -1; } + // Merge another segment following this one to it if they're contiguous + // Assumes we have something like "foo;bar" where this object is 'foo' and right +@@ -177,7 +178,10 @@ + bool NormalizeIDN(const nsCSubstring &host, nsCString &result); + void CoalescePath(netCoalesceFlags coalesceFlag, char *path); + +- uint32_t AppendSegmentToBuf(char *, uint32_t, const char *, URLSegment &, const nsCString *esc=nullptr, bool useEsc = false); ++ uint32_t AppendSegmentToBuf(char *, uint32_t, const char *, ++ const URLSegment &input, URLSegment &output, ++ const nsCString *esc=nullptr, ++ bool useEsc = false, int32_t* diff = nullptr); + uint32_t AppendToBuf(char *, uint32_t, const char *, uint32_t); + + nsresult BuildNormalizedSpec(const char *spec); +@@ -216,17 +220,17 @@ + const nsDependentCSubstring Ref() { return Segment(mRef); } + + // shift the URLSegments to the right by diff +- void ShiftFromAuthority(int32_t diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); } +- void ShiftFromUsername(int32_t diff) { mUsername.mPos += diff; ShiftFromPassword(diff); } +- void ShiftFromPassword(int32_t diff) { mPassword.mPos += diff; ShiftFromHost(diff); } +- void ShiftFromHost(int32_t diff) { mHost.mPos += diff; ShiftFromPath(diff); } +- void ShiftFromPath(int32_t diff) { mPath.mPos += diff; ShiftFromFilepath(diff); } +- void ShiftFromFilepath(int32_t diff) { mFilepath.mPos += diff; ShiftFromDirectory(diff); } +- void ShiftFromDirectory(int32_t diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); } +- void ShiftFromBasename(int32_t diff) { mBasename.mPos += diff; ShiftFromExtension(diff); } +- void ShiftFromExtension(int32_t diff) { mExtension.mPos += diff; ShiftFromQuery(diff); } +- void ShiftFromQuery(int32_t diff) { mQuery.mPos += diff; ShiftFromRef(diff); } +- void ShiftFromRef(int32_t diff) { mRef.mPos += diff; } ++ void ShiftFromAuthority(int32_t diff); ++ void ShiftFromUsername(int32_t diff); ++ void ShiftFromPassword(int32_t diff); ++ void ShiftFromHost(int32_t diff); ++ void ShiftFromPath(int32_t diff); ++ void ShiftFromFilepath(int32_t diff); ++ void ShiftFromDirectory(int32_t diff); ++ void ShiftFromBasename(int32_t diff); ++ void ShiftFromExtension(int32_t diff); ++ void ShiftFromQuery(int32_t diff); ++ void ShiftFromRef(int32_t diff); + + // fastload helper functions + nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &); |