[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-3197

ssl/s2_srvr.c in OpenSSL 1.0.1 before 1.0.1r and 1.0.2 before 1.0.2f does not prevent use of disabled ciphers, which makes it easier for man-in-the-middle attackers to defeat cryptographic protection mechanisms by performing computations on SSLv2 traffic, related to the get_client_master_key and get_client_hello functions.

## Package
openssl

## Files to modify
- ssl/t1_lib.c

## Target Source Code

### ssl/t1_lib.c

#### region() [lines 165-273]
```c
	ssl3_free(s);
	}

void tls1_clear(SSL *s)
	{
	ssl3_clear(s);
	s->version = s->method->version;
	}

#ifndef OPENSSL_NO_EC

static int nid_list[] =
	{
		NID_sect163k1, /* sect163k1 (1) */
		NID_sect163r1, /* sect163r1 (2) */
		NID_sect163r2, /* sect163r2 (3) */
		NID_sect193r1, /* sect193r1 (4) */
		NID_sect193r2, /* sect193r2 (5) */
		NID_sect233k1, /* sect233k1 (6) */
		NID_sect233r1, /* sect233r1 (7) */
		NID_sect239k1, /* sect239k1 (8) */
		NID_sect283k1, /* sect283k1 (9) */
		NID_sect283r1, /* sect283r1 (10) */
		NID_sect409k1, /* sect409k1 (11) */
		NID_sect409r1, /* sect409r1 (12) */
		NID_sect571k1, /* sect571k1 (13) */
		NID_sect571r1, /* sect571r1 (14) */
		NID_secp160k1, /* secp160k1 (15) */
		NID_secp160r1, /* secp160r1 (16) */
		NID_secp160r2, /* secp160r2 (17) */
		NID_secp192k1, /* secp192k1 (18) */
		NID_X9_62_prime192v1, /* secp192r1 (19) */
		NID_secp224k1, /* secp224k1 (20) */
		NID_secp224r1, /* secp224r1 (21) */
		NID_secp256k1, /* secp256k1 (22) */
		NID_X9_62_prime256v1, /* secp256r1 (23) */
		NID_secp384r1, /* secp384r1 (24) */
		NID_secp521r1  /* secp521r1 (25) */
	};

static int pref_list[] =
	{
		NID_sect571r1, /* sect571r1 (14) */
		NID_sect571k1, /* sect571k1 (13) */
		NID_secp521r1, /* secp521r1 (25) */
		NID_sect409k1, /* sect409k1 (11) */
		NID_sect409r1, /* sect409r1 (12) */
		NID_secp384r1, /* secp384r1 (24) */
		NID_sect283k1, /* sect283k1 (9) */
		NID_sect283r1, /* sect283r1 (10) */
		NID_secp256k1, /* secp256k1 (22) */
		NID_X9_62_prime256v1, /* secp256r1 (23) */
		NID_sect239k1, /* sect239k1 (8) */
		NID_sect233k1, /* sect233k1 (6) */
		NID_sect233r1, /* sect233r1 (7) */
		NID_secp224k1, /* secp224k1 (20) */
		NID_secp224r1, /* secp224r1 (21) */
		NID_sect193r1, /* sect193r1 (4) */
		NID_sect193r2, /* sect193r2 (5) */
		NID_secp192k1, /* secp192k1 (18) */
		NID_X9_62_prime192v1, /* secp192r1 (19) */
		NID_sect163k1, /* sect163k1 (1) */
		NID_sect163r1, /* sect163r1 (2) */
		NID_sect163r2, /* sect163r2 (3) */
		NID_secp160k1, /* secp160k1 (15) */
		NID_secp160r1, /* secp160r1 (16) */
		NID_secp160r2, /* secp160r2 (17) */
	};

int tls1_ec_curve_id2nid(int curve_id)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	if ((curve_id < 1) || ((unsigned int)curve_id >
				sizeof(nid_list)/sizeof(nid_list[0])))
		return 0;
	return nid_list[curve_id-1];
	}

int tls1_ec_nid2curve_id(int nid)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	switch (nid)
		{
	case NID_sect163k1: /* sect163k1 (1) */
		return 1;
	case NID_sect163r1: /* sect163r1 (2) */
		return 2;
	case NID_sect163r2: /* sect163r2 (3) */
		return 3;
	case NID_sect193r1: /* sect193r1 (4) */
		return 4;
	case NID_sect193r2: /* sect193r2 (5) */
		return 5;
	case NID_sect233k1: /* sect233k1 (6) */
		return 6;
	case NID_sect233r1: /* sect233r1 (7) */
		return 7;
	case NID_sect239k1: /* sect239k1 (8) */
		return 8;
	case NID_sect283k1: /* sect283k1 (9) */
		return 9;
	case NID_sect283r1: /* sect283r1 (10) */
		return 10;
	case NID_sect409k1: /* sect409k1 (11) */
		return 11;
	case NID_sect409r1: /* sect409r1 (12) */
		return 12;
	case NID_sect571k1: /* sect571k1 (13) */
		return 13;
```

#### region() [lines 194-281]
```c
		NID_secp160r2, /* secp160r2 (17) */
		NID_secp192k1, /* secp192k1 (18) */
		NID_X9_62_prime192v1, /* secp192r1 (19) */
		NID_secp224k1, /* secp224k1 (20) */
		NID_secp224r1, /* secp224r1 (21) */
		NID_secp256k1, /* secp256k1 (22) */
		NID_X9_62_prime256v1, /* secp256r1 (23) */
		NID_secp384r1, /* secp384r1 (24) */
		NID_secp521r1  /* secp521r1 (25) */
	};

static int pref_list[] =
	{
		NID_sect571r1, /* sect571r1 (14) */
		NID_sect571k1, /* sect571k1 (13) */
		NID_secp521r1, /* secp521r1 (25) */
		NID_sect409k1, /* sect409k1 (11) */
		NID_sect409r1, /* sect409r1 (12) */
		NID_secp384r1, /* secp384r1 (24) */
		NID_sect283k1, /* sect283k1 (9) */
		NID_sect283r1, /* sect283r1 (10) */
		NID_secp256k1, /* secp256k1 (22) */
		NID_X9_62_prime256v1, /* secp256r1 (23) */
		NID_sect239k1, /* sect239k1 (8) */
		NID_sect233k1, /* sect233k1 (6) */
		NID_sect233r1, /* sect233r1 (7) */
		NID_secp224k1, /* secp224k1 (20) */
		NID_secp224r1, /* secp224r1 (21) */
		NID_sect193r1, /* sect193r1 (4) */
		NID_sect193r2, /* sect193r2 (5) */
		NID_secp192k1, /* secp192k1 (18) */
		NID_X9_62_prime192v1, /* secp192r1 (19) */
		NID_sect163k1, /* sect163k1 (1) */
		NID_sect163r1, /* sect163r1 (2) */
		NID_sect163r2, /* sect163r2 (3) */
		NID_secp160k1, /* secp160k1 (15) */
		NID_secp160r1, /* secp160r1 (16) */
		NID_secp160r2, /* secp160r2 (17) */
	};

int tls1_ec_curve_id2nid(int curve_id)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	if ((curve_id < 1) || ((unsigned int)curve_id >
				sizeof(nid_list)/sizeof(nid_list[0])))
		return 0;
	return nid_list[curve_id-1];
	}

int tls1_ec_nid2curve_id(int nid)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	switch (nid)
		{
	case NID_sect163k1: /* sect163k1 (1) */
		return 1;
	case NID_sect163r1: /* sect163r1 (2) */
		return 2;
	case NID_sect163r2: /* sect163r2 (3) */
		return 3;
	case NID_sect193r1: /* sect193r1 (4) */
		return 4;
	case NID_sect193r2: /* sect193r2 (5) */
		return 5;
	case NID_sect233k1: /* sect233k1 (6) */
		return 6;
	case NID_sect233r1: /* sect233r1 (7) */
		return 7;
	case NID_sect239k1: /* sect239k1 (8) */
		return 8;
	case NID_sect283k1: /* sect283k1 (9) */
		return 9;
	case NID_sect283r1: /* sect283r1 (10) */
		return 10;
	case NID_sect409k1: /* sect409k1 (11) */
		return 11;
	case NID_sect409r1: /* sect409r1 (12) */
		return 12;
	case NID_sect571k1: /* sect571k1 (13) */
		return 13;
	case NID_sect571r1: /* sect571r1 (14) */
		return 14;
	case NID_secp160k1: /* secp160k1 (15) */
		return 15;
	case NID_secp160r1: /* secp160r1 (16) */
		return 16;
	case NID_secp160r2: /* secp160r2 (17) */
		return 17;
```

#### tls1_ec_curve_id2nid() [lines 231-243]
```c
		NID_secp160r2, /* secp160r2 (17) */
	};

int tls1_ec_curve_id2nid(int curve_id)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	if ((curve_id < 1) || ((unsigned int)curve_id >
				sizeof(nid_list)/sizeof(nid_list[0])))
		return 0;
	return nid_list[curve_id-1];
	}

int tls1_ec_nid2curve_id(int nid)
```

#### region() [lines 449-540]
```c
		(*ret++) = (unsigned char) login_len;
		memcpy(ret, s->srp_ctx.login, login_len);
		ret+=login_len;
		}
#endif

#ifndef OPENSSL_NO_EC
	if (s->tlsext_ecpointformatlist != NULL)
		{
		/* Add TLS extension ECPointFormats to the ClientHello message */
		long lenmax;

		if ((lenmax = limit - ret - 5) < 0) return NULL;
		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
		if (s->tlsext_ecpointformatlist_length > 255)
			{
			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
			return NULL;
			}

		s2n(TLSEXT_TYPE_ec_point_formats,ret);
		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
		ret+=s->tlsext_ecpointformatlist_length;
		}
	if (s->tlsext_ellipticcurvelist != NULL)
		{
		/* Add TLS extension EllipticCurves to the ClientHello message */
		long lenmax;

		if ((lenmax = limit - ret - 6) < 0) return NULL;
		if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
		if (s->tlsext_ellipticcurvelist_length > 65532)
			{
			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
			return NULL;
			}

		s2n(TLSEXT_TYPE_elliptic_curves,ret);
		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);

		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
		 * elliptic_curve_list, but the examples use two bytes.
		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
		 * resolves this to two bytes.
		 */
		s2n(s->tlsext_ellipticcurvelist_length, ret);
		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
		ret+=s->tlsext_ellipticcurvelist_length;
		}
#endif /* OPENSSL_NO_EC */

	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
		{
		int ticklen;
		if (!s->new_session && s->session && s->session->tlsext_tick)
			ticklen = s->session->tlsext_ticklen;
		else if (s->session && s->tlsext_session_ticket &&
			 s->tlsext_session_ticket->data)
			{
			ticklen = s->tlsext_session_ticket->length;
			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
			if (!s->session->tlsext_tick)
				return NULL;
			memcpy(s->session->tlsext_tick,
			       s->tlsext_session_ticket->data,
			       ticklen);
			s->session->tlsext_ticklen = ticklen;
			}
		else
			ticklen = 0;
		if (ticklen == 0 && s->tlsext_session_ticket &&
		    s->tlsext_session_ticket->data == NULL)
			goto skip_ext;
		/* Check for enough room 2 for extension type, 2 for len
 		 * rest for ticket
  		 */
		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
		s2n(TLSEXT_TYPE_session_ticket,ret);
		s2n(ticklen,ret);
		if (ticklen)
			{
			memcpy(ret, s->session->tlsext_tick, ticklen);
			ret += ticklen;
			}
		}
		skip_ext:

	if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
		{
		if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
```

#### ssl_prepare_clienthello_tlsext() [lines 1761-1857]
```c
	}

int ssl_prepare_clienthello_tlsext(SSL *s)
	{
#ifndef OPENSSL_NO_EC
	/* If we are client and using an elliptic curve cryptography cipher suite, send the point formats
	 * and elliptic curves we support.
	 */
	int using_ecc = 0;
	int i;
	unsigned char *j;
	unsigned long alg_k, alg_a;
	STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);

	for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
		{
		SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);

		alg_k = c->algorithm_mkey;
		alg_a = c->algorithm_auth;
		if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
			{
			using_ecc = 1;
			break;
			}
		}
	using_ecc = using_ecc && (s->version >= TLS1_VERSION);
	if (using_ecc)
		{
		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
			{
			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
			return -1;
			}
		s->tlsext_ecpointformatlist_length = 3;
		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;

		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
		s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
			{
			s->tlsext_ellipticcurvelist_length = 0;
			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
			return -1;
			}
		for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i <
				sizeof(pref_list)/sizeof(pref_list[0]); i++)
			{
			int id = tls1_ec_nid2curve_id(pref_list[i]);
			s2n(id,j);
			}
		}
#endif /* OPENSSL_NO_EC */

#ifdef TLSEXT_TYPE_opaque_prf_input
 	{
		int r = 1;

		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
			{
			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
			if (!r)
				return -1;
			}

		if (s->tlsext_opaque_prf_input != NULL)
			{
			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
				OPENSSL_free(s->s3->client_opaque_prf_input);

			if (s->tlsext_opaque_prf_input_len == 0)
				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
			else
				s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
			if (s->s3->client_opaque_prf_input == NULL)
				{
				SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
				return -1;
				}
			s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
			}

		if (r == 2)
			/* at callback's request, insist on receiving an appropriate server opaque PRF input */
			s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
	}
#endif

	return 1;
	}

int ssl_prepare_serverhello_tlsext(SSL *s)
```

## Upstream Fix
```diff
From 8b6205c48496f519774954db97836343820bff27 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 10 Nov 2014 23:42:50 +0000
Subject: [PATCH] Added OPENSSL_NO_EC2M guards around the preferred EC curve
 list

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
---
 ssl/t1_lib.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d6aff4b682f23..f5728c28d97dd 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -204,28 +204,40 @@ static int nid_list[] =

 static int pref_list[] =
 	{
+#ifndef OPENSSL_NO_EC2M
 		NID_sect571r1, /* sect571r1 (14) */
 		NID_sect571k1, /* sect571k1 (13) */
+#endif
 		NID_secp521r1, /* secp521r1 (25) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect409k1, /* sect409k1 (11) */
 		NID_sect409r1, /* sect409r1 (12) */
+#endif
 		NID_secp384r1, /* secp384r1 (24) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect283k1, /* sect283k1 (9) */
 		NID_sect283r1, /* sect283r1 (10) */
+#endif
 		NID_secp256k1, /* secp256k1 (22) */
 		NID_X9_62_prime256v1, /* secp256r1 (23) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect239k1, /* sect239k1 (8) */
 		NID_sect233k1, /* sect233k1 (6) */
 		NID_sect233r1, /* sect233r1 (7) */
+#endif
 		NID_secp224k1, /* secp224k1 (20) */
 		NID_secp224r1, /* secp224r1 (21) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect193r1, /* sect193r1 (4) */
 		NID_sect193r2, /* sect193r2 (5) */
+#endif
 		NID_secp192k1, /* secp192k1 (18) */
 		NID_X9_62_prime192v1, /* secp192r1 (19) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect163k1, /* sect163k1 (1) */
 		NID_sect163r1, /* sect163r1 (2) */
 		NID_sect163r2, /* sect163r2 (3) */
+#endif
 		NID_secp160k1, /* secp160k1 (15) */
 		NID_secp160r1, /* secp160r1 (16) */
 		NID_secp160r2, /* secp160r2 (17) */
@@ -233,7 +245,7 @@ static int pref_list[] =

 int tls1_ec_curve_id2nid(int curve_id)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	if ((curve_id < 1) || ((unsigned int)curve_id >
 				sizeof(nid_list)/sizeof(nid_list[0])))
 		return 0;
@@ -242,7 +254,7 @@ int tls1_ec_curve_id2nid(int curve_id)

 int tls1_ec_nid2curve_id(int nid)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	switch (nid)
 		{
 	case NID_sect163k1: /* sect163k1 (1) */
@@ -488,11 +500,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
 		s2n(TLSEXT_TYPE_elliptic_curves,ret);
 		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);

-		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
-		 * elliptic_curve_list, but the examples use two bytes.
-		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
-		 * resolves this to two bytes.
-		 */
 		s2n(s->tlsext_ellipticcurvelist_length, ret);
 		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
 		ret+=s->tlsext_ellipticcurvelist_length;
@@ -1800,7 +1807,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
 		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
 		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;

-		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+		/* we support all named elliptic curves in RFC 4492 */
 		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
 		s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
 		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
```

Generate a backported patch for the SUSE target version.

[Assistant]
From 8b6205c48496f519774954db97836343820bff27 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 10 Nov 2014 23:42:50 +0000
Subject: [PATCH] Added OPENSSL_NO_EC2M guards around the preferred EC curve
 list

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
---
 ssl/t1_lib.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d6aff4b..f5728c2 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -204,28 +204,40 @@ static int nid_list[] =

 static int pref_list[] =
 	{
+#ifndef OPENSSL_NO_EC2M
 		NID_sect571r1, /* sect571r1 (14) */
 		NID_sect571k1, /* sect571k1 (13) */
+#endif
 		NID_secp521r1, /* secp521r1 (25) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect409k1, /* sect409k1 (11) */
 		NID_sect409r1, /* sect409r1 (12) */
+#endif
 		NID_secp384r1, /* secp384r1 (24) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect283k1, /* sect283k1 (9) */
 		NID_sect283r1, /* sect283r1 (10) */
+#endif
 		NID_secp256k1, /* secp256k1 (22) */
 		NID_X9_62_prime256v1, /* secp256r1 (23) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect239k1, /* sect239k1 (8) */
 		NID_sect233k1, /* sect233k1 (6) */
 		NID_sect233r1, /* sect233r1 (7) */
+#endif
 		NID_secp224k1, /* secp224k1 (20) */
 		NID_secp224r1, /* secp224r1 (21) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect193r1, /* sect193r1 (4) */
 		NID_sect193r2, /* sect193r2 (5) */
+#endif
 		NID_secp192k1, /* secp192k1 (18) */
 		NID_X9_62_prime192v1, /* secp192r1 (19) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect163k1, /* sect163k1 (1) */
 		NID_sect163r1, /* sect163r1 (2) */
 		NID_sect163r2, /* sect163r2 (3) */
+#endif
 		NID_secp160k1, /* secp160k1 (15) */
 		NID_secp160r1, /* secp160r1 (16) */
 		NID_secp160r2, /* secp160r2 (17) */
@@ -233,7 +245,7 @@ static int pref_list[] =

 int tls1_ec_curve_id2nid(int curve_id)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	if ((curve_id < 1) || ((unsigned int)curve_id >
 				sizeof(nid_list)/sizeof(nid_list[0])))
 		return 0;
@@ -242,7 +254,7 @@ int tls1_ec_curve_id2nid(int curve_id)

 int tls1_ec_nid2curve_id(int nid)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	switch (nid)
 		{
 	case NID_sect163k1: /* sect163k1 (1) */
@@ -488,11 +500,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
 		s2n(TLSEXT_TYPE_elliptic_curves,ret);
 		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);

-		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
-		 * elliptic_curve_list, but the examples use two bytes.
-		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
-		 * resolves this to two bytes.
-		 */
 		s2n(s->tlsext_ellipticcurvelist_length, ret);
 		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
 		ret+=s->tlsext_ellipticcurvelist_length;
@@ -1800,7 +1807,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
 		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
 		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;

-		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+		/* we support all named elliptic curves in RFC 4492 */
 		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
 		s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
 		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
--
2.1.2


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2016-4658

xpointer.c in libxml2 before 2.9.5 (as used in Apple iOS before 10, OS X before 10.12, tvOS before 10, and watchOS before 3, and other products) does not forbid namespace nodes in XPointer ranges, which allows remote attackers to execute arbitrary code or cause a denial of service (use-after-free and memory corruption) via a crafted XML document.

## Package
libxml2

## Files to modify
- SAX2.c

## Upstream Fix
```diff
commit 77b77b1301e052d90e6a0967534a698506afcd86
Author: Daniel Veillard <veillard@redhat.com>
Date:   Thu Jan 26 19:11:02 2012 +0800

    Fix SAX2 builder in case of undefined element namespaces

    Work as in XML-1.0 before namespaces, and use prefix:localname
    as the new element name (and no namespace of course)
    Also fix 3 cases in the regression tests where the prefix: was
    erroneously dropped in such case

Index: SAX2.c
===================================================================
--- SAX2.c.orig	2012-09-11 08:01:01.000000000 +0200
+++ SAX2.c	2012-12-15 16:32:27.353560391 +0100
@@ -2188,7 +2188,6 @@
     xmlNodePtr parent;
     xmlNsPtr last = NULL, ns;
     const xmlChar *uri, *pref;
-    xmlChar *lname = NULL;
     int i, j;

     if (ctx == NULL) return;
@@ -2208,20 +2207,6 @@
     }

     /*
-     * Take care of the rare case of an undefined namespace prefix
-     */
-    if ((prefix != NULL) && (URI == NULL)) {
-        if (ctxt->dictNames) {
-	    const xmlChar *fullname;
-
-	    fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
-	    if (fullname != NULL)
-	        localname = fullname;
-	} else {
-	    lname = xmlBuildQName(localname, prefix, NULL, 0);
-	}
-    }
-    /*
      * allocate the node
      */
     if (ctxt->freeElems != NULL) {
@@ -2234,10 +2219,7 @@
 	if (ctxt->dictNames)
 	    ret->name = localname;
 	else {
-	    if (lname == NULL)
-		ret->name = xmlStrdup(localname);
-	    else
-	        ret->name = lname;
+	    ret->name = xmlStrdup(localname);
 	    if (ret->name == NULL) {
 	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 		return;
@@ -2249,11 +2231,8 @@
 	if (ctxt->dictNames)
 	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
 	                               (xmlChar *) localname, NULL);
-	else if (lname == NULL)
-	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
 	else
-	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
-	                               (xmlChar *) lname, NULL);
+	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
 	if (ret == NULL) {
 	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 	    return;
@@ -2360,31 +2339,6 @@
      */
     if (nb_attributes > 0) {
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
-	    /*
-	     * Handle the rare case of an undefined atribute prefix
-	     */
-	    if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
-		if (ctxt->dictNames) {
-		    const xmlChar *fullname;
-
-		    fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
-		                              attributes[j]);
-		    if (fullname != NULL) {
-			xmlSAX2AttributeNs(ctxt, fullname, NULL,
-			                   attributes[j+3], attributes[j+4]);
-		        continue;
-		    }
-		} else {
-		    lname = xmlBuildQName(attributes[j], attributes[j+1],
-		                          NULL, 0);
-		    if (lname != NULL) {
-			xmlSAX2AttributeNs(ctxt, lname, NULL,
-			                   attributes[j+3], attributes[j+4]);
-			xmlFree(lname);
-		        continue;
-		    }
-		}
-	    }
 	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
 			       attributes[j+3], attributes[j+4]);
 	}

Index: result/namespaces/err_7.xml
===================================================================
--- result/namespaces/err_7.xml.orig
+++ result/namespaces/err_7.xml
@@ -1,2 +1,2 @@
 <?xml version="1.0"?>
-<f:foo/>
+<foo/>
Index: result/xmlid/id_tst2.xml
===================================================================
--- result/xmlid/id_tst2.xml.orig
+++ result/xmlid/id_tst2.xml
@@ -1,6 +1,6 @@
 Object is a Node Set :
 Set contains 1 nodes:
-1  ELEMENT n:foo
+1  ELEMENT foo
     ATTRIBUTE id
       TEXT
         content=bar
Index: result/xmlid/id_tst3.xml
===================================================================
--- result/xmlid/id_tst3.xml.orig
+++ result/xmlid/id_tst3.xml
@@ -1,6 +1,6 @@
 Object is a Node Set :
 Set contains 1 nodes:
-1  ELEMENT f:o:o
+1  ELEMENT o:o
     ATTRIBUTE id
       TEXT
         content=bar
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 77b77b1301e052d90e6a0967534a698506afcd86
Author: Daniel Veillard <veillard@redhat.com>
Date:   Thu Jan 26 19:11:02 2012 +0800

    Fix SAX2 builder in case of undefined element namespaces

    Work as in XML-1.0 before namespaces, and use prefix:localname
    as the new element name (and no namespace of course)
    Also fix 3 cases in the regression tests where the prefix: was
    erroneously dropped in such case

Index: SAX2.c
===================================================================
--- SAX2.c.orig	2012-09-11 08:01:01.000000000 +0200
+++ SAX2.c	2012-12-15 16:32:27.353560391 +0100
@@ -2188,7 +2188,6 @@
     xmlNodePtr parent;
     xmlNsPtr last = NULL, ns;
     const xmlChar *uri, *pref;
-    xmlChar *lname = NULL;
     int i, j;

     if (ctx == NULL) return;
@@ -2208,20 +2207,6 @@
     }

     /*
-     * Take care of the rare case of an undefined namespace prefix
-     */
-    if ((prefix != NULL) && (URI == NULL)) {
-        if (ctxt->dictNames) {
-	    const xmlChar *fullname;
-
-	    fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
-	    if (fullname != NULL)
-	        localname = fullname;
-	} else {
-	    lname = xmlBuildQName(localname, prefix, NULL, 0);
-	}
-    }
-    /*
      * allocate the node
      */
     if (ctxt->freeElems != NULL) {
@@ -2234,10 +2219,7 @@
 	if (ctxt->dictNames)
 	    ret->name = localname;
 	else {
-	    if (lname == NULL)
-		ret->name = xmlStrdup(localname);
-	    else
-	        ret->name = lname;
+	    ret->name = xmlStrdup(localname);
 	    if (ret->name == NULL) {
 	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 		return;
@@ -2249,11 +2231,8 @@
 	if (ctxt->dictNames)
 	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
 	                               (xmlChar *) localname, NULL);
-	else if (lname == NULL)
-	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
 	else
-	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
-	                               (xmlChar *) lname, NULL);
+	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
 	if (ret == NULL) {
 	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 	    return;
@@ -2360,31 +2339,6 @@
      */
     if (nb_attributes > 0) {
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
-	    /*
-	     * Handle the rare case of an undefined atribute prefix
-	     */
-	    if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
-		if (ctxt->dictNames) {
-		    const xmlChar *fullname;
-
-		    fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
-		                              attributes[j]);
-		    if (fullname != NULL) {
-			xmlSAX2AttributeNs(ctxt, fullname, NULL,
-			                   attributes[j+3], attributes[j+4]);
-		        continue;
-		    }
-		} else {
-		    lname = xmlBuildQName(attributes[j], attributes[j+1],
-		                          NULL, 0);
-		    if (lname != NULL) {
-			xmlSAX2AttributeNs(ctxt, lname, NULL,
-			                   attributes[j+3], attributes[j+4]);
-			xmlFree(lname);
-		        continue;
-		    }
-		}
-	    }
 	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
 			       attributes[j+3], attributes[j+4]);
 	}

Index: result/namespaces/err_7.xml
===================================================================
--- result/namespaces/err_7.xml.orig
+++ result/namespaces/err_7.xml
@@ -1,2 +1,2 @@
 <?xml version="1.0"?>
-<f:foo/>
+<foo/>
Index: result/xmlid/id_tst2.xml
===================================================================
--- result/xmlid/id_tst2.xml.orig
+++ result/xmlid/id_tst2.xml
@@ -1,6 +1,6 @@
 Object is a Node Set :
 Set contains 1 nodes:
-1  ELEMENT n:foo
+1  ELEMENT foo
     ATTRIBUTE id
       TEXT
         content=bar
Index: result/xmlid/id_tst3.xml
===================================================================
--- result/xmlid/id_tst3.xml.orig
+++ result/xmlid/id_tst3.xml
@@ -1,6 +1,6 @@
 Object is a Node Set :
 Set contains 1 nodes:
-1  ELEMENT f:o:o
+1  ELEMENT o:o
     ATTRIBUTE id
       TEXT
         content=bar


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2016-6250

Integer overflow in the ISO9660 writer in libarchive before 3.2.1 allows remote attackers to cause a denial of service (application crash) or execute arbitrary code via vectors related to verifying filename lengths when writing an ISO9660 archive, which trigger a buffer overflow.

## Package
libarchive

## Files to modify
- libarchive/archive_read_support_format_iso9660.c

## Upstream Fix
```diff
commit 3ad08e01b4d253c66ae56414886089684155af22
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sun Jun 19 14:34:37 2016 -0700

    Issue 717:  Fix integer overflow when computing location of volume descriptor

    The multiplication here defaulted to 'int' but calculations
    of file positions should always use int64_t.  A simple cast
    suffices to fix this since the base location is always 32 bits
    for ISO, so multiplying by the sector size will never overflow
    a 64-bit integer.

diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 6934cee..f41ba38 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -1091,7 +1091,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 		/* This condition is unlikely; by way of caution. */
 		vd = &(iso9660->joliet);

-	skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+	skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
 	skipsize = __archive_read_consume(a, skipsize);
 	if (skipsize < 0)
 		return ((int)skipsize);
@@ -1129,7 +1129,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 	    && iso9660->seenJoliet) {
 		/* Switch reading data from primary to joliet. */
 		vd = &(iso9660->joliet);
-		skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+		skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
 		skipsize -= iso9660->current_position;
 		skipsize = __archive_read_consume(a, skipsize);
 		if (skipsize < 0)
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 3ad08e01b4d253c66ae56414886089684155af22
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sun Jun 19 14:34:37 2016 -0700

    Issue 717:  Fix integer overflow when computing location of volume descriptor

    The multiplication here defaulted to 'int' but calculations
    of file positions should always use int64_t.  A simple cast
    suffices to fix this since the base location is always 32 bits
    for ISO, so multiplying by the sector size will never overflow
    a 64-bit integer.

diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 6934cee..f41ba38 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -1091,7 +1091,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 		/* This condition is unlikely; by way of caution. */
 		vd = &(iso9660->joliet);

-	skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+	skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
 	skipsize = __archive_read_consume(a, skipsize);
 	if (skipsize < 0)
 		return ((int)skipsize);
@@ -1129,7 +1129,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 	    && iso9660->seenJoliet) {
 		/* Switch reading data from primary to joliet. */
 		vd = &(iso9660->joliet);
-		skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+		skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
 		skipsize -= iso9660->current_position;
 		skipsize = __archive_read_consume(a, skipsize);
 		if (skipsize < 0)


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2016-6250

Integer overflow in the ISO9660 writer in libarchive before 3.2.1 allows remote attackers to cause a denial of service (application crash) or execute arbitrary code via vectors related to verifying filename lengths when writing an ISO9660 archive, which trigger a buffer overflow.

## Package
libarchive

## Files to modify
- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c
- libarchive/test/test_read_format_7zip_malformed.c
- libarchive/archive_read_support_format_7zip.c

## Target Source Code

### Makefile.am

#### region() [lines 334-420]
```c
	libarchive/test/test_compat_cpio.c			\
	libarchive/test/test_compat_gtar.c			\
	libarchive/test/test_compat_gzip.c			\
	libarchive/test/test_compat_lzip.c			\
	libarchive/test/test_compat_lzma.c			\
	libarchive/test/test_compat_lzop.c			\
	libarchive/test/test_compat_mac.c			\
	libarchive/test/test_compat_pax_libarchive_2x.c		\
	libarchive/test/test_compat_solaris_tar_acl.c		\
	libarchive/test/test_compat_solaris_pax_sparse.c	\
	libarchive/test/test_compat_tar_hardlink.c		\
	libarchive/test/test_compat_uudecode.c			\
	libarchive/test/test_compat_xz.c			\
	libarchive/test/test_compat_zip.c			\
	libarchive/test/test_empty_write.c			\
	libarchive/test/test_entry.c				\
	libarchive/test/test_entry_strmode.c			\
	libarchive/test/test_extattr_freebsd.c			\
	libarchive/test/test_filter_count.c			\
	libarchive/test/test_fuzz.c				\
	libarchive/test/test_gnutar_filename_encoding.c		\
	libarchive/test/test_link_resolver.c			\
	libarchive/test/test_open_failure.c			\
	libarchive/test/test_open_fd.c				\
	libarchive/test/test_open_file.c			\
	libarchive/test/test_open_filename.c			\
	libarchive/test/test_pax_filename_encoding.c		\
	libarchive/test/test_read_data_large.c			\
	libarchive/test/test_read_disk.c			\
	libarchive/test/test_read_disk_directory_traversals.c	\
	libarchive/test/test_read_disk_entry_from_file.c	\
	libarchive/test/test_read_extract.c			\
	libarchive/test/test_read_file_nonexistent.c		\
	libarchive/test/test_read_filter_grzip.c		\
	libarchive/test/test_read_filter_lrzip.c		\
	libarchive/test/test_read_filter_lzop.c			\
	libarchive/test/test_read_filter_lzop_multiple_parts.c	\
	libarchive/test/test_read_filter_program.c		\
	libarchive/test/test_read_filter_program_signature.c	\
	libarchive/test/test_read_filter_uudecode.c		\
	libarchive/test/test_read_format_7zip.c			\
	libarchive/test/test_read_format_ar.c			\
	libarchive/test/test_read_format_cab.c			\
	libarchive/test/test_read_format_cab_filename.c		\
	libarchive/test/test_read_format_cpio_afio.c		\
	libarchive/test/test_read_format_cpio_bin.c		\
	libarchive/test/test_read_format_cpio_bin_Z.c		\
	libarchive/test/test_read_format_cpio_bin_be.c		\
	libarchive/test/test_read_format_cpio_bin_bz2.c		\
	libarchive/test/test_read_format_cpio_bin_gz.c		\
	libarchive/test/test_read_format_cpio_bin_lzip.c	\
	libarchive/test/test_read_format_cpio_bin_lzma.c	\
	libarchive/test/test_read_format_cpio_bin_xz.c		\
	libarchive/test/test_read_format_cpio_filename.c	\
	libarchive/test/test_read_format_cpio_odc.c		\
	libarch
/* ... truncated ... */
```

### libarchive/archive_read_support_format_7zip.c

#### read_CodersInfo() [lines 1897-1995]
```c
}

static int
read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
{
	const unsigned char *p;
	struct _7z_digests digest;
	unsigned i;

	memset(ci, 0, sizeof(*ci));
	memset(&digest, 0, sizeof(digest));

	if ((p = header_bytes(a, 1)) == NULL)
		goto failed;
	if (*p != kFolder)
		goto failed;

	/*
	 * Read NumFolders.
	 */
	if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
		goto failed;
	if (1000000 < ci->numFolders)
			return (-1);

	/*
	 * Read External.
	 */
	if ((p = header_bytes(a, 1)) == NULL)
		goto failed;
	switch (*p) {
	case 0:
		ci->folders =
			calloc((size_t)ci->numFolders, sizeof(*ci->folders));
		if (ci->folders == NULL)
			return (-1);
		for (i = 0; i < ci->numFolders; i++) {
			if (read_Folder(a, &(ci->folders[i])) < 0)
				goto failed;
		}
		break;
	case 1:
		if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
			return (-1);
		if (1000000 < ci->dataStreamIndex)
			return (-1);
		break;
	}

	if ((p = header_bytes(a, 1)) == NULL)
		goto failed;
	if (*p != kCodersUnPackSize)
		goto failed;

	for (i = 0; i < ci->numFolders; i++) {
		struct _7z_folder *folder = &(ci->folders[i]);
		unsigned j;

		folder->unPackSize =
		    calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize));
		if (folder->unPackSize == NULL)
			goto failed;
		for (j = 0; j < folder->numOutStreams; j++) {
			if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
				goto failed;
		}
	}

	/*
	 * Read CRCs.
	 */
	if ((p = header_bytes(a, 1)) == NULL)
		goto failed;
	if (*p == kEnd)
		return (0);
	if (*p != kCRC)
		goto failed;
	if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0)
		goto failed;
	for (i = 0; i < ci->numFolders; i++) {
		ci->folders[i].digest_defined = digest.defineds[i];
		ci->folders[i].digest = digest.digests[i];
	}

	/*
	 *  Must be kEnd.
	 */
	if ((p = header_bytes(a, 1)) == NULL)
		goto failed;
	if (*p != kEnd)
		goto failed;
	free_Digest(&digest);
	return (0);
failed:
	free_Digest(&digest);
	return (-1);
}

static uint64_t
```

### Type definitions

```c
/* from archive_private.h */
struct archive {
	/*
	 * The magic/state values are used to sanity-check the
	 * client's usage.  If an API function is called at a
	 * ridiculous time, or the client passes us an invalid
	 * pointer, these values allow me to catch that.
	 */
	unsigned int	magic;
	unsigned int	state;

	/*
	 * Some public API functions depend on the "real" type of the
	 * archive object.
	 */
	struct archive_vtable *vtable;

	int		  archive_format;
	const char	 *archive_format_name;

	int	  compression_code;	/* Currently active compression. */
	const char *compression_name;

	/* Number of file entries processed. */
	int		  file_count;

	int		  archive_error_number;
	const char	 *error;
	struct archive_string	error_string;

	char *current_code;
	unsigned current_codepage; /* Current ACP(ANSI CodePage). */
	unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
	struct archive_string_conv *sconv;
};
```

## Upstream Fix
```diff
commit d094dc02905605ca514baf87855f026b9bf52f1f
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sun Feb 8 13:29:51 2015 -0800

    Issue 405: segfault on malformed 7z archive

    Reject a couple of nonsensical cases.

Index: libarchive-3.1.2/Makefile.am
===================================================================
--- libarchive-3.1.2.orig/Makefile.am
+++ libarchive-3.1.2/Makefile.am
@@ -373,6 +373,7 @@ libarchive_test_SOURCES=					\
 	libarchive/test/test_read_filter_program_signature.c	\
 	libarchive/test/test_read_filter_uudecode.c		\
 	libarchive/test/test_read_format_7zip.c			\
+        libarchive/test/test_read_format_7zip_malformed.c       \
 	libarchive/test/test_read_format_ar.c			\
 	libarchive/test/test_read_format_cab.c			\
 	libarchive/test/test_read_format_cab_filename.c		\
@@ -601,6 +602,8 @@ libarchive_test_EXTRA_DIST=\
 	libarchive/test/test_read_format_7zip_lzma1_2.7z.uu		\
 	libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu		\
 	libarchive/test/test_read_format_7zip_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_malformed.7z.uu 		\
+	libarchive/test/test_read_format_7zip_malformed2.7z.uu 		\
 	libarchive/test/test_read_format_7zip_ppmd.7z.uu		\
 	libarchive/test/test_read_format_7zip_symbolic_name.7z.uu	\
 	libarchive/test/test_read_format_ar.ar.uu			\
Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c
@@ -1940,7 +1940,16 @@ read_CodersInfo(struct archive_read *a,
 			return (-1);
 		if (1000000 < ci->dataStreamIndex)
 			return (-1);
+		if (ci->numFolders > 0) {
+			archive_set_error(&a->archive, -1,
+			    "Malformed 7-Zip archive");
+			goto failed;
+		}
 		break;
+	default:
+		archive_set_error(&a->archive, -1,
+		    "Malformed 7-Zip archive");
+		goto failed;
 	}

 	if ((p = header_bytes(a, 1)) == NULL)
Index: libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu
@@ -0,0 +1,5 @@
+begin 644 test_read_format_7zip_malformed.7z
+M-WJ\KR<<,#"@P/<&!P
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit d094dc02905605ca514baf87855f026b9bf52f1f
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sun Feb 8 13:29:51 2015 -0800

    Issue 405: segfault on malformed 7z archive

    Reject a couple of nonsensical cases.

Index: libarchive-3.1.2/Makefile.am
===================================================================
--- libarchive-3.1.2.orig/Makefile.am
+++ libarchive-3.1.2/Makefile.am
@@ -373,6 +373,7 @@ libarchive_test_SOURCES=					\
 	libarchive/test/test_read_filter_program_signature.c	\
 	libarchive/test/test_read_filter_uudecode.c		\
 	libarchive/test/test_read_format_7zip.c			\
+        libarchive/test/test_read_format_7zip_malformed.c       \
 	libarchive/test/test_read_format_ar.c			\
 	libarchive/test/test_read_format_cab.c			\
 	libarchive/test/test_read_format_cab_filename.c		\
@@ -601,6 +602,8 @@ libarchive_test_EXTRA_DIST=\
 	libarchive/test/test_read_format_7zip_lzma1_2.7z.uu		\
 	libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu		\
 	libarchive/test/test_read_format_7zip_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_malformed.7z.uu 		\
+	libarchive/test/test_read_format_7zip_malformed2.7z.uu 		\
 	libarchive/test/test_read_format_7zip_ppmd.7z.uu		\
 	libarchive/test/test_read_format_7zip_symbolic_name.7z.uu	\
 	libarchive/test/test_read_format_ar.ar.uu			\
Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c
@@ -1940,7 +1940,16 @@ read_CodersInfo(struct archive_read *a,
 			return (-1);
 		if (1000000 < ci->dataStreamIndex)
 			return (-1);
+		if (ci->numFolders > 0) {
+			archive_set_error(&a->archive, -1,
+			    "Malformed 7-Zip archive");
+			goto failed;
+		}
 		break;
+	default:
+		archive_set_error(&a->archive, -1,
+		    "Malformed 7-Zip archive");
+		goto failed;
 	}

 	if ((p = header_bytes(a, 1)) == NULL)
Index: libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu
@@ -0,0 +1,5 @@
+begin 644 test_read_format_7zip_malformed.7z
+M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y<P,#`P,#`P`00&``$)
+'!P`'"S`P#```
+`
+end
Index: libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.c
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+test_malformed1(void)
+{
+	const char *refname = "test_read_format_7zip_malformed.7z";
+	struct archive *a;
+	struct archive_entry *ae;
+
+	extract_reference_file(refname);
+
+	assert((a = archive_read_new()) != NULL);
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_malformed2(void)
+{
+	const char *refname = "test_read_format_7zip_malformed2.7z";
+	struct archive *a;
+	struct archive_entry *ae;
+
+	extract_reference_file(refname);
+
+	assert((a = archive_read_new()) != NULL);
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_malformed)
+{
+	test_malformed1();
+	test_malformed2();
+}
Index: libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed2.7z.uu
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed2.7z.uu
@@ -0,0 +1,5 @@
+begin 644 test_read_format_7zip_malformed2.7z
+M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y<P,#`P,#`P`00&``$)
+(!P`'"S`!#`P`
+`
+end


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-3197

ssl/s2_srvr.c in OpenSSL 1.0.1 before 1.0.1r and 1.0.2 before 1.0.2f does not prevent use of disabled ciphers, which makes it easier for man-in-the-middle attackers to defeat cryptographic protection mechanisms by performing computations on SSLv2 traffic, related to the get_client_master_key and get_client_hello functions.

## Package
openssl

## Files to modify
- openssl-1.0.1i.orig/crypto/bn/bn_print.c
- openssl-1.0.1i/crypto/bn/bn_print.c
- openssl-1.0.1i/crypto/bn/bn.h
- openssl-1.0.1i.orig/crypto/bn/bn.h

## Target Source Code

### crypto/bn/bn_print.c

#### region() [lines 19-105]
```c
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include "bn_lcl.h"

static const char Hex[]="0123456789ABCDEF";

/* Must 'OPENSSL_free' the returned data */
char *BN_bn2hex(const BIGNUM *a)
	{
	int i,j,v,z=0;
	char *buf;
	char *p;

	buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
	if (buf == NULL)
		{
		BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=buf;
	if (a->neg) *(p++)='-';
	if (BN_is_zero(a)) *(p++)='0';
	for (i=a->top-1; i >=0; i--)
		{
		for (j=BN_BITS2-8; j >= 0; j-=8)
			{
			/* strip leading zeros */
			v=((int)(a->d[i]>>(long)j))&0xff;
			if (z || (v != 0))
				{
				*(p++)=Hex[v>>4];
				*(p++)=Hex[v&0x0f];
				z=1;
				}
			}
		}
	*p='\0';
err:
	return(buf);
	}

/* Must 'OPENSSL_free' the returned data */
char *BN_bn2dec(const BIGNUM *a)
	{
	int i=0,num, ok = 0;
```

#### region() [lines 169-239]
```c
	return(buf);
	}

int BN_hex2bn(BIGNUM **bn, const char *a)
	{
	BIGNUM *ret=NULL;
	BN_ULONG l=0;
	int neg=0,h,m,i,j,k,c;
	int num;

	if ((a == NULL) || (*a == '\0')) return(0);

	if (*a == '-') { neg=1; a++; }

	for (i=0; isxdigit((unsigned char) a[i]); i++)
		;

	num=i+neg;
	if (bn == NULL) return(num);

	/* a is the start of the hex digits, and it is 'i' long */
	if (*bn == NULL)
		{
		if ((ret=BN_new()) == NULL) return(0);
		}
	else
		{
		ret= *bn;
		BN_zero(ret);
		}

	/* i is the number of hex digests; */
	if (bn_expand(ret,i*4) == NULL) goto err;

	j=i; /* least significant 'hex' */
	m=0;
	h=0;
	while (j > 0)
		{
		m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
		l=0;
		for (;;)
			{
			c=a[j-m];
			if ((c >= '0') && (c <= '9')) k=c-'0';
			else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
			else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
			else k=0; /* paranoia */
			l=(l<<4)|k;

			if (--m <= 0)
				{
				ret->d[h++]=l;
				break;
				}
			}
		j-=(BN_BYTES*2);
		}
	ret->top=h;
	bn_correct_top(ret);
	ret->neg=neg;

	*bn=ret;
	bn_check_top(ret);
	return(num);
err:
	if (*bn == NULL) BN_free(ret);
	return(0);
	}

int BN_dec2bn(BIGNUM **bn, const char *a)
```

#### region() [lines 236-297]
```c
	return(0);
	}

int BN_dec2bn(BIGNUM **bn, const char *a)
	{
	BIGNUM *ret=NULL;
	BN_ULONG l=0;
	int neg=0,i,j;
	int num;

	if ((a == NULL) || (*a == '\0')) return(0);
	if (*a == '-') { neg=1; a++; }

	for (i=0; isdigit((unsigned char) a[i]); i++)
		;

	num=i+neg;
	if (bn == NULL) return(num);

	/* a is the start of the digits, and it is 'i' long.
	 * We chop it into BN_DEC_NUM digits at a time */
	if (*bn == NULL)
		{
		if ((ret=BN_new()) == NULL) return(0);
		}
	else
		{
		ret= *bn;
		BN_zero(ret);
		}

	/* i is the number of digests, a bit of an over expand; */
	if (bn_expand(ret,i*4) == NULL) goto err;

	j=BN_DEC_NUM-(i%BN_DEC_NUM);
	if (j == BN_DEC_NUM) j=0;
	l=0;
	while (*a)
		{
		l*=10;
		l+= *a-'0';
		a++;
		if (++j == BN_DEC_NUM)
			{
			BN_mul_word(ret,BN_DEC_CONV);
			BN_add_word(ret,l);
			l=0;
			j=0;
			}
		}
	ret->neg=neg;

	bn_correct_top(ret);
	*bn=ret;
	bn_check_top(ret);
	return(num);
err:
	if (*bn == NULL) BN_free(ret);
	return(0);
	}

int BN_asc2bn(BIGNUM **bn, const char *a)
```

### crypto/bn/bn.h

#### region() [lines 92-178]
```c
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the Eric Young open source
 * license provided above.
 *
 * The binary polynomial arithmetic software is originally written by
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
 *
 */

#ifndef HEADER_BN_H
#define HEADER_BN_H

#include <openssl/e_os2.h>
#ifndef OPENSSL_NO_FP_API
#include <stdio.h> /* FILE */
#endif
#include <openssl/ossl_typ.h>
#include <openssl/crypto.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* These preprocessor symbols control various aspects of the bignum headers and
 * library code. They're not defined by any "normal" configuration, as they are
 * intended for development and testing purposes. NB: defining all three can be
 * useful for debugging application code as well as openssl itself.
 *
 * BN_DEBUG - turn on various debugging alterations to the bignum code
 * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
 * mismanagement of bignum internals. You must also define BN_DEBUG.
 */
/* #define BN_DEBUG */
/* #define BN_DEBUG_RAND */

#ifndef OPENSSL_SMALL_FOOTPRINT
#define BN_MUL_COMBA
#define BN_SQR_COMBA
#define BN_RECURSION
#endif

/* This next option uses the C libraries (2 word)/(1 word) function.
 * If it is not defined, I use my C version (which is slower).
 * The reason for this flag is that when the particular C compiler
 * library routine is used, and the library is linked with a different
 * compiler, the library is missing.  This mostly happens when the
 * library is built with gcc and then linked using normal cc.  This would
 * be a common occurrence because gcc normally produces code that is
 * 2 times faster than system compilers for the big number stuff.
 * For machines with only one compiler (or shared libraries), this should
 * be on.  Again this in only really a problem on machines
 * using "long long's", are 32bit, and are not using my assembler code. */
#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
    defined(OPENSSL_SYS_WIN32) || defined(linux)
# ifndef BN_DIV2W
#  define BN_DIV2W
# endif
#endif

/* assuming long is 64bit - this is the DEC Alpha
 * unsigned long long is only 64 bits :-(, don't define
 * BN_LLONG for the DEC Alpha */
#ifdef SIXTY_FOUR_BIT_LONG
```

#### region() [lines 657-745]
```c
/* Some functions allow for representation of the irreducible polynomials
 * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
 *     t^p[0] + t^p[1] + ... + t^p[k]
 * where m = p[0] > p[1] > ... > p[k] = 0.
 */
int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
	/* r = a mod p */
int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
	const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
	BN_CTX *ctx); /* r = (a * a) mod p */
int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
	BN_CTX *ctx); /* r = (1 / b) mod p */
int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
	const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
	const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
	const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
	const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
int	BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
int	BN_GF2m_arr2poly(const int p[], BIGNUM *a);

#endif

/* faster mod functions for the 'NIST primes'
 * 0 <= a < p^2 */
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);

