[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/ssl_err.c
- openssl-1.0.1i.orig/ssl/s3_enc.c
- openssl-1.0.1i.orig/ssl/ssl_lib.c
- openssl-1.0.1i.orig/ssl/t1_enc.c
- openssl-1.0.1i/ssl/s23_srvr.c

## Target Source Code

### CHANGES

#### region() [lines 1-50]
```c

 OpenSSL CHANGES
 _______________

 Changes between 1.0.1h and 1.0.1i [6 Aug 2014]

  *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
     SRP code can be overrun an internal buffer. Add sanity check that
     g, A, B < N to SRP code.

     Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC
     Group for discovering this issue.
     (CVE-2014-3512)
     [Steve Henson]

  *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate
     TLS 1.0 instead of higher protocol versions when the ClientHello message
     is badly fragmented. This allows a man-in-the-middle attacker to force a
     downgrade to TLS 1.0 even if both the server and the client support a
     higher protocol version
/* ... truncated ... */
```

### apps/s_client.c

#### sc_usage() [lines 281-374]
```c
	}
#endif

static void sc_usage(void)
	{
	BIO_printf(bio_err,"usage: s_client args\n");
	BIO_printf(bio_err,"\n");
	BIO_printf(bio_err," -host host     - use -connect instead\n");
	BIO_printf(bio_err," -port port     - use -connect instead\n");
	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);

	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
	BIO_printf(bio_err," -verify_return_error - return verification errors\n");
	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
	BIO_printf(bio_err," -key arg      - Private key file to use,
/* ... truncated ... */
```

### crypto/err/openssl.ec

#### region() [lines 32-97]
```c
L ECDH		crypto/ecdh/ecdh.h		crypto/ecdh/ech_err.c
L STORE		crypto/store/store.h		crypto/store/str_err.c
L TS		crypto/ts/ts.h			crypto/ts/ts_err.c
L HMAC		crypto/hmac/hmac.h		crypto/hmac/hmac_err.c
L CMS		crypto/cms/cms.h		crypto/cms/cms_err.c
L JPAKE		crypto/jpake/jpake.h		crypto/jpake/jpake_err.c

# additional header files to be scanned for function names
L NONE		crypto/x509/x509_vfy.h		NONE
L NONE		crypto/ec/ec_lcl.h		NONE
L NONE		crypto/asn1/asn_lcl.h		NONE
L NONE		crypto/cms/cms_lcl.h		NONE

F RSAREF_F_RSA_BN2BIN
F RSAREF_F_RSA_PRIVATE_DECRYPT
F RSAREF_F_RSA_PRIVATE_ENCRYPT
F RSAREF_F_RSA_PUBLIC_DECRYPT
F RSAREF_F_RSA_PUBLIC_ENCRYPT
#F SSL_F_CLIENT_CERTIFICATE

R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		1010
R SSL_R_SSLV3_ALERT_BAD_RECORD_MA
/* ... truncated ... */
```

### ssl/d1_lib.c

#### dtls1_ctrl() [lines 248-277]
```c
		s->version=DTLS1_VERSION;
	}

long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
	{
	int ret=0;

	switch (cmd)
		{
	case DTLS_CTRL_GET_TIMEOUT:
		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
			{
			ret = 1;
			}
		break;
	case DTLS_CTRL_HANDLE_TIMEOUT:
		ret = dtls1_handle_timeout(s);
		break;
	case DTLS_CTRL_LISTEN:
		ret = dtls1_listen(s, parg);
		break;

	default:
		ret = ssl3_ctrl(s, cmd, larg, parg);
		break;
		}
	return(ret);
	}

/*
```

### ssl/dtls1.h

#### region() [lines 45-131]
```c
 * 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).
 *
 */

#ifndef HEADER_DTLS1_H
#define HEADER_DTLS1_H

#include <openssl
/* ... truncated ... */
```

### ssl/s23_clnt.c

#### 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
/* ... 81 lin
/* ... truncated ... */
```

### ssl/s23_srvr.c

#### 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_ver
/* ... truncated ... */
```

### ssl/s2_lib.c

#### ssl2_ctrl() [lines 382-400]
```c
	s->packet_length=0;
	}

long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
	{
	int ret=0;

	switch(cmd)
		{
	case SSL_CTRL_GET_SESSION_REUSED:
		ret=s->hit;
		break;
	default:
		break;
		}
	return(ret);
	}

long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
```

#### ssl2_put_cipher_by_char() [lines 430-448]
```c
		return cp;
	}

int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
	{
	long l;

	if (p != NULL)
		{
		l=c->id;
		if ((l & 0xff000000) != 0x02000000) return(0);
		p[0]=((unsigned char)(l>>16L))&0xFF;
		p[1]=((unsigned char)(l>> 8L))&0xFF;
		p[2]=((unsigned char)(l     ))&0xFF;
		}
	return(3);
	}

int ssl2_generate_key_material(SSL *s)
```

### ssl/s3_enc.c

#### ssl3_alert_code() [lines 866-907]
```c
	return(ret);
	}

int ssl3_alert_code(int code)
	{
	switch (code)
		{
	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);
	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);
	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);
	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
	case SSL_AD_CER
/* ... truncated ... */
```

### ssl/s3_lib.c

#### ssl3_ctrl() [lines 3088-3364]
```c
	}
#endif

long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
	{
	int ret=0;

#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
	if (
#ifndef OPENSSL_NO_RSA
	    cmd == SSL_CTRL_SET_TMP_RSA ||
	    cmd == SSL_CTRL_SET_TMP_RSA_CB ||
#endif
#ifndef OPENSSL_NO_DSA
	    cmd == SSL_CTRL_SET_TMP_DH ||
	    cmd == SSL_CTRL_SET_TMP_DH_CB ||
#endif
		0)
		{
		if (!ssl_cert_inst(&s->cert))
		    	{
			SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
			return(0);
			}
		}
#endif

	switch (cmd)
		{
	case SSL_CTRL_GET_SESSION_REUSED:
		ret=s->hit;
		break;
	case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
		break;
	case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
		ret=s->s3->num_renegotiations;
		break;
	case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
		ret=s->s3->nu
/* ... truncated ... */
```

### ssl/ssl.h

#### region() [lines 618-704]
```c
 * zap so we have some more flags.
 */
/* The next flag deliberately changes the ciphertest, this is a check
 * for the PKCS#1 attack */
#define SSL_OP_PKCS1_CHECK_1				0x0
#define SSL_OP_PKCS1_CHECK_2				0x0

#define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
/* Make server add server-hello extension from early version of
 * cryptopro draft, when GOST ciphersuite is negotiated.
 * Required for interoperability with CryptoPro CSP 3.x
 */
#define SSL_OP_CRYPTOPRO_TLSEXT_BUG			0x80000000L

/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
 * when just a single record has been written): */
#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
/* Make it possib
/* ... truncated ... */
```

### ssl/ssl3.h

#### region() [lines 89-178]
```c
 *    "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,
 * STRI
/* ... truncated ... */
```

### ssl/ssl_err.c

#### region() [lines 344-430]
```c
{ERR_REASON(SSL_R_CA_DN_TOO_LONG)        ,"ca dn too long"},
{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY)    ,"ccs received early"},
{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH)  ,"cert length mismatch"},
{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT)    ,"clienthello tlsext"},
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
{ERR_REASON(SSL_R_COMPRESSION_DISABLED)  ,"compressio
/* ... truncated ... */
```

### ssl/ssl_lib.c

#### ssl_cipher_list_to_bytes() [lines 1375-1436]
```c
	return(buf);
	}

int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
			     int (*put_cb)(const SSL_CIPHER *, unsigned char *))
	{
	int i,j=0;
	SSL_CIPHER *c;
	unsigned char *q;
#ifndef OPENSSL_NO_KRB5
	int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
#endif /* OPENSSL_NO_KRB5 */

	if (sk == NULL) return(0);
	q=p;

	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
		{
		c=sk_SSL_CIPHER_value(sk,i);
		/* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
		if ((c->algorithm_ssl & SSL_TLSV1_2) &&
			(TLS1_get_client_version(s) < TLS1_2_VERSION))
			continue;
#ifndef OPENSSL_NO_KRB5
		if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
		    nokrb5)
		    continue;
#endif /* O
/* ... truncated ... */
```

### ssl/t1_enc.c

#### tls1_alert_code() [lines 1207-1251]
```c
	return(rv);
	}

int tls1_alert_code(int code)
	{
	switch (code)
		{
	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
	case SSL_AD_NO_CERTIFICATE:	return(-1);
	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
	case SSL_AD_CERTIFICATE_REVOKE
/* ... truncated ... */
```

### ssl/tls1.h

#### region() [lines 120-217]
```c
 * ECC cipher suite support in OpenSSL originally written by
 * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * ex
/* ... truncated ... */
```

## Upstream Fix
```diff
commit 6bfe55380abbf7528e04e59f18921bd6c896af1c
Author: Bodo Moeller <bodo@openssl.org>
Date:   Wed Oct 15 04:05:42 2014 +0200

    Support TLS_FALLBACK_SCSV.

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

Index: openssl-1.0.1i/CHANGES
===================================================================
--- openssl-1.0.1i.orig/CHANGES	2014-10-30 17:13:45.900895822 +0100
+++ openssl-1.0.1i/CHANGES	2014-10-30 17:14:58.085762986 +0100
@@ -3,6 +3,11 @@
  _______________

  Changes between 1.0.1h and 1.0.1i [6 Aug 2014]
+  *) Add support for TLS_FALLBACK_SCSV.
+     Client applications doing fallback retries should call
+     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
+     (CVE-2014-3566)
+     [Adam Langley, Bodo Moeller]

   *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
      SRP code can be overrun an internal buffer. Add sanity check that
Index: openssl-1.0.1i/apps/s_client.c
===================================================================
--- openssl-1.0.1i.orig/apps/s_client.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/apps/s_client.c	2014-10-30 17:13:45.900895822 +0100
@@ -337,6 +337,7 @@ static void sc_usage(void)
 	BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");
+	BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
 	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
 	BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
@@ -617,6 +618,7 @@ int MAIN(int argc, char **argv)
 	char *sess_out = NULL;
 	struct sockaddr peer;
 	int peerlen = sizeof(peer);
+	int fallback_scsv = 0;
 	int enable_timeouts = 0 ;
 	long socket_mtu = 0;
 #ifndef OPENSSL_NO_JPAKE
@@ -822,6 +824,10 @@ int MAIN(int argc, char **argv)
 			meth=DTLSv1_client_method();
 			socket_type=SOCK_DGRAM;
 			}
+		else if (strcmp(*argv,"-fallback_scsv") == 0)
+			{
+			fallback_scsv = 1;
+			}
 		else if (strcmp(*argv,"-timeout") == 0)
 			enable_timeouts=1;
 		else if (strcmp(*argv,"-mtu") == 0)
@@ -1241,6 +1247,10 @@ bad:
 		SSL_set_session(con, sess);
 		SSL_SESSION_free(sess);
 		}
+
+	if (fallback_scsv)
+		SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
 #ifndef OPENSSL_NO_TLSEXT
 	if (servername != NULL)
 		{
Index: openssl-1.0.1i/crypto/err/openssl.ec
===================================================================
--- openssl-1.0.1i.orig/crypto/err/openssl.ec	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/crypto/err/openssl.ec	2014-10-30 17:13:45.901895834 +0100
@@ -71,6 +71,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION
 R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
 R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
 R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
+R SSL_R_SSLV3_ALERT_INAPPROPRIATE_FALLBACK	1086
 R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
 R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
 R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
Index: openssl-1.0.1i/ssl/d1_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/d1_lib.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/d1_lib.c	2014-10-30 17:13:45.901895834 +0100
@@ -265,6 +265,16 @@ long dtls1_ctrl(SSL *s, int cmd, long la
 	case DTLS_CTRL_LISTEN:
 		ret = dtls1_listen(s, parg);
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+#if DTLS_MAX_VERSION != DTLS1_VERSION
+#  error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
+#endif
+		/* Just one protocol version is supported so far;
+		 * fail closed if the version is not as expected. */
+		return s->version == DTLS_MAX_VERSION;

 	default:
 		ret = ssl3_ctrl(s, cmd, larg, parg);
Index: openssl-1.0.1i/ssl/dtls1.h
===================================================================
--- openssl-1.0.1i.orig/ssl/dtls1.h	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/dtls1.h	2014-10-30 17:13:45.901895834 +0100
@@ -84,6 +84,8 @@ extern "C" {
 #endif

 #define DTLS1_VERSION			0xFEFF
+#define DTLS_MAX_VERSION		DTLS1_VERSION
+
 #define DTLS1_BAD_VER			0x0100

 #if 0
@@ -284,4 +286,3 @@ typedef struct dtls1_record_data_st
 }
 #endif
 #endif
-
Index: openssl-1.0.1i/ssl/s23_clnt.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_clnt.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/s23_clnt.c	2014-10-30 17:13:45.901895834 +0100
@@ -736,6 +736,9 @@ static int ssl23_get_server_hello(SSL *s
 			goto err;
 			}

+		/* ensure that TLS_MAX_VERSION is up-to-date */
+		OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
 			/* fatal alert */
Index: openssl-1.0.1i/ssl/s23_srvr.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_srvr.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s23_srvr.c	2014-10-30 17:13:45.901895834 +0100
@@ -421,6 +421,9 @@ static int ssl23_get_client_hello(SSL *s
 			}
 		}

+	/* ensure that TLS_MAX_VERSION is up-to-date */
+	OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 #ifdef OPENSSL_FIPS
 	if (FIPS_mode() && (s->version < TLS1_VERSION))
 		{
Index: openssl-1.0.1i/ssl/s2_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s2_lib.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s2_lib.c	2014-10-30 17:13:45.901895834 +0100
@@ -390,6 +390,8 @@ long ssl2_ctrl(SSL *s, int cmd, long lar
 	case SSL_CTRL_GET_SESSION_REUSED:
 		ret=s->hit;
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
 	default:
 		break;
 		}
@@ -436,7 +438,7 @@ int ssl2_put_cipher_by_char(const SSL_CI
 	if (p != NULL)
 		{
 		l=c->id;
-		if ((l & 0xff000000) != 0x02000000) return(0);
+		if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
 		p[0]=((unsigned char)(l>>16L))&0xFF;
 		p[1]=((unsigned char)(l>> 8L))&0xFF;
 		p[2]=((unsigned char)(l     ))&0xFF;
Index: openssl-1.0.1i/ssl/s3_enc.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s3_enc.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s3_enc.c	2014-10-30 17:13:45.901895834 +0100
@@ -900,7 +900,7 @@ int ssl3_alert_code(int code)
 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
 	default:			return(-1);
 		}
 	}
-
Index: openssl-1.0.1i/ssl/s3_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s3_lib.c	2014-10-30 17:13:43.389865657 +0100
+++ openssl-1.0.1i/ssl/s3_lib.c	2014-10-30 17:13:45.902895846 +0100
@@ -3354,6 +3354,33 @@ long ssl3_ctrl(SSL *s, int cmd, long lar
 #endif

 #endif /* !OPENSSL_NO_TLSEXT */
+
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+		if (s->version == s->ctx->method->version)
+			return 1;
+		/* Apparently we're using a version-flexible SSL_METHOD
+		 * (not at its highest protocol version). */
+		if (s->ctx->method->version == SSLv23_method()->version)
+			{
+#if TLS_MAX_VERSION != TLS1_2_VERSION
+#  error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
+#endif
+			if (!(s->options & SSL_OP_NO_TLSv1_2))
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 6bfe55380abbf7528e04e59f18921bd6c896af1c
Author: Bodo Moeller <bodo@openssl.org>
Date:   Wed Oct 15 04:05:42 2014 +0200

    Support TLS_FALLBACK_SCSV.

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

Index: openssl-1.0.1i/CHANGES
===================================================================
--- openssl-1.0.1i.orig/CHANGES	2014-10-30 17:13:45.900895822 +0100
+++ openssl-1.0.1i/CHANGES	2014-10-30 17:14:58.085762986 +0100
@@ -3,6 +3,11 @@
  _______________

  Changes between 1.0.1h and 1.0.1i [6 Aug 2014]
+  *) Add support for TLS_FALLBACK_SCSV.
+     Client applications doing fallback retries should call
+     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
+     (CVE-2014-3566)
+     [Adam Langley, Bodo Moeller]

   *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
      SRP code can be overrun an internal buffer. Add sanity check that
Index: openssl-1.0.1i/apps/s_client.c
===================================================================
--- openssl-1.0.1i.orig/apps/s_client.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/apps/s_client.c	2014-10-30 17:13:45.900895822 +0100
@@ -337,6 +337,7 @@ static void sc_usage(void)
 	BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");
+	BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
 	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
 	BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
@@ -617,6 +618,7 @@ int MAIN(int argc, char **argv)
 	char *sess_out = NULL;
 	struct sockaddr peer;
 	int peerlen = sizeof(peer);
+	int fallback_scsv = 0;
 	int enable_timeouts = 0 ;
 	long socket_mtu = 0;
 #ifndef OPENSSL_NO_JPAKE
@@ -822,6 +824,10 @@ int MAIN(int argc, char **argv)
 			meth=DTLSv1_client_method();
 			socket_type=SOCK_DGRAM;
 			}
+		else if (strcmp(*argv,"-fallback_scsv") == 0)
+			{
+			fallback_scsv = 1;
+			}
 		else if (strcmp(*argv,"-timeout") == 0)
 			enable_timeouts=1;
 		else if (strcmp(*argv,"-mtu") == 0)
@@ -1241,6 +1247,10 @@ bad:
 		SSL_set_session(con, sess);
 		SSL_SESSION_free(sess);
 		}
+
+	if (fallback_scsv)
+		SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
 #ifndef OPENSSL_NO_TLSEXT
 	if (servername != NULL)
 		{
Index: openssl-1.0.1i/crypto/err/openssl.ec
===================================================================
--- openssl-1.0.1i.orig/crypto/err/openssl.ec	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/crypto/err/openssl.ec	2014-10-30 17:13:45.901895834 +0100
@@ -71,6 +71,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION
 R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
 R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
 R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
+R SSL_R_SSLV3_ALERT_INAPPROPRIATE_FALLBACK	1086
 R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
 R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
 R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
Index: openssl-1.0.1i/ssl/d1_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/d1_lib.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/d1_lib.c	2014-10-30 17:13:45.901895834 +0100
@@ -265,6 +265,16 @@ long dtls1_ctrl(SSL *s, int cmd, long la
 	case DTLS_CTRL_LISTEN:
 		ret = dtls1_listen(s, parg);
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+#if DTLS_MAX_VERSION != DTLS1_VERSION
+#  error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
+#endif
+		/* Just one protocol version is supported so far;
+		 * fail closed if the version is not as expected. */
+		return s->version == DTLS_MAX_VERSION;

 	default:
 		ret = ssl3_ctrl(s, cmd, larg, parg);
Index: openssl-1.0.1i/ssl/dtls1.h
===================================================================
--- openssl-1.0.1i.orig/ssl/dtls1.h	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/dtls1.h	2014-10-30 17:13:45.901895834 +0100
@@ -84,6 +84,8 @@ extern "C" {
 #endif

 #define DTLS1_VERSION			0xFEFF
+#define DTLS_MAX_VERSION		DTLS1_VERSION
+
 #define DTLS1_BAD_VER			0x0100

 #if 0
@@ -284,4 +286,3 @@ typedef struct dtls1_record_data_st
 }
 #endif
 #endif
-
Index: openssl-1.0.1i/ssl/s23_clnt.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_clnt.c	2014-10-30 17:13:43.387865632 +0100
+++ openssl-1.0.1i/ssl/s23_clnt.c	2014-10-30 17:13:45.901895834 +0100
@@ -736,6 +736,9 @@ static int ssl23_get_server_hello(SSL *s
 			goto err;
 			}

+		/* ensure that TLS_MAX_VERSION is up-to-date */
+		OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
 			/* fatal alert */
Index: openssl-1.0.1i/ssl/s23_srvr.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s23_srvr.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s23_srvr.c	2014-10-30 17:13:45.901895834 +0100
@@ -421,6 +421,9 @@ static int ssl23_get_client_hello(SSL *s
 			}
 		}

+	/* ensure that TLS_MAX_VERSION is up-to-date */
+	OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 #ifdef OPENSSL_FIPS
 	if (FIPS_mode() && (s->version < TLS1_VERSION))
 		{
Index: openssl-1.0.1i/ssl/s2_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s2_lib.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s2_lib.c	2014-10-30 17:13:45.901895834 +0100
@@ -390,6 +390,8 @@ long ssl2_ctrl(SSL *s, int cmd, long lar
 	case SSL_CTRL_GET_SESSION_REUSED:
 		ret=s->hit;
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
 	default:
 		break;
 		}
@@ -436,7 +438,7 @@ int ssl2_put_cipher_by_char(const SSL_CI
 	if (p != NULL)
 		{
 		l=c->id;
-		if ((l & 0xff000000) != 0x02000000) return(0);
+		if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
 		p[0]=((unsigned char)(l>>16L))&0xFF;
 		p[1]=((unsigned char)(l>> 8L))&0xFF;
 		p[2]=((unsigned char)(l     ))&0xFF;
Index: openssl-1.0.1i/ssl/s3_enc.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s3_enc.c	2014-10-30 17:13:43.388865644 +0100
+++ openssl-1.0.1i/ssl/s3_enc.c	2014-10-30 17:13:45.901895834 +0100
@@ -900,7 +900,7 @@ int ssl3_alert_code(int code)
 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
 	default:			return(-1);
 		}
 	}
-
Index: openssl-1.0.1i/ssl/s3_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s3_lib.c	2014-10-30 17:13:43.389865657 +0100
+++ openssl-1.0.1i/ssl/s3_lib.c	2014-10-30 17:13:45.902895846 +0100
@@ -3354,6 +3354,33 @@ long ssl3_ctrl(SSL *s, int cmd, long lar
 #endif

 #endif /* !OPENSSL_NO_TLSEXT */
+
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+		if (s->version == s->ctx->method->version)
+			return 1;
+		/* Apparently we're using a version-flexible SSL_METHOD
+		 * (not at its highest protocol version). */
+		if (s->ctx->method->version == SSLv23_method()->version)
+			{
+#if TLS_MAX_VERSION != TLS1_2_VERSION
+#  error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
+#endif
+			if (!(s->options & SSL_OP_NO_TLSv1_2))
+				return s->version == TLS1_2_VERSION;
+			if (!(s->options & SSL_OP_NO_TLSv1_1))
+				return s->version == TLS1_1_VERSION;
+			if (!(s->options & SSL_OP_NO_TLSv1))
+				return s->version == TLS1_VERSION;
+			if (!(s->options & SSL_OP_NO_SSLv3))
+				return s->version == SSL3_VERSION;
+			if (!(s->options & SSL_OP_NO_SSLv2))
+				return s->version == SSL2_VERSION;
+			}
+		return 0; /* Unexpected state; fail closed. */
+
 	default:
 		break;
 		}
@@ -3713,6 +3740,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx
 		break;
 #endif
 #endif
+
 	default:
 		return(0);
 		}
@@ -4290,4 +4318,3 @@ long ssl_get_algorithm2(SSL *s)
 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
 	return alg2;
 	}
-
Index: openssl-1.0.1i/ssl/ssl.h
===================================================================
--- openssl-1.0.1i.orig/ssl/ssl.h	2014-10-30 17:13:43.390865668 +0100
+++ openssl-1.0.1i/ssl/ssl.h	2014-10-30 17:13:45.902895846 +0100
@@ -657,6 +657,10 @@ struct ssl_session_st
  */
 #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
 #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
+/* Send TLS_FALLBACK_SCSV in the ClientHello.
+ * To be set by applications that reconnect with a downgraded protocol
+ * version; see draft-ietf-tls-downgrade-scsv-00 for details. */
+#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L

 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
  * they cannot be used to clear bits. */
@@ -1515,6 +1519,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
 #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
 #define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
+#define SSL_AD_INAPPROPRIATE_FALLBACK	TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */

 #define SSL_ERROR_NONE			0
 #define SSL_ERROR_SSL			1
@@ -1625,6 +1630,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS		82
 #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS	83

+#define SSL_CTRL_CHECK_PROTO_VERSION		119
+
 #define DTLSv1_get_timeout(ssl, arg) \
 	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
 #define DTLSv1_handle_timeout(ssl) \
@@ -2383,6 +2390,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_HTTPS_PROXY_REQUEST			 155
 #define SSL_R_HTTP_REQUEST				 156
 #define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INAPPROPRIATE_FALLBACK			 373
 #define SSL_R_INCONSISTENT_COMPRESSION			 340
 #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
 #define SSL_R_INVALID_COMMAND				 280
@@ -2529,6 +2537,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
 #define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
 #define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
+#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK	 1086
 #define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
 #define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
 #define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
Index: openssl-1.0.1i/ssl/ssl3.h
===================================================================
--- openssl-1.0.1i.orig/ssl/ssl3.h	2014-10-30 17:13:43.390865668 +0100
+++ openssl-1.0.1i/ssl/ssl3.h	2014-10-30 17:13:45.903895858 +0100
@@ -128,9 +128,14 @@
 extern "C" {
 #endif

-/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
+/* Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
 #define SSL3_CK_SCSV				0x030000FF

+/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV) */
+#define SSL3_CK_FALLBACK_SCSV			0x03005600
+
 #define SSL3_CK_RSA_NULL_MD5			0x03000001
 #define SSL3_CK_RSA_NULL_SHA			0x03000002
 #define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
Index: openssl-1.0.1i/ssl/ssl_err.c
===================================================================
--- openssl-1.0.1i.orig/ssl/ssl_err.c	2014-10-30 17:13:43.390865668 +0100
+++ openssl-1.0.1i/ssl/ssl_err.c	2014-10-30 17:13:45.903895858 +0100
@@ -383,6 +383,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
 {ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
 {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"},
 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
 {ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
@@ -529,6 +530,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},
Index: openssl-1.0.1i/ssl/ssl_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/ssl_lib.c	2014-10-30 17:13:43.392865692 +0100
+++ openssl-1.0.1i/ssl/ssl_lib.c	2014-10-30 17:13:45.903895858 +0100
@@ -1386,6 +1386,8 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC

 	if (sk == NULL) return(0);
 	q=p;
+	if (put_cb == NULL)
+		put_cb = s->method->put_cipher_by_char;

 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 		{
@@ -1410,24 +1412,36 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC
 		    !(s->srp_ctx.srp_Mask & SSL_kSRP))
 		    continue;
 #endif /* OPENSSL_NO_SRP */
-		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
+		j = put_cb(c,p);
 		p+=j;
 		}
-	/* If p == q, no ciphers and caller indicates an error. Otherwise
-	 * add SCSV if not renegotiating.
-	 */
-	if (p != q && !s->renegotiate)
+	/* If p == q, no ciphers; caller indicates an error.
+	 * Otherwise, add applicable SCSVs. */
+	if (p != q)
 		{
-		static SSL_CIPHER scsv =
+		if (!s->renegotiate)
 			{
-			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
-			};
-		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
-		p+=j;
+			static SSL_CIPHER scsv =
+				{
+				0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+				};
+			j = put_cb(&scsv,p);
+			p+=j;
 #ifdef OPENSSL_RI_DEBUG
-		fprintf(stderr, "SCSV sent by client\n");
+			fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
 #endif
-		}
+			}
+
+		if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
+			{
+			static SSL_CIPHER scsv =
+				{
+				0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+				};
+			j = put_cb(&scsv,p);
+			p+=j;
+			}
+ 		}

 	return(p-q);
 	}
@@ -1438,11 +1452,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
 	const SSL_CIPHER *c;
 	STACK_OF(SSL_CIPHER) *sk;
 	int i,n;
+
 	if (s->s3)
 		s->s3->send_connection_binding = 0;

 	n=ssl_put_cipher_by_char(s,NULL,NULL);
-	if ((num%n) != 0)
+	if (n == 0 || (num%n) != 0)
 		{
 		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
 		return(NULL);
@@ -1457,7 +1472,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe

 	for (i=0; i<num; i+=n)
 		{
-		/* Check for SCSV */
+		/* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
 		if (s->s3 && (n != 3 || !p[0]) &&
 			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
 			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
@@ -1477,6 +1492,23 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
 			continue;
 			}

+		/* Check for TLS_FALLBACK_SCSV */
+		if ((n != 3 || !p[0]) &&
+			(p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+			(p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff)))
+			{
+			/* The SCSV indicates that the client previously tried a higher version.
+			 * Fail if the current version is an unexpected downgrade. */
+			if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL))
+				{
+				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK);
+				if (s->s3)
+					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
+				goto err;
+				}
+			continue;
+			}
+
 		c=ssl_get_cipher_by_char(s,p);
 		p+=n;
 		if (c != NULL)
Index: openssl-1.0.1i/ssl/t1_enc.c
===================================================================
--- openssl-1.0.1i.orig/ssl/t1_enc.c	2014-10-30 17:13:43.392865692 +0100
+++ openssl-1.0.1i/ssl/t1_enc.c	2014-10-30 17:13:45.903895858 +0100
@@ -1262,6 +1262,7 @@ int tls1_alert_code(int code)
 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
 #if 0 /* not appropriate for TLS, not used for DTLS */
 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
Index: openssl-1.0.1i/ssl/tls1.h
===================================================================
--- openssl-1.0.1i.orig/ssl/tls1.h	2014-10-30 17:13:43.392865692 +0100
+++ openssl-1.0.1i/ssl/tls1.h	2014-10-30 17:13:45.904895870 +0100
@@ -159,17 +159,19 @@ extern "C" {

 #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0

+#define TLS1_VERSION			0x0301
+#define TLS1_1_VERSION			0x0302
 #define TLS1_2_VERSION			0x0303
-#define TLS1_2_VERSION_MAJOR		0x03
-#define TLS1_2_VERSION_MINOR		0x03
+#define TLS_MAX_VERSION			TLS1_2_VERSION
+
+#define TLS1_VERSION_MAJOR		0x03
+#define TLS1_VERSION_MINOR		0x01

-#define TLS1_1_VERSION			0x0302
 #define TLS1_1_VERSION_MAJOR		0x03
 #define TLS1_1_VERSION_MINOR		0x02

-#define TLS1_VERSION			0x0301
-#define TLS1_VERSION_MAJOR		0x03
-#define TLS1_VERSION_MINOR		0x01
+#define TLS1_2_VERSION_MAJOR		0x03
+#define TLS1_2_VERSION_MINOR		0x03

 #define TLS1_get_version(s) \
 		((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
@@ -187,6 +189,7 @@ extern "C" {
 #define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
 #define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
 #define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
+#define TLS1_AD_INAPPROPRIATE_FALLBACK	86	/* fatal */
 #define TLS1_AD_USER_CANCELLED		90
 #define TLS1_AD_NO_RENEGOTIATION	100
 /* codes 110-114 are from RFC3546 */


[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-2012-1798

The TIFFGetEXIFProperties function in coders/tiff.c in ImageMagick before 6.7.6-3 allows remote attackers to cause a denial of service (out-of-bounds read and crash) via a crafted EXIF IFD in a TIFF image.

## Package
ImageMagick

## Files to modify
- magick/profile.c
- ImageMagick-6.6.5-8.orig/magick/property.c
- ImageMagick-6.6.5-8.orig/magick/profile.c
- magick/property.c

## Upstream Fix
```diff
http://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=20286 (note the date of announcement in contrast with date of patch)
Index: ImageMagick-6.6.5-8/magick/profile.c
===================================================================
--- ImageMagick-6.6.5-8.orig/magick/profile.c
+++ ImageMagick-6.6.5-8/magick/profile.c
@@ -1827,12 +1827,13 @@ MagickExport MagickBooleanType SyncImage
   EndianType
     endian;

-  int
-    offset;
+  SplayTreeInfo
+    *exif_resources;

   ssize_t
     id,
-    level;
+    level,
+    offset;

   size_t
     entry,
@@ -1889,12 +1890,14 @@ MagickExport MagickBooleanType SyncImage
   /*
     This the offset to the first IFD.
   */
-  offset=(int) ReadProfileLong(endian,exif+4);
-  if ((size_t) offset >= length)
+  offset=(ssize_t) ((int) ReadProfileLong(endian,exif+4));
+  if ((offset < 0) || ((size_t) offset >= length))
     return(MagickFalse);
   directory=exif+offset;
   level=0;
   entry=0;
+  exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+    (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
   do
   {
     if (level > 0)
@@ -1924,6 +1927,9 @@ MagickExport MagickBooleanType SyncImage
         number_bytes;

       q=(unsigned char *) (directory+2+(12*entry));
+      if (GetValueFromSplayTree(exif_resources,q) == q)
+        break;
+      (void) AddValueToSplayTree(exif_resources,q,q);
       tag_value=(ssize_t) ReadProfileShort(endian,q);
       format=(ssize_t) ReadProfileShort(endian,q+2);
       if ((format-1) >= EXIF_NUM_FORMATS)
@@ -1934,13 +1940,15 @@ MagickExport MagickBooleanType SyncImage
         p=q+8;
       else
         {
-          int
+          ssize_t
             offset;

           /*
             The directory entry contains an offset.
           */
-          offset=(int) ReadProfileLong(endian,q+8);
+          offset=(ssize_t) ((int) ReadProfileLong(endian,q+8));
+          if ((offset+number_bytes) < offset)
+            continue;  /* prevent overflow */
           if ((size_t) (offset+number_bytes) > length)
             continue;
           p=(unsigned char *) (exif+offset);
@@ -1949,28 +1957,25 @@ MagickExport MagickBooleanType SyncImage
       {
         case 0x011a:
         {
-          (void) WriteProfileLong(endian,(size_t)
-            (image->x_resolution+0.5),p);
+          (void) WriteProfileLong(endian,(size_t) (image->x_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;
         }
         case 0x011b:
         {
-          (void) WriteProfileLong(endian,(size_t)
-            (image->y_resolution+0.5),p);
+          (void) WriteProfileLong(endian,(size_t) (image->y_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;
         }
         case 0x0112:
         {
-          (void) WriteProfileShort(endian,(unsigned short)
-            image->orientation,p);
+          (void) WriteProfileShort(endian,(unsigned short) image->orientation,
+            p);
           break;
         }
         case 0x0128:
         {
-          (void) WriteProfileShort(endian,(unsigned short)
-            (image->units+1),p);
+          (void) WriteProfileShort(endian,(unsigned short) (image->units+1),p);
           break;
         }
         default:
@@ -1978,11 +1983,11 @@ MagickExport MagickBooleanType SyncImage
       }
       if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
         {
-          size_t
+          ssize_t
             offset;

-          offset=(size_t) ReadProfileLong(endian,p);
-          if ((offset < length) && (level < (MaxDirectoryStack-2)))
+          offset=(ssize_t) ((int) ReadProfileLong(endian,p));
+          if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
             {
               directory_stack[level].directory=directory;
               entry++;
@@ -1993,9 +1998,9 @@ MagickExport MagickBooleanType SyncImage
               level++;
               if ((directory+2+(12*number_entries)) > (exif+length))
                 break;
-              offset=(size_t) ReadProfileLong(endian,directory+2+(12*
-                number_entries));
-              if ((offset != 0) && (offset < length) &&
+              offset=(ssize_t) ((int) ReadProfileLong(endian,directory+2+(12*
+                number_entries)));
+              if ((offset != 0) && ((size_t) offset < length) &&
                   (level < (MaxDirectoryStack-2)))
                 {
                   directory_stack[level].directory=exif+offset;
@@ -2007,5 +2012,6 @@ MagickExport MagickBooleanType SyncImage
         }
     }
   } while (level > 0);
+  exif_resources=DestroySplayTree(exif_resources);
   return(MagickTrue);
 }
Index: ImageMagick-6.6.5-8/magick/property.c
===================================================================
--- ImageMagick-6.6.5-8.orig/magick/property.c
+++ ImageMagick-6.6.5-8/magick/property.c
@@ -459,6 +459,13 @@ static inline ssize_t MagickMax(const ss
   return(y);
 }

+static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
+{
+  if (x < y)
+    return(x);
+  return(y);
+}
+
 static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
 {
   int
@@ -593,7 +600,7 @@ static MagickBooleanType Get8BIMProperty
       continue;
     if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
       continue;
-    id=(ssize_t) ReadPropertyMSBShort(&info,&length);
+    id=(ssize_t) ((int) ReadPropertyMSBShort(&info,&length));
     if (id < (ssize_t) start)
       continue;
     if (id > (ssize_t) stop)
@@ -624,7 +631,7 @@ static MagickBooleanType Get8BIMProperty
             No name match, scroll forward and try next.
           */
           info+=count;
-          length-=count;
+          length-=MagickMin(count,(ssize_t) length);
           continue;
         }
     if ((*name == '#') && (sub_number != 1))
@@ -634,7 +641,7 @@ static MagickBooleanType Get8BIMProperty
         */
         sub_number--;
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         continue;
       }
     /*
@@ -649,7 +656,7 @@ static MagickBooleanType Get8BIMProperty
         (void) CopyMagickMemory(attribute,(char *) info,(size_t) count);
         attribute[count]='\0';
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         if ((id <= 1999) || (id >= 2999))
           (void) SetImageProperty((Image *) image,key,(const char *)
             attribute);
@@ -789,7 +796,9 @@ static MagickBooleanType GetEXIFProperty
       *directory;

     size_t
-      entry,
+      entry;
+
+    ssize_t
       offset;
   } DirectoryInfo;

@@ -1095,6 +1104,7 @@ static MagickBooleanType GetEXIFProperty
     all,
     id,
     level,
+    tag_offset,
     tag_value;

   register ssize_t
@@ -1112,9 +1122,11 @@ static MagickBooleanType GetEXIFProperty
   size_t
     entry,
     number_entries,
-    tag_offset,
     tag;

+  SplayTreeInfo
+    *exif_resources;
+
   /*
     If EXIF data exists, then try to parse the request for a tag.
   */
@@ -1225,7 +1237,7 @@ static MagickBooleanType GetEXIFProperty
   }
   if (length < 16)
     return(MagickFalse);
-  id=(ssize_t) ReadPropertyShort(LSBEndian,exif);
+  id=(ssize_t) ((int) ReadPropertyShort(LSBEndian,exif));
   endian=LSBEndian;
   if (id == 0x4949)
     endian=LSBEndian;
@@ -1240,7 +1252,7 @@ static MagickBooleanType GetEXIFProperty
     This the offset to the first IFD.
   */
   offset=(int) ReadPropertyLong(endian,exif+4);
-  if ((size_t) offset >= length)
+  if ((offset < 0) || (size_t) offset >= length)
     return(MagickFalse);
   /*
     Set the pointer to the first IFD and follow it were it leads.
@@ -1249,6 +1261,8 @@ static MagickBooleanType GetEXIFProperty
   level=0;
   entry=0;
   tag_offset=0;
+  exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+    (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
   do
   {
     /*
@@ -1264,7 +1278,7 @@ static MagickBool
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
http://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=20286 (note the date of announcement in contrast with date of patch)
Index: ImageMagick-6.6.5-8/magick/profile.c
===================================================================
--- ImageMagick-6.6.5-8.orig/magick/profile.c
+++ ImageMagick-6.6.5-8/magick/profile.c
@@ -1827,12 +1827,13 @@ MagickExport MagickBooleanType SyncImage
   EndianType
     endian;

-  int
-    offset;
+  SplayTreeInfo
+    *exif_resources;

   ssize_t
     id,
-    level;
+    level,
+    offset;

   size_t
     entry,
@@ -1889,12 +1890,14 @@ MagickExport MagickBooleanType SyncImage
   /*
     This the offset to the first IFD.
   */
-  offset=(int) ReadProfileLong(endian,exif+4);
-  if ((size_t) offset >= length)
+  offset=(ssize_t) ((int) ReadProfileLong(endian,exif+4));
+  if ((offset < 0) || ((size_t) offset >= length))
     return(MagickFalse);
   directory=exif+offset;
   level=0;
   entry=0;
+  exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+    (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
   do
   {
     if (level > 0)
@@ -1924,6 +1927,9 @@ MagickExport MagickBooleanType SyncImage
         number_bytes;

       q=(unsigned char *) (directory+2+(12*entry));
+      if (GetValueFromSplayTree(exif_resources,q) == q)
+        break;
+      (void) AddValueToSplayTree(exif_resources,q,q);
       tag_value=(ssize_t) ReadProfileShort(endian,q);
       format=(ssize_t) ReadProfileShort(endian,q+2);
       if ((format-1) >= EXIF_NUM_FORMATS)
@@ -1934,13 +1940,15 @@ MagickExport MagickBooleanType SyncImage
         p=q+8;
       else
         {
-          int
+          ssize_t
             offset;

           /*
             The directory entry contains an offset.
           */
-          offset=(int) ReadProfileLong(endian,q+8);
+          offset=(ssize_t) ((int) ReadProfileLong(endian,q+8));
+          if ((offset+number_bytes) < offset)
+            continue;  /* prevent overflow */
           if ((size_t) (offset+number_bytes) > length)
             continue;
           p=(unsigned char *) (exif+offset);
@@ -1949,28 +1957,25 @@ MagickExport MagickBooleanType SyncImage
       {
         case 0x011a:
         {
-          (void) WriteProfileLong(endian,(size_t)
-            (image->x_resolution+0.5),p);
+          (void) WriteProfileLong(endian,(size_t) (image->x_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;
         }
         case 0x011b:
         {
-          (void) WriteProfileLong(endian,(size_t)
-            (image->y_resolution+0.5),p);
+          (void) WriteProfileLong(endian,(size_t) (image->y_resolution+0.5),p);
           (void) WriteProfileLong(endian,1UL,p+4);
           break;
         }
         case 0x0112:
         {
-          (void) WriteProfileShort(endian,(unsigned short)
-            image->orientation,p);
+          (void) WriteProfileShort(endian,(unsigned short) image->orientation,
+            p);
           break;
         }
         case 0x0128:
         {
-          (void) WriteProfileShort(endian,(unsigned short)
-            (image->units+1),p);
+          (void) WriteProfileShort(endian,(unsigned short) (image->units+1),p);
           break;
         }
         default:
@@ -1978,11 +1983,11 @@ MagickExport MagickBooleanType SyncImage
       }
       if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
         {
-          size_t
+          ssize_t
             offset;

-          offset=(size_t) ReadProfileLong(endian,p);
-          if ((offset < length) && (level < (MaxDirectoryStack-2)))
+          offset=(ssize_t) ((int) ReadProfileLong(endian,p));
+          if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
             {
               directory_stack[level].directory=directory;
               entry++;
@@ -1993,9 +1998,9 @@ MagickExport MagickBooleanType SyncImage
               level++;
               if ((directory+2+(12*number_entries)) > (exif+length))
                 break;
-              offset=(size_t) ReadProfileLong(endian,directory+2+(12*
-                number_entries));
-              if ((offset != 0) && (offset < length) &&
+              offset=(ssize_t) ((int) ReadProfileLong(endian,directory+2+(12*
+                number_entries)));
+              if ((offset != 0) && ((size_t) offset < length) &&
                   (level < (MaxDirectoryStack-2)))
                 {
                   directory_stack[level].directory=exif+offset;
@@ -2007,5 +2012,6 @@ MagickExport MagickBooleanType SyncImage
         }
     }
   } while (level > 0);
+  exif_resources=DestroySplayTree(exif_resources);
   return(MagickTrue);
 }
Index: ImageMagick-6.6.5-8/magick/property.c
===================================================================
--- ImageMagick-6.6.5-8.orig/magick/property.c
+++ ImageMagick-6.6.5-8/magick/property.c
@@ -459,6 +459,13 @@ static inline ssize_t MagickMax(const ss
   return(y);
 }

+static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
+{
+  if (x < y)
+    return(x);
+  return(y);
+}
+
 static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
 {
   int
@@ -593,7 +600,7 @@ static MagickBooleanType Get8BIMProperty
       continue;
     if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
       continue;
-    id=(ssize_t) ReadPropertyMSBShort(&info,&length);
+    id=(ssize_t) ((int) ReadPropertyMSBShort(&info,&length));
     if (id < (ssize_t) start)
       continue;
     if (id > (ssize_t) stop)
@@ -624,7 +631,7 @@ static MagickBooleanType Get8BIMProperty
             No name match, scroll forward and try next.
           */
           info+=count;
-          length-=count;
+          length-=MagickMin(count,(ssize_t) length);
           continue;
         }
     if ((*name == '#') && (sub_number != 1))
@@ -634,7 +641,7 @@ static MagickBooleanType Get8BIMProperty
         */
         sub_number--;
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         continue;
       }
     /*
@@ -649,7 +656,7 @@ static MagickBooleanType Get8BIMProperty
         (void) CopyMagickMemory(attribute,(char *) info,(size_t) count);
         attribute[count]='\0';
         info+=count;
-        length-=count;
+        length-=MagickMin(count,(ssize_t) length);
         if ((id <= 1999) || (id >= 2999))
           (void) SetImageProperty((Image *) image,key,(const char *)
             attribute);
@@ -789,7 +796,9 @@ static MagickBooleanType GetEXIFProperty
       *directory;

     size_t
-      entry,
+      entry;
+
+    ssize_t
       offset;
   } DirectoryInfo;

@@ -1095,6 +1104,7 @@ static MagickBooleanType GetEXIFProperty
     all,
     id,
     level,
+    tag_offset,
     tag_value;

   register ssize_t
@@ -1112,9 +1122,11 @@ static MagickBooleanType GetEXIFProperty
   size_t
     entry,
     number_entries,
-    tag_offset,
     tag;

+  SplayTreeInfo
+    *exif_resources;
+
   /*
     If EXIF data exists, then try to parse the request for a tag.
   */
@@ -1225,7 +1237,7 @@ static MagickBooleanType GetEXIFProperty
   }
   if (length < 16)
     return(MagickFalse);
-  id=(ssize_t) ReadPropertyShort(LSBEndian,exif);
+  id=(ssize_t) ((int) ReadPropertyShort(LSBEndian,exif));
   endian=LSBEndian;
   if (id == 0x4949)
     endian=LSBEndian;
@@ -1240,7 +1252,7 @@ static MagickBooleanType GetEXIFProperty
     This the offset to the first IFD.
   */
   offset=(int) ReadPropertyLong(endian,exif+4);
-  if ((size_t) offset >= length)
+  if ((offset < 0) || (size_t) offset >= length)
     return(MagickFalse);
   /*
     Set the pointer to the first IFD and follow it were it leads.
@@ -1249,6 +1261,8 @@ static MagickBooleanType GetEXIFProperty
   level=0;
   entry=0;
   tag_offset=0;
+  exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+    (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
   do
   {
     /*
@@ -1264,7 +1278,7 @@ static MagickBooleanType GetEXIFProperty
     /*
       Determine how many entries there are in the current IFD.
     */
-    number_entries=ReadPropertyShort(endian,directory);
+    number_entries=(size_t) ((int) ReadPropertyShort(endian,directory));
     for ( ; entry < number_entries; entry++)
     {
       ssize_t
@@ -1280,9 +1294,12 @@ static MagickBooleanType GetEXIFProperty
       size_t
         format;

-      q=(unsigned char *) (directory+2+(12*entry));
-      tag_value=(ssize_t) (ReadPropertyShort(endian,q)+tag_offset);
-      format=(size_t) ReadPropertyShort(endian,q+2);
+      q=(unsigned char *) (directory+(12*entry)+2);
+      if (GetValueFromSplayTree(exif_resources,q) == q)
+        break;
+      (void) AddValueToSplayTree(exif_resources,q,q);
+      tag_value=(ssize_t) ((int) ReadPropertyShort(endian,q)+tag_offset);
+      format=(size_t) ((int) ReadPropertyShort(endian,q+2));
       if (format >= (sizeof(tag_bytes)/sizeof(*tag_bytes)))
         break;
       components=(int) ReadPropertyLong(endian,q+4);
@@ -1298,6 +1315,8 @@ static MagickBooleanType GetEXIFProperty
             The directory entry contains an offset.
           */
           offset=(int) ReadPropertyLong(endian,q+8);
+          if ((offset+number_bytes) < offset)
+            continue;  /* prevent overflow */
           if ((size_t) (offset+number_bytes) > length)
             continue;
           p=(unsigned char *) (exif+offset);
@@ -1335,7 +1354,7 @@ static MagickBooleanType GetEXIFProperty
             case EXIF_FMT_ULONG:
             {
               EXIFMultipleValues(4,"%.20g",(double)
-                ReadPropertyLong(endian,p1));
+                ((int) ReadPropertyLong(endian,p1)));
               break;
             }
             case EXIF_FMT_SLONG:
@@ -1347,8 +1366,8 @@ static MagickBooleanType GetEXIFProperty
             case EXIF_FMT_URATIONAL:
             {
               EXIFMultipleFractions(8,"%.20g/%.20g",(double)
-                ReadPropertyLong(endian,p1),(double)
-                ReadPropertyLong(endian,p1+4));
+                ((int) ReadPropertyLong(endian,p1)),(double)
+                ((int) ReadPropertyLong(endian,p1+4)));
               break;
             }
             case EXIF_FMT_SRATIONAL:
@@ -1449,19 +1468,19 @@ static MagickBooleanType GetEXIFProperty
             }
         }
         if ((tag_value == TAG_EXIF_OFFSET) ||
-            (tag_value == TAG_INTEROP_OFFSET) ||
-            (tag_value == TAG_GPS_OFFSET))
+            (tag_value == TAG_INTEROP_OFFSET) || (tag_value == TAG_GPS_OFFSET))
           {
-            size_t
+            ssize_t
               offset;

-            offset=(size_t) ReadPropertyLong(endian,p);
-            if ((offset < length) && (level < (MaxDirectoryStack-2)))
+            offset=(ssize_t) ((int) ReadPropertyLong(endian,p));
+            if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
               {
-                size_t
+                ssize_t
                   tag_offset1;

-                tag_offset1=(tag_value == TAG_GPS_OFFSET) ? 0x10000UL : 0UL;
+                tag_offset1=(ssize_t) ((tag_value == TAG_GPS_OFFSET) ? 0x10000 :
+                  0);
                 directory_stack[level].directory=directory;
                 entry++;
                 directory_stack[level].entry=entry;
@@ -1473,9 +1492,9 @@ static MagickBooleanType GetEXIFProperty
                 level++;
                 if ((directory+2+(12*number_entries)) > (exif+length))
                   break;
-                offset=(size_t) ReadPropertyLong(endian,directory+2+(12*
-                  number_entries));
-                if ((offset != 0) && (offset < length) &&
+                offset=(ssize_t) ((int) ReadPropertyLong(endian,directory+2+(12*
+                  number_entries)));
+                if ((offset != 0) && ((size_t) offset < length) &&
                     (level < (MaxDirectoryStack-2)))
                   {
                     directory_stack[level].directory=exif+offset;
@@ -1488,6 +1507,7 @@ static MagickBooleanType GetEXIFProperty
           }
     }
   } while (level > 0);
+  exif_resources=DestroySplayTree(exif_resources);
   return(MagickTrue);
 }

@@ -1629,7 +1649,7 @@ static char *TracePSClippath(const unsig
   in_subpath=MagickFalse;
   while (length > 0)
   {
-    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
     switch (selector)
     {
       case 0:
@@ -1638,15 +1658,15 @@ static char *TracePSClippath(const unsig
         if (knot_count != 0)
           {
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
           Expected subpath length record.
         */
-        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
         blob+=22;
-        length-=22;
+        length-=MagickMin(22,(ssize_t) length);
         break;
       }
       case 1:
@@ -1660,7 +1680,7 @@ static char *TracePSClippath(const unsig
               Unexpected subpath knot
             */
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
@@ -1672,8 +1692,8 @@ static char *TracePSClippath(const unsig
             xx,
             yy;

-          yy=ReadPropertyMSBLong(&blob,&length);
-          xx=ReadPropertyMSBLong(&blob,&length);
+          yy=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+          xx=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
           x=(ssize_t) xx;
           if (xx > 2147483647)
             x=(ssize_t) xx-4294967295-1;
@@ -1761,7 +1781,7 @@ static char *TracePSClippath(const unsig
       default:
       {
         blob+=24;
-        length-=24;
+        length-=MagickMin(24,(ssize_t) length);
         break;
       }
     }
@@ -1826,7 +1846,7 @@ static char *TraceSVGClippath(const unsi
   in_subpath=MagickFalse;
   while (length != 0)
   {
-    selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+    selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
     switch (selector)
     {
       case 0:
@@ -1835,15 +1855,15 @@ static char *TraceSVGClippath(const unsi
         if (knot_count != 0)
           {
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
           Expected subpath length record.
         */
-        knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+        knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
         blob+=22;
-        length-=22;
+        length-=MagickMin(22,(ssize_t) length);
         break;
       }
       case 1:
@@ -1857,7 +1877,7 @@ static char *TraceSVGClippath(const unsi
               Unexpected subpath knot.
             */
             blob+=24;
-            length-=24;
+            length-=MagickMin(24,(ssize_t) length);
             break;
           }
         /*
@@ -1932,7 +1952,7 @@ static char *TraceSVGClippath(const unsi
       default:
       {
         blob+=24;
-        length-=24;
+        length-=MagickMin(24,(ssize_t) length);
         break;
       }
     }


[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-1000104

A security Bypass vulnerability exists in the FcgidPassHeader Proxy in mod_fcgid through 2016-07-07.

## Package
apache2-mod_fcgid

## Files to modify
- mod_fcgid-2.3.9.orig/modules/fcgid/mod_fcgid.c
- modules/fcgid/mod_fcgid.c

## Upstream Fix
```diff
Index: mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c
===================================================================
--- mod_fcgid-2.3.9.orig/modules/fcgid/mod_fcgid.c
+++ mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c
@@ -155,9 +155,15 @@ static void fcgid_add_cgi_vars(request_r
                  * consistent with legacy mod_fcgid behavior and mod_fastcgi
                  * prior to 2.4.7
                  */
-                apr_table_setn(r->subprocess_env, *hdr, val);
-                /* standard munging of header name (upcase, HTTP_, etc.) */
-                apr_table_setn(r->subprocess_env, http2env(r->pool, *hdr), val);
+                /* boo#988492 httpoxy don't set HTTP_PROXY */
+                if ( strcasecmp(*hdr, "HTTP_PROXY") != 0 && strcasecmp(*hdr, "HTTP-PROXY") != 0) {
+                    apr_table_setn(r->subprocess_env, *hdr, val);
+                }
+                /* boo#988492 httpoxy don't set HTTP_PROXY */
+                if ( strcasecmp(*hdr, "PROXY") != 0 ) {
+                    /* standard munging of header name (upcase, HTTP_, etc.) */
+                    apr_table_setn(r->subprocess_env, http2env(r->pool, *hdr), val);
+                }
             }
         }
     }
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c
===================================================================
--- mod_fcgid-2.3.9.orig/modules/fcgid/mod_fcgid.c
+++ mod_fcgid-2.3.9/modules/fcgid/mod_fcgid.c
@@ -155,9 +155,15 @@ static void fcgid_add_cgi_vars(request_r
                  * consistent with legacy mod_fcgid behavior and mod_fastcgi
                  * prior to 2.4.7
                  */
-                apr_table_setn(r->subprocess_env, *hdr, val);
-                /* standard munging of header name (upcase, HTTP_, etc.) */
-                apr_table_setn(r->subprocess_env, http2env(r->pool, *hdr), val);
+                /* boo#988492 httpoxy don't set HTTP_PROXY */
+                if ( strcasecmp(*hdr, "HTTP_PROXY") != 0 && strcasecmp(*hdr, "HTTP-PROXY") != 0) {
+                    apr_table_setn(r->subprocess_env, *hdr, val);
+                }
+                /* boo#988492 httpoxy don't set HTTP_PROXY */
+                if ( strcasecmp(*hdr, "PROXY") != 0 ) {
+                    /* standard munging of header name (upcase, HTTP_, etc.) */
+                    apr_table_setn(r->subprocess_env, http2env(r->pool, *hdr), val);
+                }
             }
         }
     }


[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/apps/s_server.c
- apps/s_server.c
- openssl-1.0.1i/apps/s_server.c

## Target Source Code

### apps/s_server.c

#### generate_session_id() [lines 3002-3026]
```c
#endif

#define MAX_SESSION_ID_ATTEMPTS 10
static int generate_session_id(const SSL *ssl, unsigned char *id,
				unsigned int *id_len)
	{
	unsigned int count = 0;
	do	{
		RAND_pseudo_bytes(id, *id_len);
		/* Prefix the session_id with the required prefix. NB: If our
		 * prefix is too long, clip it - but there will be worse effects
		 * anyway, eg. the server could only possibly create 1 session
		 * ID (ie. the prefix!) so all future session negotiations will
		 * fail due to conflicts. */
		memcpy(id, session_id_prefix,
			(strlen(session_id_prefix) < *id_len) ?
			strlen(session_id_prefix) : *id_len);
		}
	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
		(++count < MAX_SESSION_ID_ATTEMPTS));
	if(count >= MAX_SESSION_ID_ATTEMPTS)
		return 0;
	return 1;
	}

```

#### s_server_init() [lines 423-457]
```c
#endif

#ifdef MONOLITH
static void s_server_init(void)
	{
	accept_socket=-1;
	cipher=NULL;
	s_server_verify=SSL_VERIFY_NONE;
	s_dcert_file=NULL;
	s_dkey_file=NULL;
	s_cert_file=TEST_CERT;
	s_key_file=NULL;
#ifndef OPENSSL_NO_TLSEXT
	s_cert_file2=TEST_CERT2;
	s_key_file2=NULL;
	ctx2=NULL;
#endif
#ifdef FIONBIO
	s_nbio=0;
#endif
	s_nbio_test=0;
	ctx=NULL;
	www=0;

	bio_s_out=NULL;
	s_debug=0;
	s_msg=0;
	s_quiet=0;
	hack=0;
#ifndef OPENSSL_NO_ENGINE
	engine_id=NULL;
#endif
	}
#endif

```

#### region() [lines 1681-1701]
```c

		SSL_CTX_set_tmp_dh(ctx,dh);
#ifndef OPENSSL_NO_TLSEXT
		if (ctx2)
			{
			if (!dhfile)
				{
				DH *dh2=load_dh_param(s_cert_file2);
				if (dh2 != NULL)
					{
					BIO_printf(bio_s_out,"Setting temp DH parameters\n");
					(void)BIO_flush(bio_s_out);

					DH_free(dh);
					dh = dh2;
					}
				}
			SSL_CTX_set_tmp_dh(ctx2,dh);
			}
#endif
		DH_free(dh);
```

## Upstream Fix
```diff
From f1612746ec7580132f81fb81a23f6705e63d113b Mon Sep 17 00:00:00 2001
From: Emilia Kasper <emilia@openssl.org>
Date: Tue, 12 May 2015 20:15:46 +0200
Subject: [PATCH] s_server: Use 2048-bit DH parameters by default.

Reviewed-by: Rich Salz <rsalz@openssl.org>
---
 apps/s_server.c | 58 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/apps/s_server.c b/apps/s_server.c
index 093a80d583e5b..7e501d21b92ae 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -219,7 +219,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile);
-static DH *get_dh512(void);
+static DH *get_dh2048(void);
 #endif

 #ifdef MONOLITH
@@ -227,30 +227,48 @@ static void s_server_init(void);
 #endif

 #ifndef OPENSSL_NO_DH
-static unsigned char dh512_p[] = {
-    0xDA, 0x58, 0x3C, 0x16, 0xD9, 0x85, 0x22, 0x89, 0xD0, 0xE4, 0xAF, 0x75,
-    0x6F, 0x4C, 0xCA, 0x92, 0xDD, 0x4B, 0xE5, 0x33, 0xB8, 0x04, 0xFB, 0x0F,
-    0xED, 0x94, 0xEF, 0x9C, 0x8A, 0x44, 0x03, 0xED, 0x57, 0x46, 0x50, 0xD3,
-    0x69, 0x99, 0xDB, 0x29, 0xD7, 0x76, 0x27, 0x6B, 0xA2, 0xD3, 0xD4, 0x12,
-    0xE2, 0x18, 0xF4, 0xDD, 0x1E, 0x08, 0x4C, 0xF6, 0xD8, 0x00, 0x3E, 0x7C,
-    0x47, 0x74, 0xE8, 0x33,
+static unsigned char dh2048_p[] = {
+    0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
+    0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
+    0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
+    0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
+    0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
+    0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
+    0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
+    0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
+    0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
+    0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
+    0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
+    0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
+    0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
+    0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
+    0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
+    0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
+    0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+    0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+    0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+    0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+    0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+    0xE9,0x32,0x0B,0x3B,
 };

-static unsigned char dh512_g[] = {
+static unsigned char dh2048_g[] = {
     0x02,
 };

-static DH *get_dh512(void)
+DH *get_dh2048()
 {
-    DH *dh = NULL;
+    DH *dh;

     if ((dh = DH_new()) == NULL)
-        return (NULL);
-    dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
-    dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-    if ((dh->p == NULL) || (dh->g == NULL))
-        return (NULL);
-    return (dh);
+        return NULL;
+    dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+    dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+    if (dh->p == NULL || dh->g == NULL) {
+        DH_free(dh);
+        return NULL;
+    }
+    return dh;
 }
 #endif

@@ -1654,7 +1672,11 @@ int MAIN(int argc, char *argv[])
             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
         } else {
             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
-            dh = get_dh512();
+            dh = get_dh2048();
+            if (dh == NULL) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
         }
         (void)BIO_flush(bio_s_out);
```

Generate a backported patch for the SUSE target version.

[Assistant]
From f1612746ec7580132f81fb81a23f6705e63d113b Mon Sep 17 00:00:00 2001
From: Emilia Kasper <emilia@openssl.org>
Date: Tue, 12 May 2015 20:15:46 +0200
Subject: [PATCH 1/5] s_server: Use 2048-bit DH parameters by default.

Reviewed-by: Rich Salz <rsalz@openssl.org>
---
 apps/s_server.c | 58 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 18 deletions(-)

Index: openssl-1.0.1i/apps/s_server.c
===================================================================
--- openssl-1.0.1i.orig/apps/s_server.c	2015-06-12 13:12:46.438719292 +0200
+++ openssl-1.0.1i/apps/s_server.c	2015-06-12 13:16:33.563456375 +0200
@@ -214,7 +214,7 @@ static int generate_session_id(const SSL
 				unsigned int *id_len);
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile);
-static DH *get_dh512(void);
+static DH *get_dh2048(void);
 #endif

 #ifdef MONOLITH
@@ -222,28 +222,46 @@ static void s_server_init(void);
 #endif

 #ifndef OPENSSL_NO_DH
-static unsigned char dh512_p[]={
-	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
-	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
-	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
-	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
-	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
-	0x47,0x74,0xE8,0x33,
+static unsigned char dh2048_p[] = {
+    0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
+    0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
+    0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
+    0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
+    0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
+    0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
+    0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
+    0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
+    0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
+    0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
+    0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
+    0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
+    0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
+    0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
+    0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
+    0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
+    0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+    0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+    0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+    0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+    0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+    0xE9,0x32,0x0B,0x3B,
 	};
-static unsigned char dh512_g[]={
+static unsigned char dh2048_g[] = {
 	0x02,
 	};

-static DH *get_dh512(void)
+DH *get_dh2048()
 	{
-	DH *dh=NULL;
+    DH *dh;

 	if ((dh=DH_new()) == NULL) return(NULL);
-	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
-	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
-	if ((dh->p == NULL) || (dh->g == NULL))
-		return(NULL);
-	return(dh);
+    dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+    dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+    if (dh->p == NULL || dh->g == NULL) {
+        DH_free(dh);
+        return NULL;
+    }
+    return dh;
 	}
 #endif

@@ -1685,7 +1703,11 @@ bad:
 		else
 			{
 			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
-			dh=get_dh512();
+            dh = get_dh2048();
+            if (dh == NULL) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
 			}
 		(void)BIO_flush(bio_s_out);


[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
- parser.c

## Target Source Code

### parser.c

#### xmlParseMarkupDecl() [lines 6933-7019]
```c
        return (NULL);

    htmlCtxtReset(ctxt);

    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
    if (stream == NULL) {
        return (NULL);
    }
    inputPush(ctxt, stream);
    return (htmlDoRead(ctxt, NULL, encoding, options, 1));
}

/**
 * htmlCtxtReadMemory:
 * @ctxt:  an HTML parser context
 * @buffer:  a pointer to a char array
 * @size:  the size of the array
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of htmlParserOption(s)
 *
 * parse an XML in-memory document and build a tree.
 * This reuses the existing @ctxt parser context
 *
 * Returns the resulting document tree
 */
htmlDocPtr
htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size,
                  const char *URL, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;
    xmlParserInputPtr stream;

    if (ctxt == NULL)
        return (NULL);
    if (buffer == NULL)
        return (NULL);

    htmlCtxtReset(ctxt);

    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
    if (input == NULL) {
	return(NULL);
    }

    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
    if (stream == NULL) {
	xmlFreeParserInputBuffer(input);
	return(NULL);
    }

    inputPush(ctxt, stream);
    return (htmlDoRead(ctxt, URL, encoding, options, 1));
}

/**
 * htmlCtxtReadFd:
 * @ctxt:  an HTML parser context
 * @fd:  an open file descriptor
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of htmlParserOption(s)
 *
 * parse an XML from a file descriptor and build a tree.
 * This reuses the existing @ctxt parser context
 *
 * Returns the resulting document tree
 */
htmlDocPtr
htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd,
              const char *URL, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;
    xmlParserInputPtr stream;

    if (fd < 0)
        return (NULL);
    if (ctxt == NULL)
        return (NULL);

    htmlCtxtReset(ctxt);

    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
    if (input == NULL)
        return (NULL);
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
```

## Upstream Fix
```diff
From ab2b9a93ff19cedde7befbf2fcc48c6e352b6cbe Mon Sep 17 00:00:00 2001
From: Hugh Davenport <hugh@allthethings.co.nz>
Date: Tue, 3 Nov 2015 20:40:49 +0800
Subject: [PATCH] Avoid extra processing of MarkupDecl when EOF

For https://bugzilla.gnome.org/show_bug.cgi?id=756263

One place where ctxt->instate == XML_PARSER_EOF whic was set up
by entity detection issues doesn't get noticed, and even overrided
---
 parser.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/parser.c b/parser.c
index d67b3003b0..134afe7055 100644
--- a/parser.c
+++ b/parser.c
@@ -6972,6 +6972,14 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
 	    xmlParsePI(ctxt);
 	}
     }
+
+    /*
+     * detect requirement to exit there and act accordingly
+     * and avoid having instate overriden later on
+     */
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
     /*
      * This is only for internal subset. On external entities,
      * the replacement is done before parsing stage
```

Generate a backported patch for the SUSE target version.

[Assistant]
From ab2b9a93ff19cedde7befbf2fcc48c6e352b6cbe Mon Sep 17 00:00:00 2001
From: Hugh Davenport <hugh@allthethings.co.nz>
Date: Tue, 3 Nov 2015 20:40:49 +0800
Subject: Avoid extra processing of MarkupDecl when EOF

For https://bugzilla.gnome.org/show_bug.cgi?id=756263

One place where ctxt->instate == XML_PARSER_EOF whic was set up
by entity detection issues doesn't get noticed, and even overrided
---
 parser.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/parser.c b/parser.c
index d67b300..134afe7 100644
--- a/parser.c
+++ b/parser.c
@@ -6972,6 +6972,14 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
 	    xmlParsePI(ctxt);
 	}
     }
+
+    /*
+     * detect requirement to exit there and act accordingly
+     * and avoid having instate overriden later on
+     */
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
     /*
      * This is only for internal subset. On external entities,
      * the replacement is done before parsing stage
--
cgit v0.11.2