summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTudor Florea <tudor.florea@enea.com>2015-07-06 22:18:22 (GMT)
committerTudor Florea <tudor.florea@enea.com>2015-07-06 22:18:22 (GMT)
commit35272ed55c848a63c2468b7ea1f0ddce64b4bd73 (patch)
treead3ee02e085215806e5460a83b8fc67f3b3c928c
parentd3f677a56013b1706854b016cde4dd4c4bc281fd (diff)
downloadpoky-35272ed55c848a63c2468b7ea1f0ddce64b4bd73.tar.gz
curl: Security Advisory - curl - CVE-2014-3613
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) (From OE-Core rev: dbbda31ca0a29c930f3078635ae7c5a41d933b58) Signed-off-by: Chong Lu <Chong.Lu@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Tudor Florea <tudor.florea@enea.com>
-rw-r--r--meta/recipes-support/curl/curl/CVE-2014-3613.patch269
-rw-r--r--meta/recipes-support/curl/curl_7.35.0.bb1
2 files changed, 270 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2014-3613.patch b/meta/recipes-support/curl/curl/CVE-2014-3613.patch
new file mode 100644
index 0000000..3e2fee0
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2014-3613.patch
@@ -0,0 +1,269 @@
1From 545e322cc8c383ccdfb4ad85a1634c2b719a1adf Mon Sep 17 00:00:00 2001
2From: Tim Ruehsen <tim.ruehsen@gmx.de>
3Date: Tue, 19 Aug 2014 21:01:28 +0200
4Subject: [PATCH] cookies: only use full host matches for hosts used as IP
5 address
6
7By not detecting and rejecting domain names for partial literal IP
8addresses properly when parsing received HTTP cookies, libcurl can be
9fooled to both send cookies to wrong sites and to allow arbitrary sites
10to set cookies for others.
11
12CVE-2014-3613
13
14Bug: http://curl.haxx.se/docs/adv_20140910A.html
15
16Upstream-Status: Backport
17
18Signed-off-by: Chong Lu <Chong.Lu@windriver.com>
19---
20 lib/cookie.c | 50 ++++++++++++++++++++++++++++++++++++++----------
21 tests/data/test1105 | 3 +--
22 tests/data/test31 | 55 +++++++++++++++++++++++++++--------------------------
23 tests/data/test8 | 3 ++-
24 4 files changed, 71 insertions(+), 40 deletions(-)
25
26diff --git a/lib/cookie.c b/lib/cookie.c
27index 0590643..46904ac 100644
28--- a/lib/cookie.c
29+++ b/lib/cookie.c
30@@ -93,10 +93,11 @@ Example set of cookies:
31 #include "curl_memory.h"
32 #include "share.h"
33 #include "strtoofft.h"
34 #include "rawstr.h"
35 #include "curl_memrchr.h"
36+#include "inet_pton.h"
37
38 /* The last #include file should be: */
39 #include "memdebug.h"
40
41 static void freecookie(struct Cookie *co)
42@@ -317,10 +318,32 @@ static void remove_expired(struct CookieInfo *cookies)
43 }
44 co = nx;
45 }
46 }
47
48+/*
49+ * Return true if the given string is an IP(v4|v6) address.
50+ */
51+static bool isip(const char *domain)
52+{
53+ struct in_addr addr;
54+#ifdef ENABLE_IPV6
55+ struct in6_addr addr6;
56+#endif
57+
58+ if(Curl_inet_pton(AF_INET, domain, &addr)
59+#ifdef ENABLE_IPV6
60+ || Curl_inet_pton(AF_INET6, domain, &addr6)
61+#endif
62+ ) {
63+ /* domain name given as IP address */
64+ return TRUE;
65+ }
66+
67+ return FALSE;
68+}
69+
70 /****************************************************************************
71 *
72 * Curl_cookie_add()
73 *
74 * Add a single cookie line to the cookie keeping object.
75@@ -437,28 +460,31 @@ Curl_cookie_add(struct SessionHandle *data,
76 badcookie = TRUE; /* out of memory bad */
77 break;
78 }
79 }
80 else if(Curl_raw_equal("domain", name)) {
81+ bool is_ip;
82+
83 /* Now, we make sure that our host is within the given domain,
84 or the given domain is not valid and thus cannot be set. */
85
86 if('.' == whatptr[0])
87 whatptr++; /* ignore preceding dot */
88
89- if(!domain || tailmatch(whatptr, domain)) {
90- const char *tailptr=whatptr;
91- if(tailptr[0] == '.')
92- tailptr++;
93- strstore(&co->domain, tailptr); /* don't prefix w/dots
94- internally */
95+ is_ip = isip(domain ? domain : whatptr);
96+
97+ if(!domain
98+ || (is_ip && !strcmp(whatptr, domain))
99+ || (!is_ip && tailmatch(whatptr, domain))) {
100+ strstore(&co->domain, whatptr);
101 if(!co->domain) {
102 badcookie = TRUE;
103 break;
104 }
105- co->tailmatch=TRUE; /* we always do that if the domain name was
106- given */
107+ if(!is_ip)
108+ co->tailmatch=TRUE; /* we always do that if the domain name was
109+ given */
110 }
111 else {
112 /* we did not get a tailmatch and then the attempted set domain
113 is not a domain to which the current host belongs. Mark as
114 bad. */
115@@ -966,17 +992,21 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
116 struct Cookie *newco;
117 struct Cookie *co;
118 time_t now = time(NULL);
119 struct Cookie *mainco=NULL;
120 size_t matches = 0;
121+ bool is_ip;
122
123 if(!c || !c->cookies)
124 return NULL; /* no cookie struct or no cookies in the struct */
125
126 /* at first, remove expired cookies */
127 remove_expired(c);
128
129+ /* check if host is an IP(v4|v6) address */
130+ is_ip = isip(host);
131+
132 co = c->cookies;
133
134 while(co) {
135 /* only process this cookie if it is not expired or had no expire
136 date AND that if the cookie requires we're secure we must only
137@@ -984,12 +1014,12 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
138 if((!co->expires || (co->expires > now)) &&
139 (co->secure?secure:TRUE)) {
140
141 /* now check if the domain is correct */
142 if(!co->domain ||
143- (co->tailmatch && tailmatch(co->domain, host)) ||
144- (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
145+ (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
146+ ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
147 /* the right part of the host matches the domain stuff in the
148 cookie data */
149
150 /* now check the left part of the path with the cookies path
151 requirement */
152diff --git a/tests/data/test1105 b/tests/data/test1105
153index 25f194c..9564775 100644
154--- a/tests/data/test1105
155+++ b/tests/data/test1105
156@@ -57,10 +57,9 @@ userid=myname&password=mypassword
157 # Netscape HTTP Cookie File
158 # http://curl.haxx.se/docs/http-cookies.html
159 # This file was generated by libcurl! Edit at your own risk.
160
161 127.0.0.1 FALSE /we/want/ FALSE 0 foobar name
162-.127.0.0.1 TRUE "/silly/" FALSE 0 mismatch this
163-.0.0.1 TRUE / FALSE 0 partmatch present
164+127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this
165 </file>
166 </verify>
167 </testcase>
168diff --git a/tests/data/test31 b/tests/data/test31
169index 38af83b..dfcac04 100644
170--- a/tests/data/test31
171+++ b/tests/data/test31
172@@ -49,11 +49,12 @@ Set-Cookie: nodomainnovalue
173 Set-Cookie: nodomain=value; expires=Fri Feb 2 11:56:27 GMT 2035
174 Set-Cookie: novalue; domain=reallysilly
175 Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030
176 Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030
177 Set-Cookie: magic=yessir; path=/silly/; HttpOnly
178-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
179+Set-Cookie: blexp=yesyes; domain=127.0.0.1; domain=127.0.0.1; expiry=totally bad;
180+Set-Cookie: partialip=nono; domain=.0.0.1;
181
182 boo
183 </data>
184 </reply>
185
186@@ -93,36 +94,36 @@ Accept: */*
187 <file name="log/jar31.txt" mode="text">
188 # Netscape HTTP Cookie File
189 # http://curl.haxx.se/docs/http-cookies.html
190 # This file was generated by libcurl! Edit at your own risk.
191
192-.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this
193-.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2
194-.127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1
195-.127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2
196-.127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3
197-.127.0.0.1 TRUE /secure4/ TRUE 0 sec4value secure4
198-.127.0.0.1 TRUE /secure5/ TRUE 0 sec5value secure5
199-.127.0.0.1 TRUE /secure6/ TRUE 0 sec6value secure6
200-.127.0.0.1 TRUE /secure7/ TRUE 0 sec7value secure7
201-.127.0.0.1 TRUE /secure8/ TRUE 0 sec8value secure8
202-.127.0.0.1 TRUE /secure9/ TRUE 0 secure very1
203-#HttpOnly_.127.0.0.1 TRUE /p1/ FALSE 0 httpo1 value1
204-#HttpOnly_.127.0.0.1 TRUE /p2/ FALSE 0 httpo2 value2
205-#HttpOnly_.127.0.0.1 TRUE /p3/ FALSE 0 httpo3 value3
206-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httpo4 value4
207-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httponly myvalue1
208-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec myvalue2
209-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec2 myvalue3
210-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec3 myvalue4
211-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec4 myvalue5
212-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec5 myvalue6
213-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec6 myvalue7
214-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec7 myvalue8
215-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec8 myvalue9
216-.127.0.0.1 TRUE / FALSE 0 partmatch present
217+127.0.0.1 FALSE /silly/ FALSE 0 ismatch this
218+127.0.0.1 FALSE /overwrite FALSE 0 overwrite this2
219+127.0.0.1 FALSE /secure1/ TRUE 0 sec1value secure1
220+127.0.0.1 FALSE /secure2/ TRUE 0 sec2value secure2
221+127.0.0.1 FALSE /secure3/ TRUE 0 sec3value secure3
222+127.0.0.1 FALSE /secure4/ TRUE 0 sec4value secure4
223+127.0.0.1 FALSE /secure5/ TRUE 0 sec5value secure5
224+127.0.0.1 FALSE /secure6/ TRUE 0 sec6value secure6
225+127.0.0.1 FALSE /secure7/ TRUE 0 sec7value secure7
226+127.0.0.1 FALSE /secure8/ TRUE 0 sec8value secure8
227+127.0.0.1 FALSE /secure9/ TRUE 0 secure very1
228+#HttpOnly_127.0.0.1 FALSE /p1/ FALSE 0 httpo1 value1
229+#HttpOnly_127.0.0.1 FALSE /p2/ FALSE 0 httpo2 value2
230+#HttpOnly_127.0.0.1 FALSE /p3/ FALSE 0 httpo3 value3
231+#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httpo4 value4
232+#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httponly myvalue1
233+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec myvalue2
234+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec2 myvalue3
235+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec3 myvalue4
236+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec4 myvalue5
237+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec5 myvalue6
238+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec6 myvalue7
239+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec7 myvalue8
240+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec8 myvalue9
241+127.0.0.1 FALSE / FALSE 0 partmatch present
242 127.0.0.1 FALSE /we/want/ FALSE 2054030187 nodomain value
243 #HttpOnly_127.0.0.1 FALSE /silly/ FALSE 0 magic yessir
244-.0.0.1 TRUE /we/want/ FALSE 0 blexp yesyes
245+127.0.0.1 FALSE /we/want/ FALSE 0 blexp yesyes
246 </file>
247 </verify>
248 </testcase>
249diff --git a/tests/data/test8 b/tests/data/test8
250index 4d54541..030fd55 100644
251--- a/tests/data/test8
252+++ b/tests/data/test8
253@@ -40,11 +40,12 @@ Set-Cookie: mismatch=this; domain=%HOSTIP; path="/silly/";
254 Set-Cookie: partmatch=present; domain=.0.0.1; path=/w;
255 Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey;
256 Set-Cookie: cookie=yes; path=/we;
257 Set-Cookie: cookie=perhaps; path=/we/want;
258 Set-Cookie: nocookie=yes; path=/WE;
259-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
260+Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad;
261+Set-Cookie: partialip=nono; domain=.0.0.1;
262
263 </file>
264 <precheck>
265 perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs ending with .0.0.1"; exit(1)}'
266 </precheck>
267--
2682.1.0
269
diff --git a/meta/recipes-support/curl/curl_7.35.0.bb b/meta/recipes-support/curl/curl_7.35.0.bb
index 9cc60c8..97f5ee3 100644
--- a/meta/recipes-support/curl/curl_7.35.0.bb
+++ b/meta/recipes-support/curl/curl_7.35.0.bb
@@ -11,6 +11,7 @@ DEPENDS_class-nativesdk = "nativesdk-zlib"
11 11
12SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \ 12SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \
13 file://pkgconfig_fix.patch \ 13 file://pkgconfig_fix.patch \
14 file://CVE-2014-3613.patch \
14" 15"
15 16
16# curl likes to set -g0 in CFLAGS, so we stop it 17# curl likes to set -g0 in CFLAGS, so we stop it