const BIGNUM *BN_get0_nist_prime_192(void);
const BIGNUM *BN_get0_nist_prime_224(void);
const BIGNUM *BN_get0_nist_prime_256(void);
const BIGNUM *BN_get0_nist_prime_384(void);
const BIGNUM *BN_get0_nist_prime_521(void);

/* library internal functions */

#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
BIGNUM *bn_expand2(BIGNUM *a, int words);
#ifndef OPENSSL_NO_DEPRECATED
BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
#endif

/* Bignum consistency macros
 * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
 * bignum data after direct manipulations on the data. There is also an
 * "internal" macro, bn_check_top(), for verifying that there are no leading
 * zeroes. Unfortunately, some auditing is required due to the fact that
 * bn_fix_top() has become an overabused duct-tape because bignum data is
 * occasionally passed around in an inconsistent state. So the following
 * changes have been made to sort this out;
 * - bn_fix_top()s implementation has been moved to bn_correct_top()
 * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
 *   bn_check_top() is as before.
 * - if BN_DEBUG *is* defined;
 *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
 *     consistent. (ed: only if BN_DEBUG_RAND is defined)
 *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
 * The idea is to have debug builds flag up inconsistent bignums when they
 * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
 * the use of bn_fix_top() was appropriate (ie. it follows directly after code
 * that manipulates the bignum) it is converted to bn_correct_top(), and if it
 * was not appropriate, we convert it permanently to bn_check_top() and track
 * down the cause of the bug. Eventually, no internal code should be using the
 * bn_fix_top() macro. External applications and libraries should try this with
 * their own code too, both in terms of building against the openssl headers
 * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
 * defined. This not only improves external code, it provides more test
 * coverage for openssl's own code.
 */

