diff options
author | Saul Wold <sgw@linux.intel.com> | 2014-10-28 07:55:34 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-12-03 12:23:57 +0000 |
commit | bcff2a7a69f4d9e493e5a2d22ba2b3d5023138cb (patch) | |
tree | 61f1e345065073d5149d74e7713e10cb004add82 /meta | |
parent | 49329f417ec3f37e2a092081f730d66b6f4d7421 (diff) | |
download | poky-bcff2a7a69f4d9e493e5a2d22ba2b3d5023138cb.tar.gz |
curl: Ugrade to 7.38
Remove backported CVE patches
(From OE-Core rev: 257ca2054c907c9c9868ccae57c6e0d750fb1164)
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2014-3613.patch | 269 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2014-3620.patch | 69 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl_7.38.0.bb (renamed from meta/recipes-support/curl/curl_7.37.1.bb) | 8 |
3 files changed, 3 insertions, 343 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2014-3613.patch b/meta/recipes-support/curl/curl/CVE-2014-3613.patch deleted file mode 100644 index 3e2fee0413..0000000000 --- a/meta/recipes-support/curl/curl/CVE-2014-3613.patch +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | From 545e322cc8c383ccdfb4ad85a1634c2b719a1adf Mon Sep 17 00:00:00 2001 | ||
2 | From: Tim Ruehsen <tim.ruehsen@gmx.de> | ||
3 | Date: Tue, 19 Aug 2014 21:01:28 +0200 | ||
4 | Subject: [PATCH] cookies: only use full host matches for hosts used as IP | ||
5 | address | ||
6 | |||
7 | By not detecting and rejecting domain names for partial literal IP | ||
8 | addresses properly when parsing received HTTP cookies, libcurl can be | ||
9 | fooled to both send cookies to wrong sites and to allow arbitrary sites | ||
10 | to set cookies for others. | ||
11 | |||
12 | CVE-2014-3613 | ||
13 | |||
14 | Bug: http://curl.haxx.se/docs/adv_20140910A.html | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | |||
18 | Signed-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 | |||
26 | diff --git a/lib/cookie.c b/lib/cookie.c | ||
27 | index 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 */ | ||
152 | diff --git a/tests/data/test1105 b/tests/data/test1105 | ||
153 | index 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> | ||
168 | diff --git a/tests/data/test31 b/tests/data/test31 | ||
169 | index 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> | ||
249 | diff --git a/tests/data/test8 b/tests/data/test8 | ||
250 | index 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 | -- | ||
268 | 2.1.0 | ||
269 | |||
diff --git a/meta/recipes-support/curl/curl/CVE-2014-3620.patch b/meta/recipes-support/curl/curl/CVE-2014-3620.patch deleted file mode 100644 index d11f1908af..0000000000 --- a/meta/recipes-support/curl/curl/CVE-2014-3620.patch +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | From fd7ae600adf23a9a1ed619165c5058bdec216e9c Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Stenberg <daniel@haxx.se> | ||
3 | Date: Tue, 19 Aug 2014 21:11:20 +0200 | ||
4 | Subject: [PATCH] cookies: reject incoming cookies set for TLDs | ||
5 | |||
6 | Test 61 was modified to verify this. | ||
7 | |||
8 | CVE-2014-3620 | ||
9 | |||
10 | Reported-by: Tim Ruehsen | ||
11 | URL: http://curl.haxx.se/docs/adv_20140910B.html | ||
12 | |||
13 | Upstream-Status: Backport | ||
14 | |||
15 | Signed-off-by: Chong Lu <Chong.Lu@windriver.com> | ||
16 | --- | ||
17 | lib/cookie.c | 6 ++++++ | ||
18 | tests/data/test61 | 1 + | ||
19 | 2 files changed, 7 insertions(+) | ||
20 | |||
21 | diff --git a/lib/cookie.c b/lib/cookie.c | ||
22 | index 46904ac..375485f 100644 | ||
23 | --- a/lib/cookie.c | ||
24 | +++ b/lib/cookie.c | ||
25 | @@ -461,19 +461,25 @@ Curl_cookie_add(struct SessionHandle *data, | ||
26 | break; | ||
27 | } | ||
28 | } | ||
29 | else if(Curl_raw_equal("domain", name)) { | ||
30 | bool is_ip; | ||
31 | + const char *dotp; | ||
32 | |||
33 | /* Now, we make sure that our host is within the given domain, | ||
34 | or the given domain is not valid and thus cannot be set. */ | ||
35 | |||
36 | if('.' == whatptr[0]) | ||
37 | whatptr++; /* ignore preceding dot */ | ||
38 | |||
39 | is_ip = isip(domain ? domain : whatptr); | ||
40 | |||
41 | + /* check for more dots */ | ||
42 | + dotp = strchr(whatptr, '.'); | ||
43 | + if(!dotp) | ||
44 | + domain=":"; | ||
45 | + | ||
46 | if(!domain | ||
47 | || (is_ip && !strcmp(whatptr, domain)) | ||
48 | || (!is_ip && tailmatch(whatptr, domain))) { | ||
49 | strstore(&co->domain, whatptr); | ||
50 | if(!co->domain) { | ||
51 | diff --git a/tests/data/test61 b/tests/data/test61 | ||
52 | index d2de279..e6dbbb9 100644 | ||
53 | --- a/tests/data/test61 | ||
54 | +++ b/tests/data/test61 | ||
55 | @@ -21,10 +21,11 @@ Set-Cookie: test=yes; httponly; domain=foo.com; expires=Fri Feb 2 11:56:27 GMT 2 | ||
56 | SET-COOKIE: test2=yes; domain=host.foo.com; expires=Fri Feb 2 11:56:27 GMT 2035 | ||
57 | Set-Cookie: test3=maybe; domain=foo.com; path=/moo; secure | ||
58 | Set-Cookie: test4=no; domain=nope.foo.com; path=/moo; secure | ||
59 | Set-Cookie: test5=name; domain=anything.com; path=/ ; secure | ||
60 | Set-Cookie: fake=fooledyou; domain=..com; path=/; | ||
61 | +Set-Cookie: supercookie=fooledyou; domain=.com; path=/;^M | ||
62 | Content-Length: 4 | ||
63 | |||
64 | boo | ||
65 | </data> | ||
66 | </reply> | ||
67 | -- | ||
68 | 2.1.0 | ||
69 | |||
diff --git a/meta/recipes-support/curl/curl_7.37.1.bb b/meta/recipes-support/curl/curl_7.38.0.bb index 8b854d7a8c..85bd3be032 100644 --- a/meta/recipes-support/curl/curl_7.37.1.bb +++ b/meta/recipes-support/curl/curl_7.38.0.bb | |||
@@ -7,17 +7,15 @@ LIC_FILES_CHKSUM = "file://COPYING;beginline=7;md5=3a34942f4ae3fbf1a303160714e66 | |||
7 | 7 | ||
8 | SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \ | 8 | SRC_URI = "http://curl.haxx.se/download/curl-${PV}.tar.bz2 \ |
9 | file://pkgconfig_fix.patch \ | 9 | file://pkgconfig_fix.patch \ |
10 | file://CVE-2014-3613.patch \ | 10 | " |
11 | file://CVE-2014-3620.patch \ | ||
12 | " | ||
13 | 11 | ||
14 | # curl likes to set -g0 in CFLAGS, so we stop it | 12 | # curl likes to set -g0 in CFLAGS, so we stop it |
15 | # from mucking around with debug options | 13 | # from mucking around with debug options |
16 | # | 14 | # |
17 | SRC_URI += " file://configure_ac.patch" | 15 | SRC_URI += " file://configure_ac.patch" |
18 | 16 | ||
19 | SRC_URI[md5sum] = "95c627abcf6494f5abe55effe7cd6a57" | 17 | SRC_URI[md5sum] = "af6b3c299bd891f43cb5f76c4091b7b4" |
20 | SRC_URI[sha256sum] = "c3ef3cd148f3778ddbefb344117d7829db60656efe1031f9e3065fc0faa25136" | 18 | SRC_URI[sha256sum] = "035bd41e99aa1a4e64713f4cea5ccdf366ca8199e9be1b53d5a043d5165f9eba" |
21 | 19 | ||
22 | inherit autotools pkgconfig binconfig multilib_header | 20 | inherit autotools pkgconfig binconfig multilib_header |
23 | 21 | ||