From 2925c3d648819d9e43d7562fd60a19e19742ba11 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 04 2015 07:04:28 +0000 Subject: import nss-util-3.19.1-4.el7_1 --- diff --git a/SOURCES/nss-3.20.1-security-fix.patch b/SOURCES/nss-3.20.1-security-fix.patch new file mode 100644 index 0000000..47597d0 --- /dev/null +++ b/SOURCES/nss-3.20.1-security-fix.patch @@ -0,0 +1,271 @@ +diff --git a/lib/util/secasn1d.c b/lib/util/secasn1d.c +--- a/lib/util/secasn1d.c ++++ b/lib/util/secasn1d.c +@@ -946,31 +946,116 @@ sec_asn1d_parse_more_length (sec_asn1d_s + } + + if (state->pending == 0) + state->place = afterLength; + + return count; + } + ++/* ++ * Helper function for sec_asn1d_prepare_for_contents. ++ * Checks that a value representing a number of bytes consumed can be ++ * subtracted from a remaining length. If so, returns PR_TRUE. ++ * Otherwise, sets the error SEC_ERROR_BAD_DER, indicates that there was a ++ * decoding error in the given SEC_ASN1DecoderContext, and returns PR_FALSE. ++ */ ++static PRBool ++sec_asn1d_check_and_subtract_length (unsigned long *remaining, ++ unsigned long consumed, ++ SEC_ASN1DecoderContext *cx) ++{ ++ PORT_Assert(remaining); ++ PORT_Assert(cx); ++ if (!remaining || !cx) { ++ PORT_SetError (SEC_ERROR_INVALID_ARGS); ++ cx->status = decodeError; ++ return PR_FALSE; ++ } ++ if (*remaining < consumed) { ++ PORT_SetError (SEC_ERROR_BAD_DER); ++ cx->status = decodeError; ++ return PR_FALSE; ++ } ++ *remaining -= consumed; ++ return PR_TRUE; ++} + + static void + sec_asn1d_prepare_for_contents (sec_asn1d_state *state) + { + SECItem *item; + PLArenaPool *poolp; + unsigned long alloc_len; ++ sec_asn1d_state *parent; + + #ifdef DEBUG_ASN1D_STATES + { + printf("Found Length %d %s\n", state->contents_length, + state->indefinite ? "indefinite" : ""); + } + #endif + ++ /** ++ * The maximum length for a child element should be constrained to the ++ * length remaining in the first definite length element in the ancestor ++ * stack. If there is no definite length element in the ancestor stack, ++ * there's nothing to constrain the length of the child, so there's no ++ * further processing necessary. ++ * ++ * It's necessary to walk the ancestor stack, because it's possible to have ++ * definite length children that are part of an indefinite length element, ++ * which is itself part of an indefinite length element, and which is ++ * ultimately part of a definite length element. A simple example of this ++ * would be the handling of constructed OCTET STRINGs in BER encoding. ++ * ++ * This algorithm finds the first definite length element in the ancestor ++ * stack, if any, and if so, ensures that the length of the child element ++ * is consistent with the number of bytes remaining in the constraining ++ * ancestor element (that is, after accounting for any other sibling ++ * elements that may have been read). ++ * ++ * It's slightly complicated by the need to account both for integer ++ * underflow and overflow, as well as ensure that for indefinite length ++ * encodings, there's also enough space for the End-of-Contents (EOC) ++ * octets (Tag = 0x00, Length = 0x00, or two bytes). ++ */ ++ ++ /* Determine the maximum length available for this element by finding the ++ * first definite length ancestor, if any. */ ++ parent = sec_asn1d_get_enclosing_construct(state); ++ while (parent && parent->indefinite) { ++ parent = sec_asn1d_get_enclosing_construct(parent); ++ } ++ /* If parent is null, state is either the outermost state / at the top of ++ * the stack, or the outermost state uses indefinite length encoding. In ++ * these cases, there's nothing external to constrain this element, so ++ * there's nothing to check. */ ++ if (parent) { ++ unsigned long remaining = parent->pending; ++ parent = state; ++ do { ++ if (!sec_asn1d_check_and_subtract_length( ++ &remaining, parent->consumed, state->top) || ++ /* If parent->indefinite is true, parent->contents_length is ++ * zero and this is a no-op. */ ++ !sec_asn1d_check_and_subtract_length( ++ &remaining, parent->contents_length, state->top) || ++ /* If parent->indefinite is true, then ensure there is enough ++ * space for an EOC tag of 2 bytes. */ ++ (parent->indefinite && !sec_asn1d_check_and_subtract_length( ++ &remaining, 2, state->top))) { ++ /* This element is larger than its enclosing element, which is ++ * invalid. */ ++ return; ++ } ++ } while ((parent = sec_asn1d_get_enclosing_construct(parent)) && ++ parent->indefinite); ++ } ++ + /* + * XXX I cannot decide if this allocation should exclude the case + * where state->endofcontents is true -- figure it out! + */ + if (state->allocate) { + void *dest; + + PORT_Assert (state->dest == NULL); +@@ -1002,31 +1087,16 @@ sec_asn1d_prepare_for_contents (sec_asn1 + } + + /* + * Remember, length may be indefinite here! In that case, + * both contents_length and pending will be zero. + */ + state->pending = state->contents_length; + +- /* If this item has definite length encoding, and +- ** is enclosed by a definite length constructed type, +- ** make sure it isn't longer than the remaining space in that +- ** constructed type. +- */ +- if (state->contents_length > 0) { +- sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state); +- if (parent && !parent->indefinite && +- state->consumed + state->contents_length > parent->pending) { +- PORT_SetError (SEC_ERROR_BAD_DER); +- state->top->status = decodeError; +- return; +- } +- } +- + /* + * An EXPLICIT is nothing but an outer header, which we have + * already parsed and accepted. Now we need to do the inner + * header and its contents. + */ + if (state->explicit) { + state->place = afterExplicit; + state = sec_asn1d_push_state (state->top, +@@ -1715,20 +1785,117 @@ sec_asn1d_next_substring (sec_asn1d_stat + state->top->status = decodeError; + return; + } + + state->pending -= child_consumed; + if (state->pending == 0) + done = PR_TRUE; + } else { ++ PRBool preallocatedString; ++ sec_asn1d_state *temp_state; + PORT_Assert (state->indefinite); + + item = (SECItem *)(child->dest); +- if (item != NULL && item->data != NULL) { ++ ++ /** ++ * At this point, there's three states at play: ++ * child: The element that was just parsed ++ * state: The currently processed element ++ * 'parent' (aka state->parent): The enclosing construct ++ * of state, or NULL if this is the top-most element. ++ * ++ * This state handles both substrings of a constructed string AND ++ * child elements of items whose template type was that of ++ * SEC_ASN1_ANY, SEC_ASN1_SAVE, SEC_ASN1_ANY_CONTENTS, SEC_ASN1_SKIP ++ * template, as described in sec_asn1d_prepare_for_contents. For ++ * brevity, these will be referred to as 'string' and 'any' types. ++ * ++ * This leads to the following possibilities: ++ * 1: This element is an indefinite length string, part of a ++ * definite length string. ++ * 2: This element is an indefinite length string, part of an ++ * indefinite length string. ++ * 3: This element is an indefinite length any, part of a ++ * definite length any. ++ * 4: This element is an indefinite length any, part of an ++ * indefinite length any. ++ * 5: This element is an indefinite length any and does not ++ * meet any of the above criteria. Note that this would include ++ * an indefinite length string type matching an indefinite ++ * length any template. ++ * ++ * In Cases #1 and #3, the definite length 'parent' element will ++ * have allocated state->dest based on the parent elements definite ++ * size. During the processing of 'child', sec_asn1d_parse_leaf will ++ * have copied the (string, any) data directly into the offset of ++ * dest, as appropriate, so there's no need for this class to still ++ * store the child - it's already been processed. ++ * ++ * In Cases #2 and #4, dest will be set to the parent element's dest, ++ * but dest->data will not have been allocated yet, due to the ++ * indefinite length encoding. In this situation, it's necessary to ++ * hold onto child (and all other children) until the EOC, at which ++ * point, it becomes possible to compute 'state's overall length. Once ++ * 'state' has a computed length, this can then be fed to 'parent' (via ++ * this state), and then 'parent' can similarly compute the length of ++ * all of its children up to the EOC, which will ultimately transit to ++ * sec_asn1d_concat_substrings, determine the overall size needed, ++ * allocate, and copy the contents (of all of parent's children, which ++ * would include 'state', just as 'state' will have copied all of its ++ * children via sec_asn1d_concat_substrings) ++ * ++ * The final case, Case #5, will manifest in that item->data and ++ * item->len will be NULL/0, respectively, since this element was ++ * indefinite-length encoded. In that case, both the tag and length will ++ * already exist in state's subitems, via sec_asn1d_record_any_header, ++ * and so the contents (aka 'child') should be added to that list of ++ * items to concatenate in sec_asn1d_concat_substrings once the EOC ++ * is encountered. ++ * ++ * To distinguish #2/#4 from #1/#3, it's sufficient to walk the ancestor ++ * tree. If the current type is a string type, then the enclosing ++ * construct will be that same type (#1/#2). If the current type is an ++ * any type, then the enclosing construct is either an any type (#3/#4) ++ * or some other type (#5). Since this is BER, this nesting relationship ++ * between 'state' and 'parent' may go through several levels of ++ * constructed encoding, so continue walking the ancestor chain until a ++ * clear determination can be made. ++ * ++ * The variable preallocatedString is used to indicate Case #1/#3, ++ * indicating an in-place copy has already occurred, and Cases #2, #4, ++ * and #5 all have the same behaviour of adding a new substring. ++ */ ++ preallocatedString = PR_FALSE; ++ temp_state = state; ++ while (temp_state && item == temp_state->dest && temp_state->indefinite) { ++ sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(temp_state); ++ if (!parent || parent->underlying_kind != temp_state->underlying_kind) { ++ /* Case #5 - Either this is a top-level construct or it is part ++ * of some other element (e.g. a SEQUENCE), in which case, a ++ * new item should be allocated. */ ++ break; ++ } ++ if (!parent->indefinite) { ++ /* Cases #1 / #3 - A definite length ancestor exists, for which ++ * this is a substring that has already copied into dest. */ ++ preallocatedString = PR_TRUE; ++ break; ++ } ++ if (!parent->substring) { ++ /* Cases #2 / #4 - If the parent is not a substring, but is ++ * indefinite, then there's nothing further up that may have ++ * preallocated dest, thus child will not have already ++ * been copied in place, therefore it's necessary to save child ++ * as a subitem. */ ++ break; ++ } ++ temp_state = parent; ++ } ++ if (item != NULL && item->data != NULL && !preallocatedString) { + /* + * Save the string away for later concatenation. + */ + PORT_Assert (item->data != NULL); + sec_asn1d_add_to_subitems (state, item->data, item->len, PR_FALSE); + /* + * Clear the child item for the next round. + */ diff --git a/SPECS/nss-util.spec b/SPECS/nss-util.spec index 9f28188..2be6b13 100644 --- a/SPECS/nss-util.spec +++ b/SPECS/nss-util.spec @@ -1,15 +1,17 @@ %global nspr_version 4.10.8 +# adjust to the very latest build needed +%global nspr_build_version -2 Summary: Network Security Services Utilities Library Name: nss-util Version: 3.19.1 -Release: 3%{?dist} +Release: 4%{?dist} License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries -Requires: nspr >= %{nspr_version} +Requires: nspr >= %{nspr_version}%{nspr_build_version} BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: nspr-devel >= %{nspr_version} +BuildRequires: nspr-devel >= %{nspr_version}%{nspr_build_version} BuildRequires: zlib-devel BuildRequires: pkgconfig BuildRequires: gawk @@ -35,6 +37,8 @@ Patch1: build-nss-util-only.patch Patch2: hasht-dont-include-prtypes.patch Patch7: pkcs1sig-include-prtypes.patch Patch8: nss-util-3.19.1-tls12-mechanisms.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1205157 +Patch9: nss-3.20.1-security-fix.patch %description Utilities for Network Security Services and the Softoken module @@ -60,6 +64,7 @@ Header and library files for doing development with Network Security Services. %patch7 -p0 -b .include_prtypes pushd nss %patch8 -p1 -b .tls12_mechs +%patch9 -p1 -b .various_flaws popd @@ -227,6 +232,9 @@ done %{_includedir}/nss3/templates/templates.c %changelog +* Fri Oct 16 2015 Elio Maldonado - 3.19.1-4 +- Resolves: Bug 1269357 - CVE-2015-7182 CVE-2015-7181 + * Thu Jun 18 2015 Elio Maldonado - 3.19.1-3 - Remove unused patch