#ifdef BN_DEBUG

/* We only need assert() when debugging */
#include <assert.h>

#ifdef BN_DEBUG_RAND
/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
#ifndef RAND_pseudo_bytes
int RAND_pseudo_bytes(unsigned char *buf,int num);
#define BN_DEBUG_TRIX
#endif
```

## Upstream Fix
```diff
Index: openssl-1.0.1i/crypto/bn/bn_print.c
===================================================================
--- openssl-1.0.1i.orig/crypto/bn/bn_print.c	2014-07-22 21:41:23.000000000 +0200
+++ openssl-1.0.1i/crypto/bn/bn_print.c	2016-02-24 22:09:06.146184510 +0100
@@ -58,6 +58,7 @@

 #include <stdio.h>
 #include <ctype.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include "bn_lcl.h"
@@ -180,10 +181,12 @@

 	if (*a == '-') { neg=1; a++; }

-	for (i=0; isxdigit((unsigned char) a[i]); i++)
-		;
+    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++);
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;

-	num=i+neg;
 	if (bn == NULL) return(num);

 	/* a is the start of the hex digits, and it is 'i' long */
@@ -197,7 +200,7 @@
 		BN_zero(ret);
 		}

-	/* i is the number of hex digests; */
+	/* i is the number of hex digits */
 	if (bn_expand(ret,i*4) == NULL) goto err;

 	j=i; /* least significant 'hex' */
