Gentoo Archives: gentoo-commits

From: "Alon Bar-Lev (alonbl)" <alonbl@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in net-libs/gnutls/files: gnutls-2.12.23-CVE-2014-3469.patch gnutls-2.12.23-CVE-2014-3468.patch gnutls-2.12.23-CVE-2014-3467.patch gnutls-2.12.23-CVE-2014-3466.patch
Date: Sat, 07 Jun 2014 18:18:52
Message-Id: 20140607181846.84C432004E@flycatcher.gentoo.org
1 alonbl 14/06/07 18:18:46
2
3 Added: gnutls-2.12.23-CVE-2014-3469.patch
4 gnutls-2.12.23-CVE-2014-3468.patch
5 gnutls-2.12.23-CVE-2014-3467.patch
6 gnutls-2.12.23-CVE-2014-3466.patch
7 Log:
8 Fix CVE-2014-3466, CVE-2014-3467, CVE-2014-3468, CVE-2014-3469 of 2.12 series
9
10 (Portage version: 2.2.8-r1/cvs/Linux x86_64, signed Manifest commit with key BF20DC51)
11
12 Revision Changes Path
13 1.1 net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3469.patch
14
15 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3469.patch?rev=1.1&view=markup
16 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3469.patch?rev=1.1&content-type=text/plain
17
18 Index: gnutls-2.12.23-CVE-2014-3469.patch
19 ===================================================================
20 From 7f5a6256231e278aa7d00b6851c22fb457537262 Mon Sep 17 00:00:00 2001
21 From: mancha <mancha1@××××.com>
22 Date: Sun, 1 Jun 2014
23 Subject: CVE-2014-3469
24
25 This is a backport adaptation for use with GnuTLS 2.12.23.
26
27 Relevant upstream commit(s):
28 -------------------------
29 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=a8b3e14f84174e
30 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=3d6a02f19ff15a
31 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=53958290ab731c
32
33 ---
34 lib/minitasn1/decoding.c | 11 ++++++++---
35 lib/minitasn1/element.c | 27 ++++++++++++++++++---------
36 2 files changed, 26 insertions(+), 12 deletions(-)
37
38 --- a/lib/minitasn1/decoding.c
39 +++ b/lib/minitasn1/decoding.c
40 @@ -231,7 +231,6 @@ asn1_get_octet_der (const unsigned char
41 if (der_len <= 0)
42 return ASN1_GENERIC_ERROR;
43
44 - /* if(str==NULL) return ASN1_SUCCESS; */
45 *str_len = asn1_get_length_der (der, der_len, &len_len);
46
47 if (*str_len < 0)
48 @@ -239,7 +238,10 @@ asn1_get_octet_der (const unsigned char
49
50 *ret_len = *str_len + len_len;
51 if (str_size >= *str_len)
52 - memcpy (str, der + len_len, *str_len);
53 + {
54 + if (*str_len > 0 && str != NULL)
55 + memcpy (str, der + len_len, *str_len);
56 + }
57 else
58 {
59 return ASN1_MEM_ERROR;
60 @@ -362,7 +364,10 @@ asn1_get_bit_der (const unsigned char *d
61 return ASN1_DER_ERROR;
62
63 if (str_size >= len_byte)
64 - memcpy (str, der + len_len + 1, len_byte);
65 + {
66 + if (len_byte > 0 && str)
67 + memcpy (str, der + len_len + 1, len_byte);
68 + }
69 else
70 {
71 return ASN1_MEM_ERROR;
72 --- a/lib/minitasn1/element.c
73 +++ b/lib/minitasn1/element.c
74 @@ -112,8 +112,11 @@ _asn1_convert_integer (const unsigned ch
75 /* VALUE_OUT is too short to contain the value conversion */
76 return ASN1_MEM_ERROR;
77
78 - for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
79 - value_out[k2 - k] = val[k2];
80 + if (value_out != NULL)
81 + {
82 + for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
83 + value_out[k2 - k] = val[k2];
84 + }
85
86 #if 0
87 printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
88 @@ -611,7 +614,8 @@ asn1_write_value (asn1_node node_root, c
89 if (ptr_size < data_size) { \
90 return ASN1_MEM_ERROR; \
91 } else { \
92 - memcpy( ptr, data, data_size); \
93 + if (ptr && data_size > 0) \
94 + memcpy( ptr, data, data_size); \
95 }
96
97 #define PUT_STR_VALUE( ptr, ptr_size, data) \
98 @@ -620,16 +624,19 @@ asn1_write_value (asn1_node node_root, c
99 return ASN1_MEM_ERROR; \
100 } else { \
101 /* this strcpy is checked */ \
102 - _asn1_strcpy(ptr, data); \
103 + if (ptr) { \
104 + _asn1_strcpy(ptr, data); \
105 + } \
106 }
107
108 #define ADD_STR_VALUE( ptr, ptr_size, data) \
109 - *len = (int) _asn1_strlen(data) + 1; \
110 - if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
111 + *len += _asn1_strlen(data); \
112 + if (ptr_size < (int) *len) { \
113 + (*len)++; \
114 return ASN1_MEM_ERROR; \
115 } else { \
116 /* this strcat is checked */ \
117 - _asn1_strcat(ptr, data); \
118 + if (ptr) _asn1_strcat (ptr, data); \
119 }
120
121 /**
122 @@ -786,7 +793,9 @@ asn1_read_value (asn1_node root, const c
123 case TYPE_OBJECT_ID:
124 if (node->type & CONST_ASSIGN)
125 {
126 - value[0] = 0;
127 + *len = 0;
128 + if (value)
129 + value[0] = 0;
130 p = node->down;
131 while (p)
132 {
133 @@ -800,7 +809,7 @@ asn1_read_value (asn1_node root, const c
134 }
135 p = p->right;
136 }
137 - *len = _asn1_strlen (value) + 1;
138 + (*len)++;
139 }
140 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
141 {
142
143
144
145 1.1 net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3468.patch
146
147 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3468.patch?rev=1.1&view=markup
148 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3468.patch?rev=1.1&content-type=text/plain
149
150 Index: gnutls-2.12.23-CVE-2014-3468.patch
151 ===================================================================
152 From 24ed1d41707f873f3b7a22159e4bb3942f319fac Mon Sep 17 00:00:00 2001
153 From: mancha <mancha1@××××.com>
154 Date: Sun, 1 Jun 2014
155 Subject: CVE-2014-3468
156
157 This is a backport adaptation for use with GnuTLS 2.12.23.
158
159 Relevant upstream commit(s):
160 -------------------------
161 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=1c3ccb3e040bf1
162
163 ---
164 lib/minitasn1/decoding.c | 7 +++++--
165 1 file changed, 5 insertions(+), 2 deletions(-)
166
167 --- a/lib/minitasn1/decoding.c
168 +++ b/lib/minitasn1/decoding.c
169 @@ -226,7 +226,7 @@ asn1_get_octet_der (const unsigned char
170 int *ret_len, unsigned char *str, int str_size,
171 int *str_len)
172 {
173 - int len_len;
174 + int len_len = 0;
175
176 if (der_len <= 0)
177 return ASN1_GENERIC_ERROR;
178 @@ -347,7 +347,7 @@ asn1_get_bit_der (const unsigned char *d
179 int *ret_len, unsigned char *str, int str_size,
180 int *bit_len)
181 {
182 - int len_len, len_byte;
183 + int len_len = 0, len_byte;
184
185 if (der_len <= 0)
186 return ASN1_GENERIC_ERROR;
187 @@ -358,6 +358,9 @@ asn1_get_bit_der (const unsigned char *d
188 *ret_len = len_byte + len_len + 1;
189 *bit_len = len_byte * 8 - der[len_len];
190
191 + if (*bit_len <= 0)
192 + return ASN1_DER_ERROR;
193 +
194 if (str_size >= len_byte)
195 memcpy (str, der + len_len + 1, len_byte);
196 else
197
198
199
200 1.1 net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3467.patch
201
202 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3467.patch?rev=1.1&view=markup
203 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3467.patch?rev=1.1&content-type=text/plain
204
205 Index: gnutls-2.12.23-CVE-2014-3467.patch
206 ===================================================================
207 From d4ff19de527cd3eb444c560639324cda35bc838e Mon Sep 17 00:00:00 2001
208 From: mancha <mancha1@××××.com>
209 Date: Sun, 1 Jun 2014
210 Subject: CVE-2014-3467
211
212 This is a backport adaptation for use with GnuTLS 2.12.23.
213
214 Relevant upstream commit(s):
215 -------------------------
216 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=ff3b5c68cc32e3
217 http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=51612fca32dda4
218
219 ---
220 lib/minitasn1/decoding.c | 6 +++---
221 1 file changed, 3 insertions(+), 3 deletions(-)
222
223 --- a/lib/minitasn1/decoding.c
224 +++ b/lib/minitasn1/decoding.c
225 @@ -149,7 +149,7 @@ asn1_get_tag_der (const unsigned char *d
226 /* Long form */
227 punt = 1;
228 ris = 0;
229 - while (punt <= der_len && der[punt] & 128)
230 + while (punt < der_len && der[punt] & 128)
231 {
232 last = ris;
233
234 @@ -259,7 +259,7 @@ _asn1_get_time_der (const unsigned char
235 if (der_len <= 0 || str == NULL)
236 return ASN1_DER_ERROR;
237 str_len = asn1_get_length_der (der, der_len, &len_len);
238 - if (str_len < 0 || str_size < str_len)
239 + if (str_len <= 0 || str_size < str_len)
240 return ASN1_DER_ERROR;
241 memcpy (str, der + len_len, str_len);
242 str[str_len] = 0;
243 @@ -285,7 +285,7 @@ _asn1_get_objectid_der (const unsigned c
244 return ASN1_GENERIC_ERROR;
245 len = asn1_get_length_der (der, der_len, &len_len);
246
247 - if (len < 0 || len > der_len || len_len > der_len)
248 + if (len <= 0 || len > der_len || len_len > der_len)
249 return ASN1_DER_ERROR;
250
251 val1 = der[len_len] / 40;
252
253
254
255 1.1 net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3466.patch
256
257 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3466.patch?rev=1.1&view=markup
258 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/gnutls/files/gnutls-2.12.23-CVE-2014-3466.patch?rev=1.1&content-type=text/plain
259
260 Index: gnutls-2.12.23-CVE-2014-3466.patch
261 ===================================================================
262 From e47d30e272a0b3977db8dae09327acad45b931d8 Mon Sep 17 00:00:00 2001
263 From: mancha <mancha1@××××.com>
264 Date: Sun, 1 Jun 2014
265 Subject: CVE-2014-3466
266
267 This is a backport adaptation for use with GnuTLS 2.12.23.
268
269 Relevant upstream commit(s):
270 -------------------------
271 https://gitorious.org/gnutls/gnutls/commit/688ea6428a432c
272 https://gitorious.org/gnutls/gnutls/commit/a7be326f0e33cf
273
274 ---
275 lib/gnutls_handshake.c | 2
276 tests/Makefile.am | 2
277 tests/long-session-id.c | 268 ++++++++++++++++++++++++++++++++++++++++
278 3 files changed, 270 insertions(+), 2 deletions(-)
279
280 --- a/lib/gnutls_handshake.c
281 +++ b/lib/gnutls_handshake.c
282 @@ -1797,7 +1797,7 @@ _gnutls_read_server_hello (gnutls_sessio
283 DECR_LEN (len, 1);
284 session_id_len = data[pos++];
285
286 - if (len < session_id_len)
287 + if (len < session_id_len || session_id_len > TLS_MAX_SESSION_ID_SIZE)
288 {
289 gnutls_assert ();
290 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
291 --- a/tests/Makefile.am
292 +++ b/tests/Makefile.am
293 @@ -64,7 +64,7 @@ ctests = simple gc set_pkcs12_cred certd
294 crq_key_id x509sign-verify cve-2009-1415 cve-2009-1416 \
295 crq_apis init_roundtrip pkcs12_s2k_pem dn2 mini-eagain \
296 nul-in-x509-names x509_altname pkcs12_encode mini-x509 \
297 - mini-x509-rehandshake rng-fork x509cert gendh
298 + mini-x509-rehandshake rng-fork x509cert gendh long-session-id
299
300 if ENABLE_OPENSSL
301 ctests += openssl
302 --- /dev/null
303 +++ b/tests/long-session-id.c
304 @@ -0,0 +1,268 @@
305 +/*
306 + * Copyright (C) 2012 Free Software Foundation, Inc.
307 + *
308 + * Author: Nikos Mavrogiannopoulos
309 + *
310 + * This file is part of GnuTLS.
311 + *
312 + * GnuTLS is free software; you can redistribute it and/or modify it
313 + * under the terms of the GNU General Public License as published by
314 + * the Free Software Foundation; either version 3 of the License, or
315 + * (at your option) any later version.
316 + *
317 + * GnuTLS is distributed in the hope that it will be useful, but
318 + * WITHOUT ANY WARRANTY; without even the implied warranty of
319 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
320 + * General Public License for more details.
321 + *
322 + * You should have received a copy of the GNU General Public License
323 + * along with GnuTLS; if not, write to the Free Software Foundation,
324 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
325 + */
326 +
327 +#ifdef HAVE_CONFIG_H
328 +#include <config.h>
329 +#endif
330 +
331 +#include <stdio.h>
332 +#include <stdlib.h>
333 +
334 +#if defined(_WIN32)
335 +
336 +int main()
337 +{
338 + exit(77);
339 +}
340 +
341 +#else
342 +
343 +#include <string.h>
344 +#include <sys/types.h>
345 +#include <netinet/in.h>
346 +#include <sys/socket.h>
347 +#include <sys/wait.h>
348 +#include <arpa/inet.h>
349 +#include <unistd.h>
350 +#include <gnutls/gnutls.h>
351 +#include <signal.h>
352 +
353 +static int debug = 0;
354 +static void terminate(int);
355 +
356 +/* This program tests the robustness of record
357 + * decoding.
358 + */
359 +
360 +static void client_log_func(int level, const char *str)
361 +{
362 + fprintf(stderr, "client|<%d>| %s", level, str);
363 +}
364 +
365 +static unsigned char server_cert_pem[] =
366 + "-----BEGIN CERTIFICATE-----\n"
367 + "MIICVjCCAcGgAwIBAgIERiYdMTALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
368 + "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTIxWhcNMDgwNDE3MTMyOTIxWjA3MRsw\n"
369 + "GQYDVQQKExJHbnVUTFMgdGVzdCBzZXJ2ZXIxGDAWBgNVBAMTD3Rlc3QuZ251dGxz\n"
370 + "Lm9yZzCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGA17pcr6MM8C6pJ1aqU46o63+B\n"
371 + "dUxrmL5K6rce+EvDasTaDQC46kwTHzYWk95y78akXrJutsoKiFV1kJbtple8DDt2\n"
372 + "DZcevensf9Op7PuFZKBroEjOd35znDET/z3IrqVgbtm2jFqab7a+n2q9p/CgMyf1\n"
373 + "tx2S5Zacc1LWn9bIjrECAwEAAaOBkzCBkDAMBgNVHRMBAf8EAjAAMBoGA1UdEQQT\n"
374 + "MBGCD3Rlc3QuZ251dGxzLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8B\n"
375 + "Af8EBQMDB6AAMB0GA1UdDgQWBBTrx0Vu5fglyoyNgw106YbU3VW0dTAfBgNVHSME\n"
376 + "GDAWgBTpPBz7rZJu5gakViyi4cBTJ8jylTALBgkqhkiG9w0BAQUDgYEAaFEPTt+7\n"
377 + "bzvBuOf7+QmeQcn29kT6Bsyh1RHJXf8KTk5QRfwp6ogbp94JQWcNQ/S7YDFHglD1\n"
378 + "AwUNBRXwd3riUsMnsxgeSDxYBfJYbDLeohNBsqaPDJb7XailWbMQKfAbFQ8cnOxg\n"
379 + "rOKLUQRWJ0K3HyXRMhbqjdLIaQiCvQLuizo=\n" "-----END CERTIFICATE-----\n";
380 +
381 +const gnutls_datum_t server_cert = { server_cert_pem,
382 + sizeof(server_cert_pem)
383 +};
384 +
385 +static unsigned char server_key_pem[] =
386 + "-----BEGIN RSA PRIVATE KEY-----\n"
387 + "MIICXAIBAAKBgQDXulyvowzwLqknVqpTjqjrf4F1TGuYvkrqtx74S8NqxNoNALjq\n"
388 + "TBMfNhaT3nLvxqResm62ygqIVXWQlu2mV7wMO3YNlx696ex/06ns+4VkoGugSM53\n"
389 + "fnOcMRP/PciupWBu2baMWppvtr6far2n8KAzJ/W3HZLllpxzUtaf1siOsQIDAQAB\n"
390 + "AoGAYAFyKkAYC/PYF8e7+X+tsVCHXppp8AoP8TEZuUqOZz/AArVlle/ROrypg5kl\n"
391 + "8YunrvUdzH9R/KZ7saNZlAPLjZyFG9beL/am6Ai7q7Ma5HMqjGU8kTEGwD7K+lbG\n"
392 + "iomokKMOl+kkbY/2sI5Czmbm+/PqLXOjtVc5RAsdbgvtmvkCQQDdV5QuU8jap8Hs\n"
393 + "Eodv/tLJ2z4+SKCV2k/7FXSKWe0vlrq0cl2qZfoTUYRnKRBcWxc9o92DxK44wgPi\n"
394 + "oMQS+O7fAkEA+YG+K9e60sj1K4NYbMPAbYILbZxORDecvP8lcphvwkOVUqbmxOGh\n"
395 + "XRmTZUuhBrJhJKKf6u7gf3KWlPl6ShKEbwJASC118cF6nurTjuLf7YKARDjNTEws\n"
396 + "qZEeQbdWYINAmCMj0RH2P0mvybrsXSOD5UoDAyO7aWuqkHGcCLv6FGG+qwJAOVqq\n"
397 + "tXdUucl6GjOKKw5geIvRRrQMhb/m5scb+5iw8A4LEEHPgGiBaF5NtJZLALgWfo5n\n"
398 + "hmC8+G8F0F78znQtPwJBANexu+Tg5KfOnzSILJMo3oXiXhf5PqXIDmbN0BKyCKAQ\n"
399 + "LfkcEcUbVfmDaHpvzwY9VEaoMOKVLitETXdNSxVpvWM=\n"
400 + "-----END RSA PRIVATE KEY-----\n";
401 +
402 +const gnutls_datum_t server_key = { server_key_pem,
403 + sizeof(server_key_pem)
404 +};
405 +
406 +
407 +/* A very basic TLS client, with anonymous authentication.
408 + */
409 +
410 +static void client(int fd, const char *prio)
411 +{
412 + int ret;
413 + gnutls_anon_client_credentials_t anoncred;
414 + gnutls_certificate_credentials_t x509_cred;
415 + gnutls_session_t session;
416 + /* Need to enable anonymous KX specifically. */
417 +
418 + gnutls_global_init();
419 +
420 + if (debug) {
421 + gnutls_global_set_log_function(client_log_func);
422 + gnutls_global_set_log_level(7);
423 + }
424 +
425 + gnutls_anon_allocate_client_credentials(&anoncred);
426 + gnutls_certificate_allocate_credentials(&x509_cred);
427 +
428 + /* Initialize TLS session
429 + */
430 + gnutls_init(&session, GNUTLS_CLIENT);
431 +
432 + /* Use default priorities */
433 + gnutls_priority_set_direct(session, prio, NULL);
434 +
435 + /* put the anonymous credentials to the current session
436 + */
437 + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
438 + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
439 +
440 + gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);
441 +
442 + /* Perform the TLS handshake
443 + */
444 + do {
445 + ret = gnutls_handshake(session);
446 + }
447 + while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
448 +
449 + if (ret < 0) {
450 + fprintf(stderr, "client: Handshake failed (expected)\n");
451 + gnutls_perror(ret);
452 + exit(0);
453 + } else {
454 + if (debug)
455 + fprintf(stderr, "client: Handshake was completed\n");
456 + }
457 +
458 + close(fd);
459 +
460 + gnutls_deinit(session);
461 +
462 + gnutls_anon_free_client_credentials(anoncred);
463 + gnutls_certificate_free_credentials(x509_cred);
464 +
465 + gnutls_global_deinit();
466 +}
467 +
468 +
469 +/* These are global */
470 +pid_t child;
471 +
472 +static void terminate(int ret)
473 +{
474 + kill(child, SIGTERM);
475 + exit(ret);
476 +}
477 +
478 +static void server(int fd, const char *prio)
479 +{
480 + int ret;
481 + uint8_t id[255];
482 + uint8_t buffer[] = "\x16\x03\x00\x01\x25"
483 + "\x02\x00\x01\x21"
484 + "\x03\x00"/*Server Version */
485 + /*Random*/"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00"
486 + /*SessionID*/"\xfe";
487 +
488 + ret = read(fd, id, sizeof(id));
489 + if (ret < 0) {
490 + abort();
491 + }
492 +
493 + ret = write(fd, buffer, sizeof(buffer));
494 + if (ret < 0) {
495 + return;
496 + }
497 +
498 + memset(id, 0xff, sizeof(id));
499 + ret = write(fd, id, sizeof(id));
500 + if (ret < 0) {
501 + return;
502 + }
503 +
504 + memset(id, 0xff, sizeof(id));
505 + ret = write(fd, id, sizeof(id));
506 + if (ret < 0) {
507 + return;
508 + }
509 + sleep(3);
510 +
511 + return;
512 +}
513 +
514 +static void start(const char *prio)
515 +{
516 + int fd[2];
517 + int ret;
518 +
519 + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
520 + if (ret < 0) {
521 + perror("socketpair");
522 + exit(1);
523 + }
524 +
525 + child = fork();
526 + if (child < 0) {
527 + perror("fork");
528 + exit(1);
529 + }
530 +
531 + if (child) {
532 + /* parent */
533 + close(fd[1]);
534 + server(fd[0], prio);
535 + kill(child, SIGTERM);
536 + } else {
537 + close(fd[0]);
538 + client(fd[1], prio);
539 + exit(0);
540 + }
541 +}
542 +
543 +static void ch_handler(int sig)
544 +{
545 + int status, ret = 0;
546 + wait(&status);
547 + if (WEXITSTATUS(status) != 0 ||
548 + (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) {
549 + if (WIFSIGNALED(status)) {
550 + fprintf(stderr, "Child died with sigsegv\n");
551 + ret = 1;
552 + } else {
553 + fprintf(stderr, "Child died with status %d\n",
554 + WEXITSTATUS(status));
555 + }
556 + terminate(ret);
557 + }
558 + return;
559 +}
560 +
561 +int main(int argc, char **argv)
562 +{
563 + signal(SIGCHLD, ch_handler);
564 +
565 + if (argc > 1)
566 + debug = 1;
567 +
568 + start("NORMAL");
569 + return 0;
570 +}
571 +
572 +#endif /* _WIN32 */