Dizzy Next
cover Dizzy Next
Please consider the these changes for Dizzy next.
The following changes since commit 6dcaf44d8c28c466ff271d5f5585a84632bf8769:
subversion: Security Advisory - subversion - CVE-2014-3522 (2014-11-11 09:04:57 -0800)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib akuster/dizzy-next
http://git.yoctoproject.org/cgit.cgi//log/?h=akuster/dizzy-next
Armin Kuster (2):
tzcode: update to 2014j
tzdata: update to 2014j
Chong Lu (3):
curl: Security Advisory - curl - CVE-2014-3613
curl: Security Advisory - curl - CVE-2014-3620
nss: CVE-2014-1568
Yue Tao (1):
subversion: Security Advisory - subversion - CVE-2014-3528
.../subversion/subversion-CVE-2014-3528.patch | 29 + .../subversion/subversion_1.6.15.bb | 1 + .../subversion/subversion_1.8.9.bb | 1 + .../recipes-extended/tzcode/tzcode-native_2014j.bb | 10 + meta/recipes-extended/tzdata/tzdata_2014j.bb | 6 + meta/recipes-support/curl/curl/CVE-2014-3613.patch | 269 +++++++++ meta/recipes-support/curl/curl/CVE-2014-3620.patch | 69 +++ meta/recipes-support/curl/curl_7.37.1.bb | 2 + .../nss/files/nss-CVE-2014-1568.patch | 670 +++++++++++++++++++++ meta/recipes-support/nss/nss.inc | 1 + 10 files changed, 1058 insertions(+) create mode 100644 meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch create mode 100644 meta/recipes-extended/tzcode/tzcode-native_2014j.bb create mode 100644 meta/recipes-extended/tzdata/tzdata_2014j.bb create mode 100644 meta/recipes-support/curl/curl/CVE-2014-3613.patch create mode 100644 meta/recipes-support/curl/curl/CVE-2014-3620.patch create mode 100644 meta/recipes-support/nss/files/nss-CVE-2014-1568.patch
Signature · 1 line
1.9.1
PATCH 1/6 subversion: Security Advisory - subversion - CVE-2014-3528
From: Yue Tao <[email protected]>
Apache Subversion 1.0.0 through 1.7.x before 1.7.17 and 1.8.x before 1.8.10 uses an MD5 hash of the URL and authentication realm to store cached credentials, which makes it easier for remote servers to obtain the credentials via a crafted authentication realm.
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3528
(From OE-Core rev: e0dc0432b13f38d16f642bdadf8ebc78b7a74806)
--- .../subversion/subversion-CVE-2014-3528.patch | 29 ++++++++++++++++++++++ .../subversion/subversion_1.6.15.bb | 1 + .../subversion/subversion_1.8.9.bb | 1 + 3 files changed, 31 insertions(+) create mode 100644 meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +29 -0
@@ -0,0 +1,29 @@ +Upstream-Status: Backport + +Signed-off-by: Yue Tao <[email protected]> + +diff --git a/subversion/libsvn_subr/config_auth.c.old b/subversion/libsvn_subr/config_auth.c +index ff50270..c511d04 100644 +--- a/subversion/libsvn_subr/config_auth.c.old ++++ b/subversion/libsvn_subr/config_auth.c +@@ -85,6 +85,7 @@ svn_config_read_auth_data(apr_hash_t **hash, + if (kind == svn_node_file) + { + svn_stream_t *stream; ++ svn_string_t *stored_realm; + + SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool), + _("Unable to open auth file for reading")); +@@ -95,6 +96,12 @@ svn_config_read_auth_data(apr_hash_t **hash, + apr_psprintf(pool, _("Error parsing '%s'"), + svn_path_local_style(auth_path, pool))); + ++ stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY, ++ APR_HASH_KEY_STRING); ++ ++ if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0) ++ *hash = NULL; /* Hash collision, or somebody tampering with storage */ ++ + SVN_ERR(svn_stream_close(stream)); + } +
meta/recipes-devtools/subversion/subversion_1.6.15.bb +1 -0
@@ -19,6 +19,7 @@ SRC_URI = "http://subversion.tigris.org/downloads/${BPN}-${PV}.tar.bz2 \ file://subversion-CVE-2013-1847-CVE-2013-1846.patch \ file://subversion-CVE-2013-4277.patch \ file://subversion-CVE-2014-3522.patch \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "113fca1d9e4aa389d7dc2b210010fa69"
meta/recipes-devtools/subversion/subversion_1.8.9.bb +1 -0
@@ -13,6 +13,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ file://subversion-CVE-2014-3522.patch;striplevel=0 \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "bd495517a760ddd764ce449a891971db" SRC_URI[sha256sum] = "45d708a5c3ffbef4b2a1044c4716a053e680763743d1f7ba99d0369f6da49e33"
Signature · 1 line
1.9.1
PATCH 2/6 curl: Security Advisory - curl - CVE-2014-3613
In reply to Armin KusterFrom: Chong Lu <[email protected]>
By not detecting and rejecting domain names for partial literal IP addresses properly when parsing received HTTP cookies, libcurl can be fooled to both sending cookies to wrong sites and into allowing arbitrary sites to set cookies for others.
(From OE-Core rev: 985ef933208da1dd1f17645613ce08e6ad27e2c1)
--- meta/recipes-support/curl/curl/CVE-2014-3613.patch | 269 +++++++++++++++++++++ meta/recipes-support/curl/curl_7.37.1.bb | 1 + 2 files changed, 270 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2014-3613.patch
meta/recipes-support/curl/curl/CVE-2014-3613.patch new file +269 -0
@@ -0,0 +1,269 @@ +From 545e322cc8c383ccdfb4ad85a1634c2b719a1adf Mon Sep 17 00:00:00 2001 +From: Tim Ruehsen <[email protected]> +Date: Tue, 19 Aug 2014 21:01:28 +0200 +Subject: [PATCH] cookies: only use full host matches for hosts used as IP + address + +By not detecting and rejecting domain names for partial literal IP +addresses properly when parsing received HTTP cookies, libcurl can be +fooled to both send cookies to wrong sites and to allow arbitrary sites +to set cookies for others. + +CVE-2014-3613 + +Bug: http://curl.haxx.se/docs/adv_20140910A.html + +Upstream-Status: Backport + +Signed-off-by: Chong Lu <[email protected]> +--- + lib/cookie.c | 50 ++++++++++++++++++++++++++++++++++++++---------- + tests/data/test1105 | 3 +-- + tests/data/test31 | 55 +++++++++++++++++++++++++++-------------------------- + tests/data/test8 | 3 ++- + 4 files changed, 71 insertions(+), 40 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 0590643..46904ac 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -93,10 +93,11 @@ Example set of cookies: + #include "curl_memory.h" + #include "share.h" + #include "strtoofft.h" + #include "rawstr.h" + #include "curl_memrchr.h" ++#include "inet_pton.h" + + /* The last #include file should be: */ + #include "memdebug.h" + + static void freecookie(struct Cookie *co) +@@ -317,10 +318,32 @@ static void remove_expired(struct CookieInfo *cookies) + } + co = nx; + } + } + ++/* ++ * Return true if the given string is an IP(v4|v6) address. ++ */ ++static bool isip(const char *domain) ++{ ++ struct in_addr addr; ++#ifdef ENABLE_IPV6 ++ struct in6_addr addr6; ++#endif ++ ++ if(Curl_inet_pton(AF_INET, domain, &addr) ++#ifdef ENABLE_IPV6 ++ || Curl_inet_pton(AF_INET6, domain, &addr6) ++#endif ++ ) { ++ /* domain name given as IP address */ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + /**************************************************************************** + * + * Curl_cookie_add() + * + * Add a single cookie line to the cookie keeping object. +@@ -437,28 +460,31 @@ Curl_cookie_add(struct SessionHandle *data, + badcookie = TRUE; /* out of memory bad */ + break; + } + } + else if(Curl_raw_equal("domain", name)) { ++ bool is_ip; ++ + /* Now, we make sure that our host is within the given domain, + or the given domain is not valid and thus cannot be set. */ + + if('.' == whatptr[0]) + whatptr++; /* ignore preceding dot */ + +- if(!domain || tailmatch(whatptr, domain)) { +- const char *tailptr=whatptr; +- if(tailptr[0] == '.') +- tailptr++; +- strstore(&co->domain, tailptr); /* don't prefix w/dots +- internally */ ++ is_ip = isip(domain ? domain : whatptr); ++ ++ if(!domain ++ || (is_ip && !strcmp(whatptr, domain)) ++ || (!is_ip && tailmatch(whatptr, domain))) { ++ strstore(&co->domain, whatptr); + if(!co->domain) { + badcookie = TRUE; + break; + } +- co->tailmatch=TRUE; /* we always do that if the domain name was +- given */ ++ if(!is_ip) ++ co->tailmatch=TRUE; /* we always do that if the domain name was ++ given */ + } + else { + /* we did not get a tailmatch and then the attempted set domain + is not a domain to which the current host belongs. Mark as + bad. */ +@@ -966,17 +992,21 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + struct Cookie *newco; + struct Cookie *co; + time_t now = time(NULL); + struct Cookie *mainco=NULL; + size_t matches = 0; ++ bool is_ip; + + if(!c || !c->cookies) + return NULL; /* no cookie struct or no cookies in the struct */ + + /* at first, remove expired cookies */ + remove_expired(c); + ++ /* check if host is an IP(v4|v6) address */ ++ is_ip = isip(host); ++ + co = c->cookies; + + while(co) { + /* only process this cookie if it is not expired or had no expire + date AND that if the cookie requires we're secure we must only +@@ -984,12 +1014,12 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + if((!co->expires || (co->expires > now)) && + (co->secure?secure:TRUE)) { + + /* now check if the domain is correct */ + if(!co->domain || +- (co->tailmatch && tailmatch(co->domain, host)) || +- (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) { ++ (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || ++ ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) { + /* the right part of the host matches the domain stuff in the + cookie data */ + + /* now check the left part of the path with the cookies path + requirement */ +diff --git a/tests/data/test1105 b/tests/data/test1105 +index 25f194c..9564775 100644 +--- a/tests/data/test1105 ++++ b/tests/data/test1105 +@@ -57,10 +57,9 @@ userid=myname&password=mypassword + # Netscape HTTP Cookie File + # http://curl.haxx.se/docs/http-cookies.html + # This file was generated by libcurl! Edit at your own risk. + + 127.0.0.1 FALSE /we/want/ FALSE 0 foobar name +-.127.0.0.1 TRUE "/silly/" FALSE 0 mismatch this +-.0.0.1 TRUE / FALSE 0 partmatch present ++127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this + </file> + </verify> + </testcase> +diff --git a/tests/data/test31 b/tests/data/test31 +index 38af83b..dfcac04 100644 +--- a/tests/data/test31 ++++ b/tests/data/test31 +@@ -49,11 +49,12 @@ Set-Cookie: nodomainnovalue + Set-Cookie: nodomain=value; expires=Fri Feb 2 11:56:27 GMT 2035 + Set-Cookie: novalue; domain=reallysilly + Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030 + Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030 + Set-Cookie: magic=yessir; path=/silly/; HttpOnly +-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad; ++Set-Cookie: blexp=yesyes; domain=127.0.0.1; domain=127.0.0.1; expiry=totally bad; ++Set-Cookie: partialip=nono; domain=.0.0.1; + + boo + </data> + </reply> + +@@ -93,36 +94,36 @@ Accept: */* + <file name="log/jar31.txt" mode="text"> + # Netscape HTTP Cookie File + # http://curl.haxx.se/docs/http-cookies.html + # This file was generated by libcurl! Edit at your own risk. + +-.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this +-.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2 +-.127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1 +-.127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2 +-.127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3 +-.127.0.0.1 TRUE /secure4/ TRUE 0 sec4value secure4 +-.127.0.0.1 TRUE /secure5/ TRUE 0 sec5value secure5 +-.127.0.0.1 TRUE /secure6/ TRUE 0 sec6value secure6 +-.127.0.0.1 TRUE /secure7/ TRUE 0 sec7value secure7 +-.127.0.0.1 TRUE /secure8/ TRUE 0 sec8value secure8 +-.127.0.0.1 TRUE /secure9/ TRUE 0 secure very1 +-#HttpOnly_.127.0.0.1 TRUE /p1/ FALSE 0 httpo1 value1 +-#HttpOnly_.127.0.0.1 TRUE /p2/ FALSE 0 httpo2 value2 +-#HttpOnly_.127.0.0.1 TRUE /p3/ FALSE 0 httpo3 value3 +-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httpo4 value4 +-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httponly myvalue1 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec myvalue2 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec2 myvalue3 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec3 myvalue4 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec4 myvalue5 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec5 myvalue6 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec6 myvalue7 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec7 myvalue8 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec8 myvalue9 +-.127.0.0.1 TRUE / FALSE 0 partmatch present ++127.0.0.1 FALSE /silly/ FALSE 0 ismatch this ++127.0.0.1 FALSE /overwrite FALSE 0 overwrite this2 ++127.0.0.1 FALSE /secure1/ TRUE 0 sec1value secure1 ++127.0.0.1 FALSE /secure2/ TRUE 0 sec2value secure2 ++127.0.0.1 FALSE /secure3/ TRUE 0 sec3value secure3 ++127.0.0.1 FALSE /secure4/ TRUE 0 sec4value secure4 ++127.0.0.1 FALSE /secure5/ TRUE 0 sec5value secure5 ++127.0.0.1 FALSE /secure6/ TRUE 0 sec6value secure6 ++127.0.0.1 FALSE /secure7/ TRUE 0 sec7value secure7 ++127.0.0.1 FALSE /secure8/ TRUE 0 sec8value secure8 ++127.0.0.1 FALSE /secure9/ TRUE 0 secure very1 ++#HttpOnly_127.0.0.1 FALSE /p1/ FALSE 0 httpo1 value1 ++#HttpOnly_127.0.0.1 FALSE /p2/ FALSE 0 httpo2 value2 ++#HttpOnly_127.0.0.1 FALSE /p3/ FALSE 0 httpo3 value3 ++#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httpo4 value4 ++#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httponly myvalue1 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec myvalue2 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec2 myvalue3 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec3 myvalue4 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec4 myvalue5 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec5 myvalue6 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec6 myvalue7 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec7 myvalue8 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec8 myvalue9 ++127.0.0.1 FALSE / FALSE 0 partmatch present + 127.0.0.1 FALSE /we/want/ FALSE 2054030187 nodomain value + #HttpOnly_127.0.0.1 FALSE /silly/ FALSE 0 magic yessir +-.0.0.1 TRUE /we/want/ FALSE 0 blexp yesyes ++127.0.0.1 FALSE /we/want/ FALSE 0 blexp yesyes + </file> + </verify> + </testcase> +diff --git a/tests/data/test8 b/tests/data/test8 +index 4d54541..030fd55 100644 +--- a/tests/data/test8 ++++ b/tests/data/test8 +@@ -40,11 +40,12 @@ Set-Cookie: mismatch=this; domain=%HOSTIP; path="/silly/"; + Set-Cookie: partmatch=present; domain=.0.0.1; path=/w; + Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey; + Set-Cookie: cookie=yes; path=/we; + Set-Cookie: cookie=perhaps; path=/we/want; + Set-Cookie: nocookie=yes; path=/WE; +-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad; ++Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad; ++Set-Cookie: partialip=nono; domain=.0.0.1; + + </file> + <precheck> + perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs ending with .0.0.1"; exit(1)}' + </precheck> +-- +2.1.0 +
meta/recipes-support/curl/curl_7.37.1.bb +1 -0
@@ -7,6 +7,7 @@ LIC_FILES_CHKSUM = "file://COPYING;beginline=7;md5=3a34942f4ae3fbf1a303160714e66 SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \ file://pkgconfig_fix.patch \ + file://CVE-2014-3613.patch \ " # curl likes to set -g0 in CFLAGS, so we stop it
Signature · 1 line
1.9.1
PATCH 3/6 curl: Security Advisory - curl - CVE-2014-3620
In reply to Armin KusterFrom: Chong Lu <[email protected]>
libcurl wrongly allows cookies to be set for Top Level Domains (TLDs), thus making them apply broader than cookies are allowed. This can allow arbitrary sites to set cookies that then would get sent to a different and unrelated site or domain.
(From OE-Core rev: ddbaade8afbc9767583728bfdc220639203d6853)
--- meta/recipes-support/curl/curl/CVE-2014-3620.patch | 69 ++++++++++++++++++++++ meta/recipes-support/curl/curl_7.37.1.bb | 1 + 2 files changed, 70 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2014-3620.patch
meta/recipes-support/curl/curl/CVE-2014-3620.patch new file +69 -0
@@ -0,0 +1,69 @@ +From fd7ae600adf23a9a1ed619165c5058bdec216e9c Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <[email protected]> +Date: Tue, 19 Aug 2014 21:11:20 +0200 +Subject: [PATCH] cookies: reject incoming cookies set for TLDs + +Test 61 was modified to verify this. + +CVE-2014-3620 + +Reported-by: Tim Ruehsen +URL: http://curl.haxx.se/docs/adv_20140910B.html + +Upstream-Status: Backport + +Signed-off-by: Chong Lu <[email protected]> +--- + lib/cookie.c | 6 ++++++ + tests/data/test61 | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 46904ac..375485f 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -461,19 +461,25 @@ Curl_cookie_add(struct SessionHandle *data, + break; + } + } + else if(Curl_raw_equal("domain", name)) { + bool is_ip; ++ const char *dotp; + + /* Now, we make sure that our host is within the given domain, + or the given domain is not valid and thus cannot be set. */ + + if('.' == whatptr[0]) + whatptr++; /* ignore preceding dot */ + + is_ip = isip(domain ? domain : whatptr); + ++ /* check for more dots */ ++ dotp = strchr(whatptr, '.'); ++ if(!dotp) ++ domain=":"; ++ + if(!domain + || (is_ip && !strcmp(whatptr, domain)) + || (!is_ip && tailmatch(whatptr, domain))) { + strstore(&co->domain, whatptr); + if(!co->domain) { +diff --git a/tests/data/test61 b/tests/data/test61 +index d2de279..e6dbbb9 100644 +--- a/tests/data/test61 ++++ b/tests/data/test61 +@@ -21,10 +21,11 @@ Set-Cookie: test=yes; httponly; domain=foo.com; expires=Fri Feb 2 11:56:27 GMT 2 + SET-COOKIE: test2=yes; domain=host.foo.com; expires=Fri Feb 2 11:56:27 GMT 2035 + Set-Cookie: test3=maybe; domain=foo.com; path=/moo; secure + Set-Cookie: test4=no; domain=nope.foo.com; path=/moo; secure + Set-Cookie: test5=name; domain=anything.com; path=/ ; secure + Set-Cookie: fake=fooledyou; domain=..com; path=/; ++Set-Cookie: supercookie=fooledyou; domain=.com; path=/;^M + Content-Length: 4 + + boo + </data> + </reply> +-- +2.1.0 +
meta/recipes-support/curl/curl_7.37.1.bb +1 -0
@@ -8,6 +8,7 @@ LIC_FILES_CHKSUM = "file://COPYING;beginline=7;md5=3a34942f4ae3fbf1a303160714e66 SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \ file://pkgconfig_fix.patch \ file://CVE-2014-3613.patch \ + file://CVE-2014-3620.patch \ " # curl likes to set -g0 in CFLAGS, so we stop it
Signature · 1 line
1.9.1
PATCH 4/6 nss: CVE-2014-1568
In reply to Armin KusterFrom: Chong Lu <[email protected]>
the patch comes from:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-1568
https://bugzilla.mozilla.org/show_bug.cgi?id=1064636
nss ng log:
=====
changeset: 11252:ad411fb64046 user: Kai Engert <[email protected]> date: Tue Sep 23 19:28:34 2014 +0200 summary: Fix bug 1064636, patch part 2, r=rrelyea ===== changeset: 11253:4e90910ad2f9 user: Kai Engert <[email protected]> date: Tue Sep 23 19:28:45 2014 +0200 summary: Fix bug 1064636, patch part 3, r=rrelyea ===== changeset: 11254:fb7208e91ae8 user: Kai Engert <[email protected]> date: Tue Sep 23 19:28:52 2014 +0200 summary: Fix bug 1064636, patch part 1, r=rrelyea ===== changeset: 11255:8dd6c6ac977d user: Kai Engert <[email protected]> date: Tue Sep 23 19:39:40 2014 +0200 summary: Bug 1064636, follow up commit to fix Windows build bustage
--- .../nss/files/nss-CVE-2014-1568.patch | 670 +++++++++++++++++++++ meta/recipes-support/nss/nss.inc | 1 + 2 files changed, 671 insertions(+) create mode 100644 meta/recipes-support/nss/files/nss-CVE-2014-1568.patch
meta/recipes-support/nss/files/nss-CVE-2014-1568.patch new file +670 -0
@@ -0,0 +1,670 @@ +nss: CVE-2014-1568 + +the patch comes from: +http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-1568 +https://bugzilla.mozilla.org/show_bug.cgi?id=1064636 +nss ng log: +===== +changeset: 11252:ad411fb64046 +user: Kai Engert <[email protected]> +date: Tue Sep 23 19:28:34 2014 +0200 +summary: Fix bug 1064636, patch part 2, r=rrelyea +===== +changeset: 11253:4e90910ad2f9 +user: Kai Engert <[email protected]> +date: Tue Sep 23 19:28:45 2014 +0200 +summary: Fix bug 1064636, patch part 3, r=rrelyea +===== +changeset: 11254:fb7208e91ae8 +user: Kai Engert <[email protected]> +date: Tue Sep 23 19:28:52 2014 +0200 +summary: Fix bug 1064636, patch part 1, r=rrelyea +===== +changeset: 11255:8dd6c6ac977d +user: Kai Engert <[email protected]> +date: Tue Sep 23 19:39:40 2014 +0200 +summary: Bug 1064636, follow up commit to fix Windows build bustage + +Upstream-Status: Backport +Signed-off-by: Li Wang <[email protected]> +--- + nss/lib/cryptohi/secvfy.c | 202 +++++++++++++++++++++++++++----------------- + nss/lib/softoken/pkcs11c.c | 69 +++++++-------- + nss/lib/util/manifest.mn | 2 + + nss/lib/util/nssutil.def | 6 ++ + nss/lib/util/pkcs1sig.c | 169 ++++++++++++++++++++++++++++++++++++ + nss/lib/util/pkcs1sig.h | 30 +++++++ + 6 files changed, 360 insertions(+), 118 deletions(-) + create mode 100644 nss/lib/util/pkcs1sig.c + create mode 100644 nss/lib/util/pkcs1sig.h + +diff --git a/nss/lib/cryptohi/secvfy.c b/nss/lib/cryptohi/secvfy.c +index c1ac39b..0a20672 100644 +--- a/nss/lib/cryptohi/secvfy.c ++++ b/nss/lib/cryptohi/secvfy.c +@@ -12,78 +12,111 @@ + #include "secasn1.h" + #include "secoid.h" + #include "pk11func.h" ++#include "pkcs1sig.h" + #include "secdig.h" + #include "secerr.h" + #include "keyi.h" + + /* +-** Decrypt signature block using public key +-** Store the hash algorithm oid tag in *tagp +-** Store the digest in the digest buffer +-** Store the digest length in *digestlen ++** Recover the DigestInfo from an RSA PKCS#1 signature. ++** ++** If givenDigestAlg != SEC_OID_UNKNOWN, copy givenDigestAlg to digestAlgOut. ++** Otherwise, parse the DigestInfo structure and store the decoded digest ++** algorithm into digestAlgOut. ++** ++** Store the encoded DigestInfo into digestInfo. ++** Store the DigestInfo length into digestInfoLen. ++** ++** This function does *not* verify that the AlgorithmIdentifier in the ++** DigestInfo identifies givenDigestAlg or that the DigestInfo is encoded ++** correctly; verifyPKCS1DigestInfo does that. ++** + ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION + */ + static SECStatus +-DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, +- unsigned int *digestlen, unsigned int maxdigestlen, +- SECKEYPublicKey *key, const SECItem *sig, char *wincx) ++recoverPKCS1DigestInfo(SECOidTag givenDigestAlg, ++ /*out*/ SECOidTag* digestAlgOut, ++ /*out*/ unsigned char** digestInfo, ++ /*out*/ unsigned int* digestInfoLen, ++ SECKEYPublicKey* key, ++ const SECItem* sig, void* wincx) + { +- SGNDigestInfo *di = NULL; +- unsigned char *buf = NULL; +- SECStatus rv; +- SECOidTag tag; +- SECItem it; +- +- if (key == NULL) goto loser; +- ++ SGNDigestInfo* di = NULL; ++ SECItem it; ++ PRBool rv = SECSuccess; ++ ++ PORT_Assert(digestAlgOut); ++ PORT_Assert(digestInfo); ++ PORT_Assert(digestInfoLen); ++ PORT_Assert(key); ++ PORT_Assert(key->keyType == rsaKey); ++ PORT_Assert(sig); ++ ++ it.data = NULL; + it.len = SECKEY_PublicKeyStrength(key); +- if (!it.len) goto loser; +- it.data = buf = (unsigned char *)PORT_Alloc(it.len); +- if (!buf) goto loser; ++ if (it.len != 0) { ++ it.data = (unsigned char *)PORT_Alloc(it.len); ++ } ++ if (it.len == 0 || it.data == NULL ) { ++ rv = SECFailure; ++ } + +- /* decrypt the block */ +- rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx); +- if (rv != SECSuccess) goto loser; ++ if (rv == SECSuccess) { ++ /* decrypt the block */ ++ rv = PK11_VerifyRecover(key, sig, &it, wincx); ++ } + +- di = SGN_DecodeDigestInfo(&it); +- if (di == NULL) goto sigloser; ++ if (rv == SECSuccess) { ++ if (givenDigestAlg != SEC_OID_UNKNOWN) { ++ /* We don't need to parse the DigestInfo if the caller gave us the ++ * digest algorithm to use. Later verifyPKCS1DigestInfo will verify ++ * that the DigestInfo identifies the given digest algorithm and ++ * that the DigestInfo is encoded absolutely correctly. ++ */ ++ *digestInfoLen = it.len; ++ *digestInfo = (unsigned char*)it.data; ++ *digestAlgOut = givenDigestAlg; ++ return SECSuccess; ++ } ++ } + +- /* +- ** Finally we have the digest info; now we can extract the algorithm +- ** ID and the signature block +- */ +- tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm); +- /* Check that tag is an appropriate algorithm */ +- if (tag == SEC_OID_UNKNOWN) { +- goto sigloser; +- } +- /* make sure the "parameters" are not too bogus. */ +- if (di->digestAlgorithm.parameters.len > 2) { +- goto sigloser; +- } +- if (di->digest.len > maxdigestlen) { +- PORT_SetError(SEC_ERROR_OUTPUT_LEN); +- goto loser; ++ if (rv == SECSuccess) { ++ /* The caller didn't specify a digest algorithm to use, so choose the ++ * digest algorithm by parsing the AlgorithmIdentifier within the ++ * DigestInfo. ++ */ ++ di = SGN_DecodeDigestInfo(&it); ++ if (!di) { ++ rv = SECFailure; ++ } + } +- PORT_Memcpy(digest, di->digest.data, di->digest.len); +- *tagp = tag; +- *digestlen = di->digest.len; +- goto done; + +- sigloser: +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ if (rv == SECSuccess) { ++ *digestAlgOut = SECOID_GetAlgorithmTag(&di->digestAlgorithm); ++ if (*digestAlgOut == SEC_OID_UNKNOWN) { ++ rv = SECFailure; ++ } ++ } + +- loser: +- rv = SECFailure; ++ if (di) { ++ SGN_DestroyDigestInfo(di); ++ } ++ ++ if (rv == SECSuccess) { ++ *digestInfoLen = it.len; ++ *digestInfo = (unsigned char*)it.data; ++ } else { ++ if (it.data) { ++ PORT_Free(it.data); ++ } ++ *digestInfo = NULL; ++ *digestInfoLen = 0; ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ } + +- done: +- if (di != NULL) SGN_DestroyDigestInfo(di); +- if (buf != NULL) PORT_Free(buf); +- + return rv; + } + +- + struct VFYContextStr { + SECOidTag hashAlg; /* the hash algorithm */ + SECKEYPublicKey *key; +@@ -99,14 +132,14 @@ struct VFYContextStr { + union { + unsigned char buffer[1]; + +- /* the digest in the decrypted RSA signature */ +- unsigned char rsadigest[HASH_LENGTH_MAX]; + /* the full DSA signature... 40 bytes */ + unsigned char dsasig[DSA_MAX_SIGNATURE_LEN]; + /* the full ECDSA signature */ + unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; + } u; +- unsigned int rsadigestlen; ++ unsigned int pkcs1RSADigestInfoLen; ++ /* the encoded DigestInfo from a RSA PKCS#1 signature */ ++ unsigned char *pkcs1RSADigestInfo; + void * wincx; + void *hashcx; + const SECHashObject *hashobj; +@@ -117,6 +150,17 @@ struct VFYContextStr { + * VFY_EndWithSignature call. */ + }; + ++static SECStatus ++verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest) ++{ ++ SECItem pkcs1DigestInfo; ++ pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo; ++ pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen; ++ return _SGN_VerifyPKCS1DigestInfo( ++ cx->hashAlg, digest, &pkcs1DigestInfo, ++ PR_TRUE /*XXX: unsafeAllowMissingParameters*/); ++} ++ + /* + * decode the ECDSA or DSA signature from it's DER wrapping. + * The unwrapped/raw signature is placed in the buffer pointed +@@ -376,16 +420,16 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, + cx->encAlg = encAlg; + cx->hashAlg = hashAlg; + cx->key = SECKEY_CopyPublicKey(key); ++ cx->pkcs1RSADigestInfo = NULL; + rv = SECSuccess; + if (sig) { + switch (type) { + case rsaKey: +- rv = DecryptSigBlock(&cx->hashAlg, cx->u.buffer, &cx->rsadigestlen, +- HASH_LENGTH_MAX, cx->key, sig, (char*)wincx); +- if (cx->hashAlg != hashAlg && hashAlg != SEC_OID_UNKNOWN) { +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); +- rv = SECFailure; +- } ++ rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, ++ &cx->pkcs1RSADigestInfo, ++ &cx->pkcs1RSADigestInfoLen, ++ cx->key, ++ sig, wincx); + break; + case dsaKey: + case ecKey: +@@ -469,6 +513,9 @@ VFY_DestroyContext(VFYContext *cx, PRBool freeit) + if (cx->key) { + SECKEY_DestroyPublicKey(cx->key); + } ++ if (cx->pkcs1RSADigestInfo) { ++ PORT_Free(cx->pkcs1RSADigestInfo); ++ } + if (freeit) { + PORT_ZFree(cx, sizeof(VFYContext)); + } +@@ -548,21 +595,25 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) + } + break; + case rsaKey: ++ { ++ SECItem digest; ++ digest.data = final; ++ digest.len = part; + if (sig) { +- SECOidTag hashid = SEC_OID_UNKNOWN; +- rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen, +- HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx); +- if ((rv != SECSuccess) || (hashid != cx->hashAlg)) { +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ SECOidTag hashid; ++ PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN); ++ rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid, ++ &cx->pkcs1RSADigestInfo, ++ &cx->pkcs1RSADigestInfoLen, ++ cx->key, ++ sig, cx->wincx); ++ PORT_Assert(cx->hashAlg == hashid); ++ if (rv != SECSuccess) { + return SECFailure; + } + } +- if ((part != cx->rsadigestlen) || +- PORT_Memcmp(final, cx->u.buffer, part)) { +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); +- return SECFailure; +- } +- break; ++ return verifyPKCS1DigestInfo(cx, &digest); ++ } + default: + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + return SECFailure; /* shouldn't happen */ +@@ -595,12 +646,7 @@ vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key, + if (cx != NULL) { + switch (key->keyType) { + case rsaKey: +- if ((digest->len != cx->rsadigestlen) || +- PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); +- } else { +- rv = SECSuccess; +- } ++ rv = verifyPKCS1DigestInfo(cx, digest); + break; + case dsaKey: + case ecKey: +diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c +index 89b5bd8..ba6dcfa 100644 +--- a/nss/lib/softoken/pkcs11c.c ++++ b/nss/lib/softoken/pkcs11c.c +@@ -23,6 +23,7 @@ + #include "blapi.h" + #include "pkcs11.h" + #include "pkcs11i.h" ++#include "pkcs1sig.h" + #include "lowkeyi.h" + #include "secder.h" + #include "secdig.h" +@@ -2580,54 +2581,42 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, + } + + SECStatus +-RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, ++RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key, + unsigned char *sig, unsigned int sigLen, +- unsigned char *digest, unsigned int digestLen) ++ unsigned char *digestData, unsigned int digestLen) + { ++ unsigned char *pkcs1DigestInfoData; ++ SECItem pkcs1DigestInfo; ++ SECItem digest; ++ unsigned int bufferSize; ++ SECStatus rv; + +- SECItem it; +- SGNDigestInfo *di = NULL; +- SECStatus rv = SECSuccess; +- +- it.data = NULL; +- +- if (key == NULL) goto loser; +- +- it.len = nsslowkey_PublicModulusLen(key); +- if (!it.len) goto loser; ++ /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */ ++ bufferSize = key->u.rsa.modulus.len; ++ pkcs1DigestInfoData = PORT_ZAlloc(bufferSize); ++ if (!pkcs1DigestInfoData) { ++ PORT_SetError(SEC_ERROR_NO_MEMORY); ++ return SECFailure; ++ } + +- it.data = (unsigned char *) PORT_Alloc(it.len); +- if (it.data == NULL) goto loser; ++ pkcs1DigestInfo.data = pkcs1DigestInfoData; ++ pkcs1DigestInfo.len = bufferSize; + + /* decrypt the block */ +- rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen); +- if (rv != SECSuccess) goto loser; +- +- di = SGN_DecodeDigestInfo(&it); +- if (di == NULL) goto loser; +- if (di->digest.len != digestLen) goto loser; +- +- /* make sure the tag is OK */ +- if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { +- goto loser; +- } +- /* make sure the "parameters" are not too bogus. */ +- if (di->digestAlgorithm.parameters.len > 2) { +- goto loser; +- } +- /* Now check the signature */ +- if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) { +- goto done; ++ rv = RSA_CheckSignRecover(key, pkcs1DigestInfo.data, ++ &pkcs1DigestInfo.len, pkcs1DigestInfo.len, ++ sig, sigLen); ++ if (rv != SECSuccess) { ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ } else { ++ digest.data = (PRUint8*) digestData; ++ digest.len = digestLen; ++ rv = _SGN_VerifyPKCS1DigestInfo( ++ digestOid, &digest, &pkcs1DigestInfo, ++ PR_TRUE /*XXX: unsafeAllowMissingParameters*/); + } + +- loser: +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); +- rv = SECFailure; +- +- done: +- if (it.data != NULL) PORT_Free(it.data); +- if (di != NULL) SGN_DestroyDigestInfo(di); +- ++ PORT_Free(pkcs1DigestInfoData); + return rv; + } + +diff --git a/nss/lib/util/manifest.mn b/nss/lib/util/manifest.mn +index ed54a16..9ff3758 100644 +--- a/nss/lib/util/manifest.mn ++++ b/nss/lib/util/manifest.mn +@@ -22,6 +22,7 @@ EXPORTS = \ + pkcs11t.h \ + pkcs11n.h \ + pkcs11u.h \ ++ pkcs1sig.h \ + portreg.h \ + secasn1.h \ + secasn1t.h \ +@@ -58,6 +59,7 @@ CSRCS = \ + nssrwlk.c \ + nssilock.c \ + oidstring.c \ ++ pkcs1sig.c \ + portreg.c \ + secalgid.c \ + secasn1d.c \ +diff --git a/nss/lib/util/nssutil.def b/nss/lib/util/nssutil.def +index 86a0ad7..9d98df2 100644 +--- a/nss/lib/util/nssutil.def ++++ b/nss/lib/util/nssutil.def +@@ -271,3 +271,9 @@ SECITEM_ZfreeArray; + ;+ local: + ;+ *; + ;+}; ++;+NSSUTIL_3.17.1 { # NSS Utilities 3.17.1 release ++;+ global: ++_SGN_VerifyPKCS1DigestInfo; ++;+ local: ++;+ *; ++;+}; +diff --git a/nss/lib/util/pkcs1sig.c b/nss/lib/util/pkcs1sig.c +new file mode 100644 +index 0000000..03b16f5 +--- /dev/null ++++ b/nss/lib/util/pkcs1sig.c +@@ -0,0 +1,169 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#include "pkcs1sig.h" ++#include "hasht.h" ++#include "secerr.h" ++#include "secasn1t.h" ++#include "secoid.h" ++ ++typedef struct pkcs1PrefixStr pkcs1Prefix; ++struct pkcs1PrefixStr { ++ unsigned int len; ++ PRUint8 *data; ++}; ++ ++typedef struct pkcs1PrefixesStr pkcs1Prefixes; ++struct pkcs1PrefixesStr { ++ unsigned int digestLen; ++ pkcs1Prefix prefixWithParams; ++ pkcs1Prefix prefixWithoutParams; ++}; ++ ++/* The value for SGN_PKCS1_DIGESTINFO_MAX_PREFIX_LEN_EXCLUDING_OID is based on ++ * the possible prefix encodings as explained below. ++ */ ++#define MAX_PREFIX_LEN_EXCLUDING_OID 10 ++ ++static SECStatus ++encodePrefix(const SECOidData *hashOid, unsigned int digestLen, ++ pkcs1Prefix *prefix, PRBool withParams) ++{ ++ /* with params coding is: ++ * Sequence (2 bytes) { ++ * Sequence (2 bytes) { ++ * Oid (2 bytes) { ++ * Oid value (derOid->oid.len) ++ * } ++ * NULL (2 bytes) ++ * } ++ * OCTECT (2 bytes); ++ * ++ * without params coding is: ++ * Sequence (2 bytes) { ++ * Sequence (2 bytes) { ++ * Oid (2 bytes) { ++ * Oid value (derOid->oid.len) ++ * } ++ * } ++ * OCTECT (2 bytes); ++ */ ++ ++ unsigned int innerSeqLen = 2 + hashOid->oid.len; ++ unsigned int outerSeqLen = 2 + innerSeqLen + 2 + digestLen; ++ unsigned int extra = 0; ++ ++ if (withParams) { ++ innerSeqLen += 2; ++ outerSeqLen += 2; ++ extra = 2; ++ } ++ ++ if (innerSeqLen >= 128 || ++ outerSeqLen >= 128 || ++ (outerSeqLen + 2 - digestLen) > ++ (MAX_PREFIX_LEN_EXCLUDING_OID + hashOid->oid.len)) { ++ /* this is actually a library failure, It shouldn't happen */ ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ prefix->len = 6 + hashOid->oid.len + extra + 2; ++ prefix->data = PORT_Alloc(prefix->len); ++ if (!prefix->data) { ++ PORT_SetError(SEC_ERROR_NO_MEMORY); ++ return SECFailure; ++ } ++ ++ prefix->data[0] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED; ++ prefix->data[1] = outerSeqLen; ++ prefix->data[2] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED; ++ prefix->data[3] = innerSeqLen; ++ prefix->data[4] = SEC_ASN1_OBJECT_ID; ++ prefix->data[5] = hashOid->oid.len; ++ PORT_Memcpy(&prefix->data[6], hashOid->oid.data, hashOid->oid.len); ++ if (withParams) { ++ prefix->data[6 + hashOid->oid.len] = SEC_ASN1_NULL; ++ prefix->data[6 + hashOid->oid.len + 1] = 0; ++ } ++ prefix->data[6 + hashOid->oid.len + extra] = SEC_ASN1_OCTET_STRING; ++ prefix->data[6 + hashOid->oid.len + extra + 1] = digestLen; ++ ++ return SECSuccess; ++} ++ ++SECStatus ++_SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg, ++ const SECItem* digest, ++ const SECItem* dataRecoveredFromSignature, ++ PRBool unsafeAllowMissingParameters) ++{ ++ SECOidData *hashOid; ++ pkcs1Prefixes pp; ++ const pkcs1Prefix* expectedPrefix; ++ SECStatus rv, rv2, rv3; ++ ++ if (!digest || !digest->data || ++ !dataRecoveredFromSignature || !dataRecoveredFromSignature->data) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ hashOid = SECOID_FindOIDByTag(digestAlg); ++ if (hashOid == NULL) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ pp.digestLen = digest->len; ++ pp.prefixWithParams.data = NULL; ++ pp.prefixWithoutParams.data = NULL; ++ ++ rv2 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithParams, PR_TRUE); ++ rv3 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithoutParams, PR_FALSE); ++ ++ rv = SECSuccess; ++ if (rv2 != SECSuccess || rv3 != SECSuccess) { ++ rv = SECFailure; ++ } ++ ++ if (rv == SECSuccess) { ++ /* We don't attempt to avoid timing attacks on these comparisons because ++ * signature verification is a public key operation, not a private key ++ * operation. ++ */ ++ ++ if (dataRecoveredFromSignature->len == ++ pp.prefixWithParams.len + pp.digestLen) { ++ expectedPrefix = &pp.prefixWithParams; ++ } else if (unsafeAllowMissingParameters && ++ dataRecoveredFromSignature->len == ++ pp.prefixWithoutParams.len + pp.digestLen) { ++ expectedPrefix = &pp.prefixWithoutParams; ++ } else { ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ rv = SECFailure; ++ } ++ } ++ ++ if (rv == SECSuccess) { ++ if (memcmp(dataRecoveredFromSignature->data, expectedPrefix->data, ++ expectedPrefix->len) || ++ memcmp(dataRecoveredFromSignature->data + expectedPrefix->len, ++ digest->data, digest->len)) { ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); ++ rv = SECFailure; ++ } ++ } ++ ++ if (pp.prefixWithParams.data) { ++ PORT_Free(pp.prefixWithParams.data); ++ } ++ if (pp.prefixWithoutParams.data) { ++ PORT_Free(pp.prefixWithoutParams.data); ++ } ++ ++ return rv; ++} +diff --git a/nss/lib/util/pkcs1sig.h b/nss/lib/util/pkcs1sig.h +new file mode 100644 +index 0000000..7c52b15 +--- /dev/null ++++ b/nss/lib/util/pkcs1sig.h +@@ -0,0 +1,30 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#ifndef _PKCS1SIG_H_ ++#define _PKCS1SIG_H_ ++ ++#include "hasht.h" ++#include "seccomon.h" ++#include "secoidt.h" ++ ++/* SGN_VerifyPKCS1DigestInfo verifies that the length of the digest is correct ++ * for the given algorithm, then verifies that the recovered data from the ++ * PKCS#1 signature is a properly-formatted DigestInfo that identifies the ++ * given digest algorithm, then verifies that the digest in the DigestInfo ++ * matches the given digest. ++ * ++ * dataRecoveredFromSignature must be the result of calling PK11_VerifyRecover ++ * or equivalent. ++ * ++ * If unsafeAllowMissingParameters is true (not recommended), then a DigestInfo ++ * without the mandatory ASN.1 NULL parameter will also be accepted. ++ */ ++SECStatus _SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg, ++ const SECItem* digest, ++ const SECItem* dataRecoveredFromSignature, ++ PRBool unsafeAllowMissingParameters); ++ ++#endif /* _PKCS1SIG_H_ */ +-- +1.7.9.5
meta/recipes-support/nss/nss.inc +1 -0
@@ -23,6 +23,7 @@ SRC_URI = "\ file://nss-3.15.1-fix-CVE-2013-1739.patch \ file://nss-CVE-2013-5606.patch \ file://nss-CVE-2014-1544.patch \ + file://nss-CVE-2014-1568.patch \ " SRC_URI_append = "\ file://nss.pc.in \
Signature · 1 line
1.9.1
PATCH 5/6 tzcode: update to 2014j
In reply to Armin Kuster(From OE-Core rev: 2f8940e8b2a0537f131a6d5410e85bba07a8c116)
--- meta/recipes-extended/tzcode/tzcode-native_2014j.bb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 meta/recipes-extended/tzcode/tzcode-native_2014j.bb
meta/recipes-extended/tzcode/tzcode-native_2014j.bb new file +10 -0
@@ -0,0 +1,10 @@ +# note that we allow for us to use data later than our code version +# +SRC_URI =" ftp://ftp.iana.org/tz/releases/tzcode${PV}.tar.gz;name=tzcode \ + ftp://ftp.iana.org/tz/releases/tzdata2014j.tar.gz;name=tzdata" + +SRC_URI[tzcode.md5sum] = "970119e9765bc5a9320368851c91ecb6" +SRC_URI[tzcode.sha256sum] = "7fd46125464856309fc81fe85a67a61de862b8ab884ce8ca82051f5fa308ede2" +SRC_URI[tzdata.md5sum] = "2d7ea9c309f0d4e162e426e568290ca3" +SRC_URI[tzdata.sha256sum] = "a2d870320694d40535df822ac8074dc629a90e92abafa5d3373314f78ddc0e0d" +require tzcode-native.inc
Signature · 1 line
1.9.1
PATCH 6/6 tzdata: update to 2014j
In reply to Armin Kuster(From OE-Core rev: 3ab9dfb703835fee21fd73c4e5cbad1c34c6a163)
--- meta/recipes-extended/tzdata/tzdata_2014j.bb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 meta/recipes-extended/tzdata/tzdata_2014j.bb
meta/recipes-extended/tzdata/tzdata_2014j.bb new file +6 -0
@@ -0,0 +1,6 @@ +SRC_URI = "ftp://ftp.iana.org/tz/releases/tzdata${PV}.tar.gz;name=tzdata" + +SRC_URI[tzdata.md5sum] = "2d7ea9c309f0d4e162e426e568290ca3" +SRC_URI[tzdata.sha256sum] = "a2d870320694d40535df822ac8074dc629a90e92abafa5d3373314f78ddc0e0d" + +require tzdata.inc
Signature · 1 line
1.9.1
Re: [PATCH 1/6] subversion: Security Advisory - subversion - CVE-2014-3528
In reply to Armin KusterThere's subversion 1.8.10 in master branch that has included the CVE fixes.
Would you like to backport 1.8.10 from master? Or just patch 1.8.9 to fix this CVE?
Thanks
Wenzong
Quoted 83 lines · Armin Kuster
From: Yue Tao <[email protected]>
Apache Subversion 1.0.0 through 1.7.x before 1.7.17 and 1.8.x before 1.8.10 uses an MD5 hash of the URL and authentication realm to store cached credentials, which makes it easier for remote servers to obtain the credentials via a crafted authentication realm.
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3528
(From OE-Core rev:
e0dc0432b13f38d16f642bdadf8ebc78b7a74806)Signed-off-by Yue Tao <[email protected]>Signed-off-by Jackie Huang <[email protected]>Signed-off-by Ross Burton <[email protected]>Signed-off-by Richard Purdie <[email protected]>Signed-off-by Armin Kuster <[email protected]>--- .../subversion/subversion-CVE-2014-3528.patch | 29 ++++++++++++++++++++++ .../subversion/subversion_1.6.15.bb | 1 + .../subversion/subversion_1.8.9.bb | 1 + 3 files changed, 31 insertions(+)create mode 100644
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchmeta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +29
-0@@ -0,0 +1,29 @@ +Upstream-Status: Backport + +Signed-off-by: Yue Tao <[email protected]> + +diff --git a/subversion/libsvn_subr/config_auth.c.old b/subversion/libsvn_subr/config_auth.c +index ff50270..c511d04 100644 +--- a/subversion/libsvn_subr/config_auth.c.old ++++ b/subversion/libsvn_subr/config_auth.c +@@ -85,6 +85,7 @@ svn_config_read_auth_data(apr_hash_t **hash, + if (kind == svn_node_file) + { + svn_stream_t *stream; ++ svn_string_t *stored_realm; + + SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool), + _("Unable to open auth file for reading")); +@@ -95,6 +96,12 @@ svn_config_read_auth_data(apr_hash_t **hash, + apr_psprintf(pool, _("Error parsing '%s'"), + svn_path_local_style(auth_path, pool))); + ++ stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY, ++ APR_HASH_KEY_STRING); ++ ++ if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0) ++ *hash = NULL; /* Hash collision, or somebody tampering with storage */ ++ + SVN_ERR(svn_stream_close(stream)); + } +meta/recipes-devtools/subversion/subversion_1.6.15.bb +1
-0@@ -19,6 +19,7 @@ SRC_URI = "http://subversion.tigris.org/downloads/${BPN}-${PV}.tar.bz2 \ file://subversion-CVE-2013-1847-CVE-2013-1846.patch \ file://subversion-CVE-2013-4277.patch \ file://subversion-CVE-2014-3522.patch \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "113fca1d9e4aa389d7dc2b210010fa69"meta/recipes-devtools/subversion/subversion_1.8.9.bb +1
-0@@ -13,6 +13,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ file://subversion-CVE-2014-3522.patch;striplevel=0 \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "bd495517a760ddd764ce449a891971db" SRC_URI[sha256sum] = "45d708a5c3ffbef4b2a1044c4716a053e680763743d1f7ba99d0369f6da49e33"
Re: [PATCH 1/6] subversion: Security Advisory - subversion - CVE-2014-3528
Wenzong,
I wanted to just patch 1.8.9 for dizzy since 1.8.10 included more than just security fixes. Looks like my subject should have included [dizzy] even though the cover letter did. I will have to be more careful next time.
thanks,
Armin
Quoted 109 lines · wenzong fan
There's subversion 1.8.10 in master branch that has included the CVE fixes.
Would you like to backport 1.8.10 from master? Or just patch 1.8.9 to fix this CVE?
Thanks
WenzongQuoted 100 lines · Armin Kuster
From: Yue Tao <[email protected]>
Apache Subversion 1.0.0 through 1.7.x before 1.7.17 and 1.8.x before 1.8.10 uses an MD5 hash of the URL and authentication realm to store cached credentials, which makes it easier for remote servers to obtain the credentials via a crafted authentication realm.
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3528
(From OE-Core rev:
e0dc0432b13f38d16f642bdadf8ebc78b7a74806)Signed-off-by Yue Tao <[email protected]>Signed-off-by Jackie Huang <[email protected]>Signed-off-by Ross Burton <[email protected]>Signed-off-by Richard Purdie <[email protected]>Signed-off-by Armin Kuster <[email protected]>--- .../subversion/subversion-CVE-2014-3528.patch | 29 ++++++++++++++++++++++ .../subversion/subversion_1.6.15.bb | 1 + .../subversion/subversion_1.8.9.bb | 1 + 3 files changed, 31 insertions(+)create mode 100644
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchdiff --git
a/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchb/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchnew file mode 100644
index 0000000..23e738e
---/dev/null
+++b/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchmeta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +5
-0@@ -0,0 +1,29 @@ +Upstream-Status: Backport + +Signed-off-by: Yue Tao <[email protected]> + +diff --git a/subversion/libsvn_subr/config_auth.c.old
b/subversion/libsvn_subr/config_auth.cmeta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +10
-0+index ff50270..c511d04 100644 +--- a/subversion/libsvn_subr/config_auth.c.old ++++ b/subversion/libsvn_subr/config_auth.c +@@ -85,6 +85,7 @@ svn_config_read_auth_data(apr_hash_t **hash, + if (kind == svn_node_file) + { + svn_stream_t *stream; ++ svn_string_t *stored_realm; + + SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool,pool),
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +9
-0+ _("Unable to open auth file for reading")); +@@ -95,6 +96,12 @@ svn_config_read_auth_data(apr_hash_t **hash, + apr_psprintf(pool, _("Error parsing '%s'"), + svn_path_local_style(auth_path, pool))); + ++ stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY, ++ APR_HASH_KEY_STRING); ++ ++ if (!stored_realm || strcmp(stored_realm->data, realmstring)!= 0)
++ *hash = NULL; /* Hash collision, or somebody tampering with
storage */
++meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +3
-0+ SVN_ERR(svn_stream_close(stream)); + } +meta/recipes-devtools/subversion/subversion_1.6.15.bb +1
-0@@ -19,6 +19,7 @@ SRC_URI = "http://subversion.tigris.org/downloads/${BPN}-${PV}.tar.bz2 \ file://subversion-CVE-2013-1847-CVE-2013-1846.patch \ file://subversion-CVE-2013-4277.patch \ file://subversion-CVE-2014-3522.patch \ + file://subversion-CVE-2014-3528.patch \ "SRC_URI[md5sum] = "
113fca1d9e4aa389d7dc2b210010fa69"meta/recipes-devtools/subversion/subversion_1.8.9.bb +1
-0@@ -13,6 +13,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ file://subversion-CVE-2014-3522.patch;striplevel=0 \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "bd495517a760ddd764ce449a891971db"SRC_URI[sha256sum] =
"45d708a5c3ffbef4b2a1044c4716a053e680763743d1f7ba99d0369f6da49e33"
Re: [PATCH 1/6] subversion: Security Advisory - subversion - CVE-2014-3528
Quoted 7 lines · On 11/19/2014 02:07 PM, akuster808 wrote:
Wenzong,
I wanted to just patch 1.8.9 for dizzy since 1.8.10 included more than
just security fixes. Looks like my subject should have included
[dizzy] even though the cover letter did. I will have to be more careful next time.
You have clear cover page 'Dizzy next':)
Since I updated serf on master, so I wonder how the subversion related CVEes will be processed on Dizzy.
Thanks for the clarification.
Wenzong
Quoted 120 lines
thanks,
ArminQuoted 114 lines · wenzong fan
There's subversion 1.8.10 in master branch that has included the CVE fixes.
Would you like to backport 1.8.10 from master? Or just patch 1.8.9 to fix this CVE?
Thanks
WenzongQuoted 104 lines · Armin Kuster
From: Yue Tao <[email protected]>
Apache Subversion 1.0.0 through 1.7.x before 1.7.17 and 1.8.x before 1.8.10 uses an MD5 hash of the URL and authentication realm to store cached credentials, which makes it easier for remote servers to obtain the credentials via a crafted authentication realm.
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3528
(From OE-Core rev:
e0dc0432b13f38d16f642bdadf8ebc78b7a74806)Signed-off-by Yue Tao <[email protected]>Signed-off-by Jackie Huang <[email protected]>Signed-off-by Ross Burton <[email protected]>Signed-off-by Richard Purdie <[email protected]>Signed-off-by Armin Kuster <[email protected]>--- .../subversion/subversion-CVE-2014-3528.patch | 29 ++++++++++++++++++++++ .../subversion/subversion_1.6.15.bb | 1 + .../subversion/subversion_1.8.9.bb | 1 + 3 files changed, 31 insertions(+)create mode 100644
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchdiff --git
a/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch
b/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchnew file mode 100644
index 0000000..23e738e
---/dev/null
+++b/meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patchmeta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +5
-0@@ -0,0 +1,29 @@ +Upstream-Status: Backport + +Signed-off-by: Yue Tao <[email protected]> + +diff --git a/subversion/libsvn_subr/config_auth.c.old
b/subversion/libsvn_subr/config_auth.cmeta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +10
-0+index ff50270..c511d04 100644 +--- a/subversion/libsvn_subr/config_auth.c.old ++++ b/subversion/libsvn_subr/config_auth.c +@@ -85,6 +85,7 @@ svn_config_read_auth_data(apr_hash_t **hash, + if (kind == svn_node_file) + { + svn_stream_t *stream; ++ svn_string_t *stored_realm; + + SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool,pool),
meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +9
-0+ _("Unable to open auth file for reading")); +@@ -95,6 +96,12 @@ svn_config_read_auth_data(apr_hash_t **hash, + apr_psprintf(pool, _("Error parsing '%s'"), + svn_path_local_style(auth_path, pool))); + ++ stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY, ++ APR_HASH_KEY_STRING); ++ ++ if (!stored_realm || strcmp(stored_realm->data, realmstring)!= 0)
++ *hash = NULL; /* Hash collision, or somebody tampering with
storage */
++meta/recipes-devtools/subversion/subversion/subversion-CVE-2014-3528.patch new file +3
-0+ SVN_ERR(svn_stream_close(stream)); + } +meta/recipes-devtools/subversion/subversion_1.6.15.bb +1
-0@@ -19,6 +19,7 @@ SRC_URI = "http://subversion.tigris.org/downloads/${BPN}-${PV}.tar.bz2 \ file://subversion-CVE-2013-1847-CVE-2013-1846.patch \ file://subversion-CVE-2013-4277.patch \ file://subversion-CVE-2014-3522.patch \ + file://subversion-CVE-2014-3528.patch \ "SRC_URI[md5sum] = "
113fca1d9e4aa389d7dc2b210010fa69"meta/recipes-devtools/subversion/subversion_1.8.9.bb +1
-0@@ -13,6 +13,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ file://subversion-CVE-2014-3522.patch;striplevel=0 \ + file://subversion-CVE-2014-3528.patch \ " SRC_URI[md5sum] = "bd495517a760ddd764ce449a891971db"SRC_URI[sha256sum] =
"45d708a5c3ffbef4b2a1044c4716a053e680763743d1f7ba99d0369f6da49e33"