@@ -244,12 +247,15 @@
 	int num;

 	if ((a == NULL) || (*a == '\0')) return(0);
+
 	if (*a == '-') { neg=1; a++; }

-	for (i=0; isdigit((unsigned char) a[i]); i++)
-		;
+    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++);
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;

-	num=i+neg;
 	if (bn == NULL) return(num);

 	/* a is the start of the digits, and it is 'i' long.
@@ -264,7 +270,7 @@
 		BN_zero(ret);
 		}

-	/* i is the number of digests, a bit of an over expand; */
+	/* i is the number of digits, a bit of an over expand */
 	if (bn_expand(ret,i*4) == NULL) goto err;

 	j=BN_DEC_NUM-(i%BN_DEC_NUM);
Index: openssl-1.0.1i/crypto/bn/bn.h
===================================================================
--- openssl-1.0.1i.orig/crypto/bn/bn.h	2014-08-06 23:10:56.000000000 +0200
+++ openssl-1.0.1i/crypto/bn/bn.h	2016-02-24 22:10:22.862770519 +0100
@@ -131,6 +131,7 @@
 #endif
 #include <openssl/ossl_typ.h>
 #include <openssl/crypto.h>
+#include <limits.h>

 #ifdef  __cplusplus
 extern "C" {
@@ -696,8 +697,16 @@

 /* library internal functions */

-#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
-	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+#define bn_expand(a,bits) \
+    ( \
+        bits > (INT_MAX - BN_BITS2 + 1) ? \
+            NULL \
+        : \
+            (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
+                (a) \
+            : \
+                bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
+    )
 #define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
 BIGNUM *bn_expand2(BIGNUM *a, int words);
 #ifndef OPENSSL_NO_DEPRECATED
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: openssl-1.0.1i/crypto/bn/bn_print.c
===================================================================
--- openssl-1.0.1i.orig/crypto/bn/bn_print.c	2014-07-22 21:41:23.000000000 +0200
+++ openssl-1.0.1i/crypto/bn/bn_print.c	2016-02-24 22:09:06.146184510 +0100
@@ -58,6 +58,7 @@

 #include <stdio.h>
 #include <ctype.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include "bn_lcl.h"
@@ -180,10 +181,12 @@

 	if (*a == '-') { neg=1; a++; }

-	for (i=0; isxdigit((unsigned char) a[i]); i++)
-		;
+    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++);
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;

-	num=i+neg;
 	if (bn == NULL) return(num);

 	/* a is the start of the hex digits, and it is 'i' long */
@@ -197,7 +200,7 @@
 		BN_zero(ret);
 		}

-	/* i is the number of hex digests; */
+	/* i is the number of hex digits */
 	if (bn_expand(ret,i*4) == NULL) goto err;

 	j=i; /* least significant 'hex' */
@@ -244,12 +247,15 @@
 	int num;

 	if ((a == NULL) || (*a == '\0')) return(0);
+
 	if (*a == '-') { neg=1; a++; }

-	for (i=0; isdigit((unsigned char) a[i]); i++)
-		;
+    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++);
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;

-	num=i+neg;
 	if (bn == NULL) return(num);

 	/* a is the start of the digits, and it is 'i' long.
@@ -264,7 +270,7 @@
 		BN_zero(ret);
 		}

-	/* i is the number of digests, a bit of an over expand; */
+	/* i is the number of digits, a bit of an over expand */
 	if (bn_expand(ret,i*4) == NULL) goto err;

 	j=BN_DEC_NUM-(i%BN_DEC_NUM);
Index: openssl-1.0.1i/crypto/bn/bn.h
===================================================================
--- openssl-1.0.1i.orig/crypto/bn/bn.h	2014-08-06 23:10:56.000000000 +0200
+++ openssl-1.0.1i/crypto/bn/bn.h	2016-02-24 22:10:22.862770519 +0100
@@ -131,6 +131,7 @@
 #endif
 #include <openssl/ossl_typ.h>
 #include <openssl/crypto.h>
+#include <limits.h>

 #ifdef  __cplusplus
 extern "C" {
@@ -696,8 +697,16 @@

 /* library internal functions */

-#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
-	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+#define bn_expand(a,bits) \
+    ( \
+        bits > (INT_MAX - BN_BITS2 + 1) ? \
+            NULL \
+        : \
+            (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
+                (a) \
+            : \
+                bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
+    )
 #define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
 BIGNUM *bn_expand2(BIGNUM *a, int words);
 #ifndef OPENSSL_NO_DEPRECATED


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-3197

ssl/s2_srvr.c in OpenSSL 1.0.1 before 1.0.1r and 1.0.2 before 1.0.2f does not prevent use of disabled ciphers, which makes it easier for man-in-the-middle attackers to defeat cryptographic protection mechanisms by performing computations on SSLv2 traffic, related to the get_client_master_key and get_client_hello functions.

## Package
openssl

## Files to modify
- openssl-1.0.1i/ssl/s23_clnt.c
- openssl-1.0.1i.orig/ssl/s23_srvr.c
- openssl-1.0.1i/ssl/s23_srvr.c
- openssl-1.0.1i.orig/ssl/s23_clnt.c

## Target Source Code

### ssl/s23_clnt.c

#### region() [lines 86-175]
```c
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
#include <openssl/evp.h>

static const SSL_METHOD *ssl23_get_client_method(int ver);
static int ssl23_client_hello(SSL *s);
static int ssl23_get_server_hello(SSL *s);
static const SSL_METHOD *ssl23_get_client_method(int ver)
	{
#ifndef OPENSSL_NO_SSL2
	if (ver == SSL2_VERSION)
		return(SSLv2_client_method());
#endif
	if (ver == SSL3_VERSION)
		return(SSLv3_client_method());
	else if (ver == TLS1_VERSION)
		return(TLSv1_client_method());
	else if (ver == TLS1_1_VERSION)
		return(TLSv1_1_client_method());
	else if (ver == TLS1_2_VERSION)
		return(TLSv1_2_client_method());
	else
		return(NULL);
	}

IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
			ssl_undefined_function,
			ssl23_connect,
			ssl23_get_client_method)

int ssl23_connect(SSL *s)
	{
	BUF_MEM *buf=NULL;
	unsigned long Time=(unsigned long)time(NULL);
	void (*cb)(const SSL *ssl,int type,int val)=NULL;
	int ret= -1;
	int new_state,state;

	RAND_add(&Time,sizeof(Time),0);
	ERR_clear_error();
	clear_sys_error();

	if (s->info_callback != NULL)
		cb=s->info_callback;
	else if (s->ctx->info_callback != NULL)
		cb=s->ctx->info_callback;

	s->in_handshake++;
	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);

	for (;;)
		{
		state=s->state;

		switch(s->state)
			{
		case SSL_ST_BEFORE:
		case SSL_ST_CONNECT:
		case SSL_ST_BEFORE|SSL_ST_CONNECT:
		case SSL_ST_OK|SSL_ST_CONNECT:

```

#### ssl23_get_server_hello() [lines 606-801]
```c
	return ret;
	}

static int ssl23_get_server_hello(SSL *s)
	{
	char buf[8];
	unsigned char *p;
	int i;
	int n;

	n=ssl23_read_bytes(s,7);

	if (n != 7) return(n);
	p=s->packet;

	memcpy(buf,p,n);

	if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) &&
		(p[5] == 0x00) && (p[6] == 0x02))
		{
#ifdef OPENSSL_NO_SSL2
		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
		goto err;
#else
		/* we are talking sslv2 */
		/* we need to clean up the SSLv3 setup and put in the
		 * sslv2 stuff. */
		int ch_len;

		if (s->options & SSL_OP_NO_SSLv2)
			{
			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
			goto err;
			}
		if (s->s2 == NULL)
			{
			if (!ssl2_new(s))
				goto err;
			}
		else
/* ... 43 lines omitted ... */

		s->method=SSLv2_client_method();
		s->handshake_func=s->method->ssl_connect;
#endif
		}
	else if (p[1] == SSL3_VERSION_MAJOR &&
	         p[2] <= TLS1_2_VERSION_MINOR &&
	         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
	          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
		{
		/* we have sslv3 or tls1 (server hello or alert) */

		if ((p[2] == SSL3_VERSION_MINOR) &&
			!(s->options & SSL_OP_NO_SSLv3))
			{
#ifdef OPENSSL_FIPS
			if(FIPS_mode())
				{
				SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
				goto err;
				}
#endif
			s->version=SSL3_VERSION;
			s->method=SSLv3_client_method();
			}
/* ... 67 lines omitted ... */

		s->handshake_func=s->method->ssl_connect;
		}
	else
		{
		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL);
		goto err;
		}
	s->init_num=0;

	/* Since, if we are sending a ssl23 client hello, we are not
	 * reusing a session-id */
	if (!ssl_get_new_session(s,0))
		goto err;

	return(SSL_connect(s));
err:
	return(-1);
	}

```

### ssl/s23_srvr.c

#### region() [lines 88-177]
```c
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif

static const SSL_METHOD *ssl23_get_server_method(int ver);
int ssl23_get_client_hello(SSL *s);
static const SSL_METHOD *ssl23_get_server_method(int ver)
	{
#ifndef OPENSSL_NO_SSL2
	if (ver == SSL2_VERSION)
		return(SSLv2_server_method());
#endif
	if (ver == SSL3_VERSION)
		return(SSLv3_server_method());
	else if (ver == TLS1_VERSION)
		return(TLSv1_server_method());
	else if (ver == TLS1_1_VERSION)
		return(TLSv1_1_server_method());
	else if (ver == TLS1_2_VERSION)
		return(TLSv1_2_server_method());
	else
		return(NULL);
	}

IMPLEMENT_ssl23_meth_func(SSLv23_server_method,
			ssl23_accept,
			ssl_undefined_function,
			ssl23_get_server_method)

int ssl23_accept(SSL *s)
	{
	BUF_MEM *buf;
	unsigned long Time=(unsigned long)time(NULL);
	void (*cb)(const SSL *ssl,int type,int val)=NULL;
	int ret= -1;
	int new_state,state;

	RAND_add(&Time,sizeof(Time),0);
	ERR_clear_error();
	clear_sys_error();

	if (s->info_callback != NULL)
		cb=s->info_callback;
	else if (s->ctx->info_callback != NULL)
		cb=s->ctx->info_callback;

	s->in_handshake++;
	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);

	for (;;)
		{
		state=s->state;

		switch(s->state)
			{
		case SSL_ST_BEFORE:
		case SSL_ST_ACCEPT:
		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
		case SSL_ST_OK|SSL_ST_ACCEPT:

```

#### ssl23_get_client_hello() [lines 235-655]
```c
	}

int ssl23_get_client_hello(SSL *s)
	{
	char buf_space[11]; /* Request this many bytes in initial read.
	                     * We can detect SSL 3.0/TLS 1.0 Client Hellos
	                     * ('type == 3') correctly only when the following
	                     * is in a single record, which is not guaranteed by
	                     * the protocol specification:
	                     * Byte  Content
	                     *  0     type            \
	                     *  1/2   version          > record header
	                     *  3/4   length          /
	                     *  5     msg_type        \
	                     *  6-8   length           > Client Hello message
	                     *  9/10  client_version  /
	                     */
	char *buf= &(buf_space[0]);
	unsigned char *p,*d,*d_len,*dd;
	unsigned int i;
	unsigned int csl,sil,cl;
	int n=0,j;
	int type=0;
	int v[2];

	if (s->state ==	SSL23_ST_SR_CLNT_HELLO_A)
		{
		/* read the initial header */
		v[0]=v[1]=0;

		if (!ssl3_setup_buffers(s)) goto err;

		n=ssl23_read_bytes(s, sizeof buf_space);
		if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */

		p=s->packet;

		memcpy(buf,p,n);

/* ... 316 lines omitted ... */

		s->method=SSLv2_server_method();
		s->handshake_func=s->method->ssl_accept;
#endif
		}

	if ((type == 2) || (type == 3))
		{
		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */

		if (!ssl_init_wbio_buffer(s,1)) goto err;

		/* we are in this state */
		s->state=SSL3_ST_SR_CLNT_HELLO_A;

		if (type == 3)
			{
			/* put the 'n' bytes we have read into the input buffer
			 * for SSLv3 */
			s->rstate=SSL_ST_READ_HEADER;
			s->packet_length=n;
			if (s->s3->rbuf.buf == NULL)
				if (!ssl3_setup_read_buffer(s))
					goto err;

			s->packet= &(s->s3->rbuf.buf[0]);
/* ... 19 lines omitted ... */
		s->client_version=(v[0]<<8)|v[1];
#endif
		s->handshake_func=s->method->ssl_accept;
		}

	if ((type < 1) || (type > 3))
		{
		/* bad, very bad */
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL);
		goto err;
		}
	s->init_num=0;

	if (buf != buf_space) OPENSSL_free(buf);
	return(SSL_accept(s));
err:
	if (buf != buf_space) OPENSSL_free(buf);
	return(-1);
	}

```

## Upstream Fix
```diff
commit 26a59d9b46574e457870197dffa802871b4c8fc7
Author: Geoff Thorpe <geoff@openssl.org>
Date:   Wed Oct 15 03:25:50 2014 -0400

    Fix no-ssl3 configuration option

    CVE-2014-3568

    Reviewed-by: Emilia Kasper <emilia@openssl.org>
    Reviewed-by: Rich Salz <rsalz@openssl.org>

Index: openssl-1.0.1i/ssl/s23_clnt.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_clnt.c	2014-10-30 17:13:45.901895834 +0100
+++ openssl-1.0.1i/ssl/s23_clnt.c	2014-10-30 17:15:17.029990562 +0100
@@ -125,9 +125,11 @@ static const SSL_METHOD *ssl23_get_clien
 	if (ver == SSL2_VERSION)
 		return(SSLv2_client_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_client_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_client_method());
 	else if (ver == TLS1_1_VERSION)
 		return(TLSv1_1_client_method());
@@ -698,6 +700,7 @@ static int ssl23_get_server_hello(SSL *s
 		{
 		/* we have sslv3 or tls1 (server hello or alert) */

+#ifndef OPENSSL_NO_SSL3
 		if ((p[2] == SSL3_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_SSLv3))
 			{
@@ -712,7 +715,9 @@ static int ssl23_get_server_hello(SSL *s
 			s->version=SSL3_VERSION;
 			s->method=SSLv3_client_method();
 			}
-		else if ((p[2] == TLS1_VERSION_MINOR) &&
+		else
+#endif
+		if ((p[2] == TLS1_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_TLSv1))
 			{
 			s->version=TLS1_VERSION;
Index: openssl-1.0.1i/ssl/s23_srvr.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_srvr.c	2014-10-30 17:13:45.901895834 +0100
+++ openssl-1.0.1i/ssl/s23_srvr.c	2014-10-30 17:15:17.029990562 +0100
@@ -127,9 +127,11 @@ static const SSL_METHOD *ssl23_get_serve
 	if (ver == SSL2_VERSION)
 		return(SSLv2_server_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_server_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_server_method());
 	else if (ver == TLS1_1_VERSION)
 		return(TLSv1_1_server_method());
@@ -600,6 +602,12 @@ static int ssl23_get_client_hello(SSL *s
 	if ((type == 2) || (type == 3))
 		{
 		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+                s->method = ssl23_get_server_method(s->version);
+		if (s->method == NULL)
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+			goto err;
+			}

 		if (!ssl_init_wbio_buffer(s,1)) goto err;

@@ -627,14 +635,6 @@ static int ssl23_get_client_hello(SSL *s
 			s->s3->rbuf.left=0;
 			s->s3->rbuf.offset=0;
 			}
-		if (s->version == TLS1_2_VERSION)
-			s->method = TLSv1_2_server_method();
-		else if (s->version == TLS1_1_VERSION)
-			s->method = TLSv1_1_server_method();
-		else if (s->version == TLS1_VERSION)
-			s->method = TLSv1_server_method();
-		else
-			s->method = SSLv3_server_method();
 #if 0 /* ssl3_get_client_hello does this */
 		s->client_version=(v[0]<<8)|v[1];
 #endif
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 26a59d9b46574e457870197dffa802871b4c8fc7
Author: Geoff Thorpe <geoff@openssl.org>
Date:   Wed Oct 15 03:25:50 2014 -0400

    Fix no-ssl3 configuration option

    CVE-2014-3568

    Reviewed-by: Emilia Kasper <emilia@openssl.org>
    Reviewed-by: Rich Salz <rsalz@openssl.org>

Index: openssl-1.0.1i/ssl/s23_clnt.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_clnt.c	2014-10-30 17:13:45.901895834 +0100
+++ openssl-1.0.1i/ssl/s23_clnt.c	2014-10-30 17:15:17.029990562 +0100
@@ -125,9 +125,11 @@ static const SSL_METHOD *ssl23_get_clien
 	if (ver == SSL2_VERSION)
 		return(SSLv2_client_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_client_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_client_method());
 	else if (ver == TLS1_1_VERSION)
 		return(TLSv1_1_client_method());
@@ -698,6 +700,7 @@ static int ssl23_get_server_hello(SSL *s
 		{
 		/* we have sslv3 or tls1 (server hello or alert) */

+#ifndef OPENSSL_NO_SSL3
 		if ((p[2] == SSL3_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_SSLv3))
 			{
@@ -712,7 +715,9 @@ static int ssl23_get_server_hello(SSL *s
 			s->version=SSL3_VERSION;
 			s->method=SSLv3_client_method();
 			}
-		else if ((p[2] == TLS1_VERSION_MINOR) &&
+		else
+#endif
+		if ((p[2] == TLS1_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_TLSv1))
 			{
 			s->version=TLS1_VERSION;
Index: openssl-1.0.1i/ssl/s23_srvr.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_srvr.c	2014-10-30 17:13:45.901895834 +0100
+++ openssl-1.0.1i/ssl/s23_srvr.c	2014-10-30 17:15:17.029990562 +0100
@@ -127,9 +127,11 @@ static const SSL_METHOD *ssl23_get_serve
 	if (ver == SSL2_VERSION)
 		return(SSLv2_server_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_server_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_server_method());
 	else if (ver == TLS1_1_VERSION)
 		return(TLSv1_1_server_method());
@@ -600,6 +602,12 @@ static int ssl23_get_client_hello(SSL *s
 	if ((type == 2) || (type == 3))
 		{
 		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+                s->method = ssl23_get_server_method(s->version);
+		if (s->method == NULL)
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+			goto err;
+			}

 		if (!ssl_init_wbio_buffer(s,1)) goto err;

@@ -627,14 +635,6 @@ static int ssl23_get_client_hello(SSL *s
 			s->s3->rbuf.left=0;
 			s->s3->rbuf.offset=0;
 			}
-		if (s->version == TLS1_2_VERSION)
-			s->method = TLSv1_2_server_method();
-		else if (s->version == TLS1_1_VERSION)
-			s->method = TLSv1_1_server_method();
-		else if (s->version == TLS1_VERSION)
-			s->method = TLSv1_server_method();
-		else
-			s->method = SSLv3_server_method();
 #if 0 /* ssl3_get_client_hello does this */
 		s->client_version=(v[0]<<8)|v[1];
 #endif


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2013-4560

Use-after-free vulnerability in lighttpd before 1.4.33 allows remote attackers to cause a denial of service (segmentation fault and crash) via unspecified vectors that trigger FAMMonitorDirectory failures.

## Package
lighttpd

## Files to modify
- src/stat_cache.c

## Upstream Fix
```diff
origin: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2013_03.txt

commit bbbe8878144ab178c6ec37e9aeb99640cc8b6672
Author: Stefan Bühler <stbuehler@web.de>
Date:   Tue Nov 12 12:37:03 2013 +0100

    [stat-cache] FAM: fix use after free

diff --git a/src/stat_cache.c b/src/stat_cache.c
index e995f3b..924f4dc 100644
--- a/src/stat_cache.c
+++ b/src/stat_cache.c
@@ -648,6 +648,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
 						FamErrlist[FAMErrno]);

 				fam_dir_entry_free(fam_dir);
+				fam_dir = NULL;
 			} else {
 				int osize = 0;
```

Generate a backported patch for the SUSE target version.

[Assistant]
origin: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2013_03.txt

commit bbbe8878144ab178c6ec37e9aeb99640cc8b6672
Author: Stefan Bühler <stbuehler@web.de>
Date:   Tue Nov 12 12:37:03 2013 +0100

    [stat-cache] FAM: fix use after free

diff --git a/src/stat_cache.c b/src/stat_cache.c
index e995f3b..924f4dc 100644
--- a/src/stat_cache.c
+++ b/src/stat_cache.c
@@ -648,6 +648,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
 						FamErrlist[FAMErrno]);

 				fam_dir_entry_free(fam_dir);
+				fam_dir = NULL;
 			} else {
 				int osize = 0;


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-3197

ssl/s2_srvr.c in OpenSSL 1.0.1 before 1.0.1r and 1.0.2 before 1.0.2f does not prevent use of disabled ciphers, which makes it easier for man-in-the-middle attackers to defeat cryptographic protection mechanisms by performing computations on SSLv2 traffic, related to the get_client_master_key and get_client_hello functions.

## Package
openssl

## Files to modify
- openssl-1.0.1g.orig/crypto/rand/rand_egd.c

## Target Source Code

### crypto/rand/rand_egd.c

#### region() [lines 56-143]
```c

#include <openssl/e_os2.h>
#include <openssl/rand.h>
#include <openssl/buffer.h>

/*
 * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
 *
 * This module supplies three routines:
 *
 * RAND_query_egd_bytes(path, buf, bytes)
 *   will actually query "bytes" bytes of entropy form the egd-socket located
 *   at path and will write them to buf (if supplied) or will directly feed
 *   it to RAND_seed() if buf==NULL.
 *   The number of bytes is not limited by the maximum chunk size of EGD,
 *   which is 255 bytes. If more than 255 bytes are wanted, several chunks
 *   of entropy bytes are requested. The connection is left open until the
 *   query is competed.
 *   RAND_query_egd_bytes() returns with
 *     -1  if an error occured during connection or communication.
 *     num the number of bytes read from the EGD socket. This number is either
 *         the number of bytes requested or smaller, if the EGD pool is
 *         drained and the daemon signals that the pool is empty.
 *   This routine does not touch any RAND_status(). This is necessary, since
 *   PRNG functions may call it during initialization.
 *
 * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
 *   used to seed the PRNG.
 *   RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
 *   Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
 *   seed status so that the return value can reflect the seed state:
 *     -1  if an error occured during connection or communication _or_
 *         if the PRNG has still not received the required seeding.
 *     num the number of bytes read from the EGD socket. This number is either
 *         the number of bytes requested or smaller, if the EGD pool is
 *         drained and the daemon signals that the pool is empty.
 *
 * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed
 *   the PRNG.
 *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
 */

#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
	{
	return(-1);
	}
int RAND_egd(const char *path)
	{
	return(-1);
	}

int RAND_egd_bytes(const char *path,int bytes)
	{
	return(-1);
	}
#else
#include <openssl/opensslconf.h>
#include OPENSSL_UNISTD
#include <sys/types.h>
#include <sys/socket.h>
#ifndef NO_SYS_UN_H
# ifdef OPENSSL_SYS_VXWORKS
#   include <streams/un.h>
# else
#   include <sys/un.h>
# endif
#else
struct	sockaddr_un {
	short	sun_family;		/* AF_UNIX */
	char	sun_path[108];		/* path name (gag) */
};
#endif /* NO_SYS_UN_H */
#include <string.h>
#include <errno.h>

#ifndef offsetof
#  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
	{
	int ret = 0;
	struct sockaddr_un addr;
	int len, num, numbytes;
	int fd = -1;
	int success;
	unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
```

## Upstream Fix
```diff
--- openssl-1.0.1g.orig/crypto/rand/rand_egd.c
+++ openssl-1.0.1g/crypto/rand/rand_egd.c
@@ -95,7 +95,7 @@
  *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
  */

-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
+#if defined(__linux__) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
 	{
 	return(-1);
```

Generate a backported patch for the SUSE target version.

[Assistant]
--- openssl-1.0.1g.orig/crypto/rand/rand_egd.c
+++ openssl-1.0.1g/crypto/rand/rand_egd.c
@@ -95,7 +95,7 @@
  *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
  */

-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
+#if defined(__linux__) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
 	{
 	return(-1);


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2016-6250

Integer overflow in the ISO9660 writer in libarchive before 3.2.1 allows remote attackers to cause a denial of service (application crash) or execute arbitrary code via vectors related to verifying filename lengths when writing an ISO9660 archive, which trigger a buffer overflow.

## Package
libarchive

## Files to modify
- libarchive-3.1.2.orig/libarchive/archive_read_support_format_tar.c
- libarchive/archive_read_support_format_tar.c

## Target Source Code

### libarchive/archive_read_support_format_tar.c

#### archive_read_format_tar_read_header() [lines 421-521]
```c
 * tar_read_header() function below.
 */
static int
archive_read_format_tar_read_header(struct archive_read *a,
    struct archive_entry *entry)
{
	/*
	 * When converting tar archives to cpio archives, it is
	 * essential that each distinct file have a distinct inode
	 * number.  To simplify this, we keep a static count here to
	 * assign fake dev/inode numbers to each tar entry.  Note that
	 * pax format archives may overwrite this with something more
	 * useful.
	 *
	 * Ideally, we would track every file read from the archive so
	 * that we could assign the same dev/ino pair to hardlinks,
	 * but the memory required to store a complete lookup table is
	 * probably not worthwhile just to support the relatively
	 * obscure tar->cpio conversion case.
	 */
	static int default_inode;
	static int default_dev;
	struct tar *tar;
	const char *p;
	int r;
	size_t l, unconsumed = 0;

	/* Assign default device/inode values. */
	archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
	archive_entry_set_ino(entry, ++default_inode); /* Don't use zero. */
	/* Limit generated st_ino number to 16 bits. */
	if (default_inode >= 0xffff) {
		++default_dev;
		default_inode = 0;
	}

	tar = (struct tar *)(a->format->data);
	tar->entry_offset = 0;
	gnu_clear_sparse_list(tar);
	tar->realsize = -1; /* Mark this as "unset" */

	/* Setup default string conversion. */
	tar->sconv = tar->opt_sconv;
	if (tar->sconv == NULL) {
		if (!tar->init_default_conversion) {
			tar->sconv_default =
			    archive_string_default_conversion_for_read(&(a->archive));
			tar->init_default_conversion = 1;
		}
		tar->sconv = tar->sconv_default;
	}

	r = tar_read_header(a, tar, entry, &unconsumed);

	tar_flush_unconsumed(a, &unconsumed);

	/*
	 * "non-sparse" files are really just sparse files with
	 * a single block.
	 */
	if (tar->sparse_list == NULL) {
		if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
		    != ARCHIVE_OK)
			return (ARCHIVE_FATAL);
	} else {
		struct sparse_block *sb;

		for (sb = tar->sparse_list; sb != NULL; sb = sb->next) {
			if (!sb->hole)
				archive_entry_sparse_add_entry(entry,
				    sb->offset, sb->remaining);
		}
	}

	if (r == ARCHIVE_OK) {
		/*
		 * "Regular" entry with trailing '/' is really
		 * directory: This is needed for certain old tar
		 * variants and even for some broken newer ones.
		 */
		const wchar_t *wp;
		wp = archive_entry_pathname_w(entry);
		if (wp != NULL) {
			l = wcslen(wp);
			if (archive_entry_filetype(entry) == AE_IFREG
			    && wp[l-1] == L'/')
				archive_entry_set_filetype(entry, AE_IFDIR);
		} else {
			p = archive_entry_pathname(entry);
			if (p == NULL)
				return (ARCHIVE_FAILED);
			l = strlen(p);
			if (archive_entry_filetype(entry) == AE_IFREG
			    && p[l-1] == '/')
				archive_entry_set_filetype(entry, AE_IFDIR);
		}
	}
	return (r);
}

static int
```

## Upstream Fix
```diff
commit bb9b157146a62e655fb369b32684398c949fa1b1
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sat Feb 21 09:36:23 2015 -0800

    Issue 407: Tar reader tries to examine last character of an empty filename

    Of interest:  While working on this, I noted that we have
    an existing test for tar files with empty filenames.
    That test asserts that the correct behavior here is for the
    format handler to return the entry with the empty filename
    and a status of ARCHIVE_OK.  Clients need to be robust against
    empty filenames.

Index: libarchive-3.1.2/libarchive/archive_read_support_format_tar.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_tar.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_tar.c
@@ -442,6 +442,7 @@ archive_read_format_tar_read_header(stru
 	static int default_dev;
 	struct tar *tar;
 	const char *p;
+	const wchar_t *wp;
 	int r;
 	size_t l, unconsumed = 0;

@@ -492,27 +493,22 @@ archive_read_format_tar_read_header(stru
 		}
 	}

-	if (r == ARCHIVE_OK) {
+	if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
 		/*
 		 * "Regular" entry with trailing '/' is really
 		 * directory: This is needed for certain old tar
 		 * variants and even for some broken newer ones.
 		 */
-		const wchar_t *wp;
-		wp = archive_entry_pathname_w(entry);
-		if (wp != NULL) {
+		if ((wp = archive_entry_pathname_w(entry)) != NULL) {
 			l = wcslen(wp);
-			if (archive_entry_filetype(entry) == AE_IFREG
-			    && wp[l-1] == L'/')
+			if (l > 0 && wp[l - 1] == L'/') {
 				archive_entry_set_filetype(entry, AE_IFDIR);
-		} else {
-			p = archive_entry_pathname(entry);
-			if (p == NULL)
-				return (ARCHIVE_FAILED);
+			}
+		} else if ((p = archive_entry_pathname(entry)) != NULL) {
 			l = strlen(p);
-			if (archive_entry_filetype(entry) == AE_IFREG
-			    && p[l-1] == '/')
+			if (l > 0 && p[l - 1] == '/') {
 				archive_entry_set_filetype(entry, AE_IFDIR);
+			}
 		}
 	}
 	return (r);
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit bb9b157146a62e655fb369b32684398c949fa1b1
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sat Feb 21 09:36:23 2015 -0800

    Issue 407: Tar reader tries to examine last character of an empty filename

    Of interest:  While working on this, I noted that we have
    an existing test for tar files with empty filenames.
    That test asserts that the correct behavior here is for the
    format handler to return the entry with the empty filename
    and a status of ARCHIVE_OK.  Clients need to be robust against
    empty filenames.

Index: libarchive-3.1.2/libarchive/archive_read_support_format_tar.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_tar.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_tar.c
@@ -442,6 +442,7 @@ archive_read_format_tar_read_header(stru
 	static int default_dev;
 	struct tar *tar;
 	const char *p;
+	const wchar_t *wp;
 	int r;
 	size_t l, unconsumed = 0;

@@ -492,27 +493,22 @@ archive_read_format_tar_read_header(stru
 		}
 	}

-	if (r == ARCHIVE_OK) {
+	if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
 		/*
 		 * "Regular" entry with trailing '/' is really
 		 * directory: This is needed for certain old tar
 		 * variants and even for some broken newer ones.
 		 */
-		const wchar_t *wp;
-		wp = archive_entry_pathname_w(entry);
-		if (wp != NULL) {
+		if ((wp = archive_entry_pathname_w(entry)) != NULL) {
 			l = wcslen(wp);
-			if (archive_entry_filetype(entry) == AE_IFREG
-			    && wp[l-1] == L'/')
+			if (l > 0 && wp[l - 1] == L'/') {
 				archive_entry_set_filetype(entry, AE_IFDIR);
-		} else {
-			p = archive_entry_pathname(entry);
-			if (p == NULL)
-				return (ARCHIVE_FAILED);
+			}
+		} else if ((p = archive_entry_pathname(entry)) != NULL) {
 			l = strlen(p);
-			if (archive_entry_filetype(entry) == AE_IFREG
-			    && p[l-1] == '/')
+			if (l > 0 && p[l - 1] == '/') {
 				archive_entry_set_filetype(entry, AE_IFDIR);
+			}
 		}
 	}
 	return (r);