[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/bio/b_print.c
- openssl-1.0.1i/crypto/bio/b_print.c

## Target Source Code

### crypto/bio/b_print.c

#### region() [lines 86-180]
```c
#endif

/***************************************************************************/

/*
 * Copyright Patrick Powell 1995
 * This code is based on code written by Patrick Powell <papowell@astart.com>
 * It may be used for any purpose as long as this notice remains intact
 * on all source code distributions.
 */

/*
 * This code contains numerious changes and enhancements which were
 * made by lots of contributors over the last years to Patrick Powell's
 * original code:
 *
 * o Patrick Powell <papowell@astart.com>      (1995)
 * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
 * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
 * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
 * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
 * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
 * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
 * o ...                                       (for OpenSSL)
 */

#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
#else
#define LDOUBLE double
#endif

#ifdef HAVE_LONG_LONG
# if defined(_WIN32) && !defined(__GNUC__)
# define LLONG __int64
# else
# define LLONG long long
# endif
#else
#define LLONG long
#endif

static void fmtstr     (char **, char **, size_t *, size_t *,
			const char *, int, int, int);
static void fmtint     (char **, char **, size_t *, size_t *,
			LLONG, int, int, int, int);
static void fmtfp      (char **, char **, size_t *, size_t *,
			LDOUBLE, int, int, int);
static void doapr_outch (char **, char **, size_t *, size_t *, int);
static void _dopr(char **sbuffer, char **buffer,
		  size_t *maxlen, size_t *retlen, int *truncated,
		  const char *format, va_list args);

/* format read states */
#define DP_S_DEFAULT    0
#define DP_S_FLAGS      1
#define DP_S_MIN        2
#define DP_S_DOT        3
#define DP_S_MAX        4
#define DP_S_MOD        5
#define DP_S_CONV       6
#define DP_S_DONE       7

/* format flags - Bits */
#define DP_F_MINUS      (1 << 0)
#define DP_F_PLUS       (1 << 1)
#define DP_F_SPACE      (1 << 2)
#define DP_F_NUM        (1 << 3)
#define DP_F_ZERO       (1 << 4)
#define DP_F_UP         (1 << 5)
#define DP_F_UNSIGNED   (1 << 6)

/* conversion flags */
#define DP_C_SHORT      1
#define DP_C_LONG       2
#define DP_C_LDOUBLE    3
#define DP_C_LLONG      4

/* some handy macros */
#define char_to_int(p) (p - '0')
#define OSSL_MAX(p,q) ((p >= q) ? p : q)

static void
_dopr(
    char **sbuffer,
    char **buffer,
    size_t *maxlen,
    size_t *retlen,
    int *truncated,
    const char *format,
    va_list args)
{
    char ch;
    LLONG value;
    LDOUBLE fvalue;
```

#### region() [lines 126-213]
```c
#endif

static void fmtstr     (char **, char **, size_t *, size_t *,
			const char *, int, int, int);
static void fmtint     (char **, char **, size_t *, size_t *,
			LLONG, int, int, int, int);
static void fmtfp      (char **, char **, size_t *, size_t *,
			LDOUBLE, int, int, int);
static void doapr_outch (char **, char **, size_t *, size_t *, int);
static void _dopr(char **sbuffer, char **buffer,
		  size_t *maxlen, size_t *retlen, int *truncated,
		  const char *format, va_list args);

/* format read states */
#define DP_S_DEFAULT    0
#define DP_S_FLAGS      1
#define DP_S_MIN        2
#define DP_S_DOT        3
#define DP_S_MAX        4
#define DP_S_MOD        5
#define DP_S_CONV       6
#define DP_S_DONE       7

/* format flags - Bits */
#define DP_F_MINUS      (1 << 0)
#define DP_F_PLUS       (1 << 1)
#define DP_F_SPACE      (1 << 2)
#define DP_F_NUM        (1 << 3)
#define DP_F_ZERO       (1 << 4)
#define DP_F_UP         (1 << 5)
#define DP_F_UNSIGNED   (1 << 6)

/* conversion flags */
#define DP_C_SHORT      1
#define DP_C_LONG       2
#define DP_C_LDOUBLE    3
#define DP_C_LLONG      4

/* some handy macros */
#define char_to_int(p) (p - '0')
#define OSSL_MAX(p,q) ((p >= q) ? p : q)

static void
_dopr(
    char **sbuffer,
    char **buffer,
    size_t *maxlen,
    size_t *retlen,
    int *truncated,
    const char *format,
    va_list args)
{
    char ch;
    LLONG value;
    LDOUBLE fvalue;
    char *strvalue;
    int min;
    int max;
    int state;
    int flags;
    int cflags;
    size_t currlen;

    state = DP_S_DEFAULT;
    flags = currlen = cflags = min = 0;
    max = -1;
    ch = *format++;

    while (state != DP_S_DONE) {
        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
            state = DP_S_DONE;

        switch (state) {
        case DP_S_DEFAULT:
            if (ch == '%')
                state = DP_S_FLAGS;
            else
                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
            ch = *format++;
            break;
        case DP_S_FLAGS:
            switch (ch) {
            case '-':
                flags |= DP_F_MINUS;
                ch = *format++;
                break;
            case '+':
                flags |= DP_F_PLUS;
```

#### region() [lines 195-424]
```c
        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
            state = DP_S_DONE;

        switch (state) {
        case DP_S_DEFAULT:
            if (ch == '%')
                state = DP_S_FLAGS;
            else
                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
            ch = *format++;
            break;
        case DP_S_FLAGS:
            switch (ch) {
            case '-':
                flags |= DP_F_MINUS;
                ch = *format++;
                break;
            case '+':
                flags |= DP_F_PLUS;
                ch = *format++;
                break;
            case ' ':
                flags |= DP_F_SPACE;
                ch = *format++;
                break;
            case '#':
                flags |= DP_F_NUM;
                ch = *format++;
                break;
            case '0':
                flags |= DP_F_ZERO;
                ch = *format++;
                break;
            default:
                state = DP_S_MIN;
                break;
            }
            break;
        case DP_S_MIN:
            if (isdigit((unsigned char)ch)) {
/* ... 183 lines omitted ... */
            case 'w':
                /* not supported yet, treat as next char */
                ch = *format++;
                break;
            default:
                /* unknown, skip */
                break;
            }
            ch = *format++;
            state = DP_S_DEFAULT;
            flags = cflags = min = 0;
            max = -1;
            break;
        case DP_S_DONE:
            break;
        default:
            break;
        }
    }
    *truncated = (currlen > *maxlen - 1);
```

#### region() [lines 292-310]
```c
            switch (ch) {
            case 'd':
            case 'i':
                switch (cflags) {
                case DP_C_SHORT:
                    value = (short int)va_arg(args, int);
                    break;
                case DP_C_LONG:
                    value = va_arg(args, long int);
                    break;
                case DP_C_LLONG:
                    value = va_arg(args, LLONG);
                    break;
                default:
                    value = va_arg(args, int);
                    break;
                }
                fmtint(sbuffer, buffer, &currlen, maxlen,
                       value, 10, min, max, flags);
```

#### region() [lines 316-336]
```c
            case 'o':
            case 'u':
                flags |= DP_F_UNSIGNED;
                switch (cflags) {
                case DP_C_SHORT:
                    value = (unsigned short int)va_arg(args, unsigned int);
                    break;
                case DP_C_LONG:
                    value = (LLONG) va_arg(args,
                        unsigned long int);
                    break;
                case DP_C_LLONG:
                    value = va_arg(args, unsigned LLONG);
                    break;
                default:
                    value = (LLONG) va_arg(args,
                        unsigned int);
                    break;
                }
                fmtint(sbuffer, buffer, &currlen, maxlen, value,
                       ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
```

#### region() [lines 289-414]
```c
            state = DP_S_CONV;
            break;
        case DP_S_CONV:
            switch (ch) {
            case 'd':
            case 'i':
                switch (cflags) {
                case DP_C_SHORT:
                    value = (short int)va_arg(args, int);
                    break;
                case DP_C_LONG:
                    value = va_arg(args, long int);
                    break;
                case DP_C_LLONG:
                    value = va_arg(args, LLONG);
                    break;
                default:
                    value = va_arg(args, int);
                    break;
                }
                fmtint(sbuffer, buffer, &currlen, maxlen,
                       value, 10, min, max, flags);
                break;
            case 'X':
                flags |= DP_F_UP;
                /* FALLTHROUGH */
            case 'x':
            case 'o':
            case 'u':
                flags |= DP_F_UNSIGNED;
                switch (cflags) {
                case DP_C_SHORT:
                    value = (unsigned short int)va_arg(args, unsigned int);
                    break;
                case DP_C_LONG:
                    value = (LLONG) va_arg(args,
                        unsigned long int);
                    break;
                case DP_C_LLONG:
                    value = va_arg(args, unsigned LLONG);
/* ... 23 lines omitted ... */
                else
                    fvalue = va_arg(args, double);
                break;
            case 'G':
                flags |= DP_F_UP;
            case 'g':
                if (cflags == DP_C_LDOUBLE)
                    fvalue = va_arg(args, LDOUBLE);
                else
                    fvalue = va_arg(args, double);
                break;
            case 'c':
                doapr_outch(sbuffer, buffer, &currlen, maxlen,
                    va_arg(args, int));
                break;
            case 's':
                strvalue = va_arg(args, char *);
                if (max < 0) {
		    if (buffer)
			max = INT_MAX;
		    else
			max = *maxlen;
		}
                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
                       flags, min, max);
                break;
            case 'p':
                value = (long)va_arg(args, void *);
/* ... 15 lines omitted ... */
                    *num = (LLONG) currlen;
                } else {
                    int    *num;
                    num = va_arg(args, int *);
                    *num = currlen;
                }
                break;
            case '%':
                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
                break;
            case 'w':
                /* not supported yet, treat as next char */
                ch = *format++;
                break;
            default:
                /* unknown, skip */
                break;
            }
            ch = *format++;
            state = DP_S_DEFAULT;
```

#### region() [lines 366-376]
```c
                break;
            case 's':
                strvalue = va_arg(args, char *);
                if (max < 0) {
		    if (buffer)
			max = INT_MAX;
		    else
			max = *maxlen;
		}
                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
                       flags, min, max);
```

#### region() [lines 381-402]
```c
                    value, 16, min, max, flags|DP_F_NUM);
                break;
            case 'n': /* XXX */
                if (cflags == DP_C_SHORT) {
                    short int *num;
                    num = va_arg(args, short int *);
                    *num = currlen;
                } else if (cflags == DP_C_LONG) { /* XXX */
                    long int *num;
                    num = va_arg(args, long int *);
                    *num = (long int) currlen;
                } else if (cflags == DP_C_LLONG) { /* XXX */
                    LLONG *num;
                    num = va_arg(args, LLONG *);
                    *num = (LLONG) currlen;
                } else {
                    int    *num;
                    num = va_arg(args, int *);
                    *num = currlen;
                }
                break;
            case '%':
```

#### region() [lines 385-477]
```c
                    short int *num;
                    num = va_arg(args, short int *);
                    *num = currlen;
                } else if (cflags == DP_C_LONG) { /* XXX */
                    long int *num;
                    num = va_arg(args, long int *);
                    *num = (long int) currlen;
                } else if (cflags == DP_C_LLONG) { /* XXX */
                    LLONG *num;
                    num = va_arg(args, LLONG *);
                    *num = (LLONG) currlen;
                } else {
                    int    *num;
                    num = va_arg(args, int *);
                    *num = currlen;
                }
                break;
            case '%':
                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
                break;
            case 'w':
                /* not supported yet, treat as next char */
                ch = *format++;
                break;
            default:
                /* unknown, skip */
                break;
            }
            ch = *format++;
            state = DP_S_DEFAULT;
            flags = cflags = min = 0;
            max = -1;
            break;
        case DP_S_DONE:
            break;
        default:
            break;
        }
    }
    *truncated = (currlen > *maxlen - 1);
    if (*truncated)
        currlen = *maxlen - 1;
    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
    *retlen = currlen - 1;
    return;
}

static void
fmtstr(
    char **sbuffer,
    char **buffer,
    size_t *currlen,
    size_t *maxlen,
    const char *value,
    int flags,
    int min,
    int max)
{
    int padlen, strln;
    int cnt = 0;

    if (value == 0)
        value = "<NULL>";
    for (strln = 0; value[strln]; ++strln)
        ;
    padlen = min - strln;
    if (padlen < 0)
        padlen = 0;
    if (flags & DP_F_MINUS)
        padlen = -padlen;

    while ((padlen > 0) && (cnt < max)) {
        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        --padlen;
        ++cnt;
    }
    while (*value && (cnt < max)) {
        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
        ++cnt;
    }
    while ((padlen < 0) && (cnt < max)) {
        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        ++padlen;
        ++cnt;
    }
}

static void
fmtint(
    char **sbuffer,
    char **buffer,
    size_t *currlen,
    size_t *maxlen,
```

#### region() [lines 401-517]
```c
                break;
            case '%':
                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
                break;
            case 'w':
                /* not supported yet, treat as next char */
                ch = *format++;
                break;
            default:
                /* unknown, skip */
                break;
            }
            ch = *format++;
            state = DP_S_DEFAULT;
            flags = cflags = min = 0;
            max = -1;
            break;
        case DP_S_DONE:
            break;
        default:
            break;
        }
    }
    *truncated = (currlen > *maxlen - 1);
    if (*truncated)
        currlen = *maxlen - 1;
    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
    *retlen = currlen - 1;
    return;
}

static void
fmtstr(
    char **sbuffer,
    char **buffer,
    size_t *currlen,
    size_t *maxlen,
    const char *value,
    int flags,
    int min,
    int max)
{
    int padlen, strln;
    int cnt = 0;

/* ... truncated ... */

## Upstream Fix
```diff
commit 578b956fe741bf8e84055547b1e83c28dd902c73
Author: Matt Caswell <matt@openssl.org>
Date:   Thu Feb 25 13:09:46 2016 +0000

    Fix memory issues in BIO_*printf functions

    The internal |fmtstr| function used in processing a "%s" format string
    in the BIO_*printf functions could overflow while calculating the length
    of a string and cause an OOB read when printing very long strings.

    Additionally the internal |doapr_outch| function can attempt to write to
    an OOB memory location (at an offset from the NULL pointer) in the event of
    a memory allocation failure. In 1.0.2 and below this could be caused where
    the size of a buffer to be allocated is greater than INT_MAX. E.g. this
    could be in processing a very long "%s" format string. Memory leaks can also
    occur.

    These issues will only occur on certain platforms where sizeof(size_t) >
    sizeof(int). E.g. many 64 bit systems. The first issue may mask the second
    issue dependent on compiler behaviour.

    These problems could enable attacks where large amounts of untrusted data
    is passed to the BIO_*printf functions. If applications use these functions
    in this way then they could be vulnerable. OpenSSL itself uses these
    functions when printing out human-readable dumps of ASN.1 data. Therefore
    applications that print this data could be vulnerable if the data is from
    untrusted sources. OpenSSL command line applications could also be
    vulnerable where they print out ASN.1 data, or if untrusted data is passed
    as command line arguments.

    Libssl is not considered directly vulnerable. Additionally certificates etc
    received via remote connections via libssl are also unlikely to be able to
    trigger these issues because of message size limits enforced within libssl.

    CVE-2016-0799

    Issue reported by Guido Vranken.

    Reviewed-by: Andy Polyakov <appro@openssl.org>

Index: openssl-1.0.1i/crypto/bio/b_print.c
===================================================================
--- openssl-1.0.1i.orig/crypto/bio/b_print.c	2016-02-26 10:36:35.108070356 +0100
+++ openssl-1.0.1i/crypto/bio/b_print.c	2016-02-26 10:36:38.224094007 +0100
@@ -125,14 +125,14 @@
 #define LLONG long
 #endif

-static void fmtstr     (char **, char **, size_t *, size_t *,
+static int fmtstr     (char **, char **, size_t *, size_t *,
 			const char *, int, int, int);
-static void fmtint     (char **, char **, size_t *, size_t *,
+static int fmtint     (char **, char **, size_t *, size_t *,
 			LLONG, int, int, int, int);
-static void fmtfp      (char **, char **, size_t *, size_t *,
+static int fmtfp      (char **, char **, size_t *, size_t *,
 			LDOUBLE, int, int, int);
-static void doapr_outch (char **, char **, size_t *, size_t *, int);
-static void _dopr(char **sbuffer, char **buffer,
+static int doapr_outch (char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
 		  size_t *maxlen, size_t *retlen, int *truncated,
 		  const char *format, va_list args);

@@ -165,7 +165,7 @@
 #define char_to_int(p) (p - '0')
 #define OSSL_MAX(p,q) ((p >= q) ? p : q)

-static void
+static int
 _dopr(
     char **sbuffer,
     char **buffer,
@@ -200,7 +200,8 @@
             if (ch == '%')
                 state = DP_S_FLAGS;
             else
-                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
+                if(!doapr_outch(sbuffer,buffer, &currlen, maxlen, ch))
+                    return 0;
             ch = *format++;
             break;
         case DP_S_FLAGS:
@@ -306,8 +307,9 @@
                     value = va_arg(args, int);
                     break;
                 }
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                       value, 10, min, max, flags);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+                            max, flags))
+                    return 0;
                 break;
             case 'X':
                 flags |= DP_F_UP;
@@ -332,17 +334,19 @@
                         unsigned int);
                     break;
                 }
-                fmtint(sbuffer, buffer, &currlen, maxlen, value,
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
                        ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
-                       min, max, flags);
+                            min, max, flags))
+                    return 0;
                 break;
             case 'f':
                 if (cflags == DP_C_LDOUBLE)
                     fvalue = va_arg(args, LDOUBLE);
                 else
                     fvalue = va_arg(args, double);
-                fmtfp(sbuffer, buffer, &currlen, maxlen,
-                      fvalue, min, max, flags);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags))
+                    return 0;
                 break;
             case 'E':
                 flags |= DP_F_UP;
@@ -361,8 +365,9 @@
                     fvalue = va_arg(args, double);
                 break;
             case 'c':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen,
-                    va_arg(args, int));
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                    va_arg(args, int)))
+                    return 0;
                 break;
             case 's':
                 strvalue = va_arg(args, char *);
@@ -372,13 +377,15 @@
 		    else
 			max = *maxlen;
 		}
-                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
-                       flags, min, max);
+                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+                       flags, min, max))
+                    return 0;
                 break;
             case 'p':
                 value = (long)va_arg(args, void *);
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                    value, 16, min, max, flags|DP_F_NUM);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+                    value, 16, min, max, flags|DP_F_NUM))
+                    return 0;
                 break;
             case 'n': /* XXX */
                 if (cflags == DP_C_SHORT) {
@@ -400,7 +407,8 @@
                 }
                 break;
             case '%':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
                 break;
             case 'w':
                 /* not supported yet, treat as next char */
@@ -424,12 +432,13 @@
     *truncated = (currlen > *maxlen - 1);
     if (*truncated)
         currlen = *maxlen - 1;
-    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
+    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+        return 0;
     *retlen = currlen - 1;
-    return;
+    return 1;
 }

-static void
+static int
 fmtstr(
     char **sbuffer,
     char **buffer,
@@ -440,36 +449,43 @@
     int min,
     int max)
 {
-    int padlen, strln;
+    int padlen;
+    size_t strln;
     int cnt = 0;

     if (value == 0)
         value = "<NULL>";
-    for (strln = 0; value[strln]; ++strln)
-        ;
+
+strln = strlen(value);     if (strln> INT_MAX)
+        strln = INT_MAX        ;
+
     padlen = min - strln;
-    if (padlen < 0)
+    if (min < 0 || padlen < 0)
         padlen = 0;
     if (flags & DP_F_MINUS)
         padlen = -padlen;

     while ((padlen > 0) && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         --padlen;
         ++cnt;
     }
     while (*value && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+            return 0;
         ++cnt;
     }
     wh
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 578b956fe741bf8e84055547b1e83c28dd902c73
Author: Matt Caswell <matt@openssl.org>
Date:   Thu Feb 25 13:09:46 2016 +0000

    Fix memory issues in BIO_*printf functions

    The internal |fmtstr| function used in processing a "%s" format string
    in the BIO_*printf functions could overflow while calculating the length
    of a string and cause an OOB read when printing very long strings.

    Additionally the internal |doapr_outch| function can attempt to write to
    an OOB memory location (at an offset from the NULL pointer) in the event of
    a memory allocation failure. In 1.0.2 and below this could be caused where
    the size of a buffer to be allocated is greater than INT_MAX. E.g. this
    could be in processing a very long "%s" format string. Memory leaks can also
    occur.

    These issues will only occur on certain platforms where sizeof(size_t) >
    sizeof(int). E.g. many 64 bit systems. The first issue may mask the second
    issue dependent on compiler behaviour.

    These problems could enable attacks where large amounts of untrusted data
    is passed to the BIO_*printf functions. If applications use these functions
    in this way then they could be vulnerable. OpenSSL itself uses these
    functions when printing out human-readable dumps of ASN.1 data. Therefore
    applications that print this data could be vulnerable if the data is from
    untrusted sources. OpenSSL command line applications could also be
    vulnerable where they print out ASN.1 data, or if untrusted data is passed
    as command line arguments.

    Libssl is not considered directly vulnerable. Additionally certificates etc
    received via remote connections via libssl are also unlikely to be able to
    trigger these issues because of message size limits enforced within libssl.

    CVE-2016-0799

    Issue reported by Guido Vranken.

    Reviewed-by: Andy Polyakov <appro@openssl.org>

Index: openssl-1.0.1i/crypto/bio/b_print.c
===================================================================
--- openssl-1.0.1i.orig/crypto/bio/b_print.c	2016-02-26 10:36:35.108070356 +0100
+++ openssl-1.0.1i/crypto/bio/b_print.c	2016-02-26 10:36:38.224094007 +0100
@@ -125,14 +125,14 @@
 #define LLONG long
 #endif

-static void fmtstr     (char **, char **, size_t *, size_t *,
+static int fmtstr     (char **, char **, size_t *, size_t *,
 			const char *, int, int, int);
-static void fmtint     (char **, char **, size_t *, size_t *,
+static int fmtint     (char **, char **, size_t *, size_t *,
 			LLONG, int, int, int, int);
-static void fmtfp      (char **, char **, size_t *, size_t *,
+static int fmtfp      (char **, char **, size_t *, size_t *,
 			LDOUBLE, int, int, int);
-static void doapr_outch (char **, char **, size_t *, size_t *, int);
-static void _dopr(char **sbuffer, char **buffer,
+static int doapr_outch (char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
 		  size_t *maxlen, size_t *retlen, int *truncated,
 		  const char *format, va_list args);

@@ -165,7 +165,7 @@
 #define char_to_int(p) (p - '0')
 #define OSSL_MAX(p,q) ((p >= q) ? p : q)

-static void
+static int
 _dopr(
     char **sbuffer,
     char **buffer,
@@ -200,7 +200,8 @@
             if (ch == '%')
                 state = DP_S_FLAGS;
             else
-                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
+                if(!doapr_outch(sbuffer,buffer, &currlen, maxlen, ch))
+                    return 0;
             ch = *format++;
             break;
         case DP_S_FLAGS:
@@ -306,8 +307,9 @@
                     value = va_arg(args, int);
                     break;
                 }
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                       value, 10, min, max, flags);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+                            max, flags))
+                    return 0;
                 break;
             case 'X':
                 flags |= DP_F_UP;
@@ -332,17 +334,19 @@
                         unsigned int);
                     break;
                 }
-                fmtint(sbuffer, buffer, &currlen, maxlen, value,
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
                        ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
-                       min, max, flags);
+                            min, max, flags))
+                    return 0;
                 break;
             case 'f':
                 if (cflags == DP_C_LDOUBLE)
                     fvalue = va_arg(args, LDOUBLE);
                 else
                     fvalue = va_arg(args, double);
-                fmtfp(sbuffer, buffer, &currlen, maxlen,
-                      fvalue, min, max, flags);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags))
+                    return 0;
                 break;
             case 'E':
                 flags |= DP_F_UP;
@@ -361,8 +365,9 @@
                     fvalue = va_arg(args, double);
                 break;
             case 'c':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen,
-                    va_arg(args, int));
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                    va_arg(args, int)))
+                    return 0;
                 break;
             case 's':
                 strvalue = va_arg(args, char *);
@@ -372,13 +377,15 @@
 		    else
 			max = *maxlen;
 		}
-                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
-                       flags, min, max);
+                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+                       flags, min, max))
+                    return 0;
                 break;
             case 'p':
                 value = (long)va_arg(args, void *);
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                    value, 16, min, max, flags|DP_F_NUM);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+                    value, 16, min, max, flags|DP_F_NUM))
+                    return 0;
                 break;
             case 'n': /* XXX */
                 if (cflags == DP_C_SHORT) {
@@ -400,7 +407,8 @@
                 }
                 break;
             case '%':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
                 break;
             case 'w':
                 /* not supported yet, treat as next char */
@@ -424,12 +432,13 @@
     *truncated = (currlen > *maxlen - 1);
     if (*truncated)
         currlen = *maxlen - 1;
-    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
+    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+        return 0;
     *retlen = currlen - 1;
-    return;
+    return 1;
 }

-static void
+static int
 fmtstr(
     char **sbuffer,
     char **buffer,
@@ -440,36 +449,43 @@
     int min,
     int max)
 {
-    int padlen, strln;
+    int padlen;
+    size_t strln;
     int cnt = 0;

     if (value == 0)
         value = "<NULL>";
-    for (strln = 0; value[strln]; ++strln)
-        ;
+
+strln = strlen(value);     if (strln> INT_MAX)
+        strln = INT_MAX        ;
+
     padlen = min - strln;
-    if (padlen < 0)
+    if (min < 0 || padlen < 0)
         padlen = 0;
     if (flags & DP_F_MINUS)
         padlen = -padlen;

     while ((padlen > 0) && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         --padlen;
         ++cnt;
     }
     while (*value && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+            return 0;
         ++cnt;
     }
     while ((padlen < 0) && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         ++padlen;
         ++cnt;
     }
+    return 1;
 }

-static void
+static int
 fmtint(
     char **sbuffer,
     char **buffer,
@@ -533,37 +549,45 @@

     /* spaces */
     while (spadlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         --spadlen;
     }

     /* sign */
     if (signvalue)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+            return 0;

     /* prefix */
     while (*prefix) {
-	doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+            return 0;
 	prefix++;
     }

     /* zeros */
     if (zpadlen > 0) {
         while (zpadlen > 0) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
             --zpadlen;
         }
     }
     /* digits */
     while (place > 0)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
+{
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+            return 0;
+    }

     /* left justified spaces */
     while (spadlen < 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         ++spadlen;
     }
-    return;
+    return 1;
 }

 static LDOUBLE
@@ -597,7 +621,7 @@
     return intpart;
 }

-static void
+static int
 fmtfp(
     char **sbuffer,
     char **buffer,
@@ -682,47 +706,62 @@

     if ((flags & DP_F_ZERO) && (padlen > 0)) {
         if (signvalue) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+                return 0;
             --padlen;
             signvalue = 0;
         }
         while (padlen > 0) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
             --padlen;
         }
     }
     while (padlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         --padlen;
     }
-    if (signvalue)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+    if (signvalue&& !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+        return 0;

     while (iplace > 0)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
+{
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+            return 0;
+    }

     /*
      * Decimal point. This should probably use locale to find the correct
      * char to print out.
      */
     if (max > 0 || (flags & DP_F_NUM)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+            return 0;

         while (fplace > 0)
-            doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
+{
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]))
+                return 0;
+    }
     }
     while (zpadlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+            return 0;
         --zpadlen;
     }

     while (padlen < 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
         ++padlen;
     }
+    return 1;
 }

-static void
+#define BUFFER_INC  1024
+
+static int
 doapr_outch(
     char **sbuffer,
     char **buffer,
@@ -733,24 +772,30 @@
     /* If we haven't at least one buffer, someone has doe a big booboo */
     assert(*sbuffer != NULL || buffer != NULL);

-    if (buffer) {
-	while (*currlen >= *maxlen) {
+    /* |currlen| must always be <= |*maxlen| */
+    assert(*currlen <= *maxlen);
+
+    if (buffer && *currlen == *maxlen) {
+        if (*maxlen > INT_MAX - BUFFER_INC)
+            return 0;
+
+        *maxlen += BUFFER_INC;
 	    if (*buffer == NULL) {
-		if (*maxlen == 0)
-		    *maxlen = 1024;
 		*buffer = OPENSSL_malloc(*maxlen);
+            if (*buffer == NULL)
+                return 0;
 		if (*currlen > 0) {
 		    assert(*sbuffer != NULL);
 		    memcpy(*buffer, *sbuffer, *currlen);
 		}
 		*sbuffer = NULL;
 	    } else {
-		*maxlen += 1024;
-		*buffer = OPENSSL_realloc(*buffer, *maxlen);
-	    }
+            char *tmpbuf;
+            tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+            if (tmpbuf == NULL)
+                return 0;
+            *buffer = tmpbuf;
 	}
-	/* What to do if *buffer is NULL? */
-	assert(*sbuffer != NULL || *buffer != NULL);
     }

     if (*currlen < *maxlen) {
@@ -760,7 +805,7 @@
 	    (*buffer)[(*currlen)++] = (char)c;
     }

-    return;
+    return 1;
 }

 /***************************************************************************/
@@ -792,8 +837,11 @@

 	dynbuf = NULL;
 	CRYPTO_push_info("doapr()");
-	_dopr(&hugebufp, &dynbuf, &hugebufsize,
-		&retlen, &ignored, format, args);
+    if (!_dopr(&hugebufp, &dynbuf, &hugebufsize,
+		&retlen, &ignored, format, args)) {
+        OPENSSL_free(dynbuf);
+        return -1;
+    }
 	if (dynbuf)
 		{
 		ret=BIO_write(bio, dynbuf, (int)retlen);
@@ -829,7 +877,8 @@
 	size_t retlen;
 	int truncated;

-	_dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
+    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+        return -1;

 	if (truncated)
 		/* In case of truncation, return -1 like traditional snprintf.


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

## Upstream Fix
```diff
From 8fb4a770075628d6441fb17a1e435100e2f3b1a2 Mon Sep 17 00:00:00 2001
From: Hugh Davenport <hugh@allthethings.co.nz>
Date: Fri, 20 Nov 2015 17:16:06 +0800
Subject: [PATCH] CVE-2015-8242 Buffer overead with HTML parser in push mode

For https://bugzilla.gnome.org/show_bug.cgi?id=756372
Error in the code pointing to the codepoint in the stack for the
current char value instead of the pointer in the input that the SAX
callback expects
Reported and fixed by Hugh Davenport
---
 HTMLparser.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/HTMLparser.c b/HTMLparser.c
index bdf780711c..b7291972ef 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5735,17 +5735,17 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
 				if (ctxt->keepBlanks) {
 				    if (ctxt->sax->characters != NULL)
 					ctxt->sax->characters(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				} else {
 				    if (ctxt->sax->ignorableWhitespace != NULL)
 					ctxt->sax->ignorableWhitespace(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				}
 			    } else {
 				htmlCheckParagraph(ctxt);
 				if (ctxt->sax->characters != NULL)
 				    ctxt->sax->characters(
-					    ctxt->userData, &cur, 1);
+					    ctxt->userData, &in->cur[0], 1);
 			    }
 			}
 			ctxt->token = 0;
```

Generate a backported patch for the SUSE target version.

[Assistant]
From 8fb4a770075628d6441fb17a1e435100e2f3b1a2 Mon Sep 17 00:00:00 2001
From: Hugh Davenport <hugh@allthethings.co.nz>
Date: Fri, 20 Nov 2015 17:16:06 +0800
Subject: CVE-2015-8242 Buffer overead with HTML parser in push mode

For https://bugzilla.gnome.org/show_bug.cgi?id=756372
Error in the code pointing to the codepoint in the stack for the
current char value instead of the pointer in the input that the SAX
callback expects
Reported and fixed by Hugh Davenport
---
 HTMLparser.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/HTMLparser.c b/HTMLparser.c
index bdf7807..b729197 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5735,17 +5735,17 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
 				if (ctxt->keepBlanks) {
 				    if (ctxt->sax->characters != NULL)
 					ctxt->sax->characters(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				} else {
 				    if (ctxt->sax->ignorableWhitespace != NULL)
 					ctxt->sax->ignorableWhitespace(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				}
 			    } else {
 				htmlCheckParagraph(ctxt);
 				if (ctxt->sax->characters != NULL)
 				    ctxt->sax->characters(
-					    ctxt->userData, &cur, 1);
+					    ctxt->userData, &in->cur[0], 1);
 			    }
 			}
 			ctxt->token = 0;
--
cgit v0.11.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-2013-2070

http/modules/ngx_http_proxy_module.c in nginx 1.1.4 through 1.2.8 and 1.3.0 through 1.4.0, when proxy_pass is used with untrusted HTTP servers, allows remote attackers to cause a denial of service (crash) and obtain sensitive information from worker process memory via a crafted proxy response, a similar vulnerability to CVE-2013-2028.

## Package
nginx

## Upstream Fix
```diff
Index: conf/nginx.conf
===================================================================
--- conf/nginx.conf.orig
+++ conf/nginx.conf
@@ -1,16 +1,17 @@

-#user  nobody;
+#user  nginx;
 worker_processes  1;

-#error_log  logs/error.log;
-#error_log  logs/error.log  notice;
-#error_log  logs/error.log  info;
+#error_log  /var/log/nginx/error.log;
+#error_log  /var/log/nginx/error.log  notice;
+#error_log  /var/log/nginx/error.log  info;

-#pid        logs/nginx.pid;
+#pid        /var/run/nginx.pid;

 events {
     worker_connections  1024;
+    use epoll;
 }

@@ -22,7 +23,7 @@ http {
     #                  '$status $body_bytes_sent "$http_referer" '
     #                  '"$http_user_agent" "$http_x_forwarded_for"';

-    #access_log  logs/access.log  main;
+    #access_log  /var/log/nginx/access.log  main;

     sendfile        on;
     #tcp_nopush     on;
@@ -32,16 +33,18 @@ http {

     #gzip  on;

+    include conf.d/*.conf;
+
     server {
         listen       80;
         server_name  localhost;

         #charset koi8-r;

-        #access_log  logs/host.access.log  main;
+        #access_log  /var/log/nginx/host.access.log  main;

         location / {
-            root   html;
+            root   /srv/www/htdocs/;
             index  index.html index.htm;
         }

@@ -51,7 +54,7 @@ http {
         #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
-            root   html;
+            root   /srv/www/htdocs/;
         }

         # proxy the PHP scripts to Apache listening on 127.0.0.1:80
@@ -87,7 +90,7 @@ http {
     #    server_name  somename  alias  another.alias;

     #    location / {
-    #        root   html;
+    #        root   /srv/www/htdocs/;
     #        index  index.html index.htm;
     #    }
     #}
@@ -110,9 +113,10 @@ http {
     #    ssl_prefer_server_ciphers   on;

     #    location / {
-    #        root   html;
+    #        root   /srv/www/htdocs/;
     #        index  index.html index.htm;
     #    }
     #}

+    include vhosts.d/*.conf;
 }
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: conf/nginx.conf
===================================================================
--- conf/nginx.conf.orig
+++ conf/nginx.conf
@@ -1,16 +1,17 @@

-#user  nobody;
+#user  nginx;
 worker_processes  1;

-#error_log  logs/error.log;
-#error_log  logs/error.log  notice;
-#error_log  logs/error.log  info;
+#error_log  /var/log/nginx/error.log;
+#error_log  /var/log/nginx/error.log  notice;
+#error_log  /var/log/nginx/error.log  info;

-#pid        logs/nginx.pid;
+#pid        /var/run/nginx.pid;

 events {
     worker_connections  1024;
+    use epoll;
 }

@@ -22,7 +23,7 @@ http {
     #                  '$status $body_bytes_sent "$http_referer" '
     #                  '"$http_user_agent" "$http_x_forwarded_for"';

-    #access_log  logs/access.log  main;
+    #access_log  /var/log/nginx/access.log  main;

     sendfile        on;
     #tcp_nopush     on;
@@ -32,16 +33,18 @@ http {

     #gzip  on;

+    include conf.d/*.conf;
+
     server {
         listen       80;
         server_name  localhost;

         #charset koi8-r;

-        #access_log  logs/host.access.log  main;
+        #access_log  /var/log/nginx/host.access.log  main;

         location / {
-            root   html;
+            root   /srv/www/htdocs/;
             index  index.html index.htm;
         }

@@ -51,7 +54,7 @@ http {
         #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
-            root   html;
+            root   /srv/www/htdocs/;
         }

         # proxy the PHP scripts to Apache listening on 127.0.0.1:80
@@ -87,7 +90,7 @@ http {
     #    server_name  somename  alias  another.alias;

     #    location / {
-    #        root   html;
+    #        root   /srv/www/htdocs/;
     #        index  index.html index.htm;
     #    }
     #}
@@ -110,9 +113,10 @@ http {
     #    ssl_prefer_server_ciphers   on;

     #    location / {
-    #        root   html;
+    #        root   /srv/www/htdocs/;
     #        index  index.html index.htm;
     #    }
     #}

+    include vhosts.d/*.conf;
 }


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

The IsPixelGray function in MagickCore/pixel-accessor.h in ImageMagick 7.0.3-8 allows remote attackers to cause a denial of service (out-of-bounds heap read) via a crafted image file.

## Package
GraphicsMagick

## Files to modify
- GraphicsMagick-1.3.20.orig/coders/tiff.c
- coders/tiff.c
- MagickCore/property.c

## Upstream Fix
```diff
From b61d35eaccc0a7ddeff8a1c3abfcd0a43ccf210b Mon Sep 17 00:00:00 2001
From: Cristy <urban-warrior@imagemagick.org>
Date: Wed, 9 Nov 2016 15:57:28 -0500
Subject: [PATCH] https://github.com/ImageMagick/ImageMagick/issues/298

---
 MagickCore/property.c |  4 ++--
 coders/tiff.c         | 43 ++++++++++++++++++++++++++++---------------
 coders/txt.c          |  3 +--
 3 files changed, 31 insertions(+), 19 deletions(-)

Index: GraphicsMagick-1.3.20/coders/tiff.c
===================================================================
--- GraphicsMagick-1.3.20.orig/coders/tiff.c	2016-11-28 12:38:37.780341823 +0100
+++ GraphicsMagick-1.3.20/coders/tiff.c	2016-11-28 12:39:13.468935074 +0100
@@ -1727,31 +1727,31 @@ ReadTIFFImage(const ImageInfo *image_inf
       if (TIFFGetField(tiff,TIFFTAG_ARTIST,&text) == 1)
         (void) SetImageAttribute(image,"artist",text);

-      if (TIFFGetField(tiff,TIFFTAG_COPYRIGHT,&text) == 1) /* TIFFTAG_COPYRIGHT */
+      if (TIFFGetField(tiff,TIFFTAG_COPYRIGHT,&text) == 1 && (text != (char *) NULL)) /* TIFFTAG_COPYRIGHT */
         (void) SetImageAttribute(image,"copyright",text);

-      if (TIFFGetField(tiff,TIFFTAG_DATETIME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_DATETIME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"timestamp",text);

-      if (TIFFGetField(tiff,TIFFTAG_DOCUMENTNAME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_DOCUMENTNAME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"document",text);

-      if (TIFFGetField(tiff,TIFFTAG_HOSTCOMPUTER,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_HOSTCOMPUTER,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"hostcomputer",text);

-      if (TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"comment",text);

-      if (TIFFGetField(tiff,TIFFTAG_MAKE,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_MAKE,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"make",text);

-      if (TIFFGetField(tiff,TIFFTAG_MODEL,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_MODEL,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"model",text);

-      if (TIFFGetField(tiff,TIFFTAG_PAGENAME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_PAGENAME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"label",text);

-      if (TIFFGetField(tiff,TIFFTAG_SOFTWARE,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_SOFTWARE,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"software",text);

       /*
```

Generate a backported patch for the SUSE target version.

[Assistant]
From b61d35eaccc0a7ddeff8a1c3abfcd0a43ccf210b Mon Sep 17 00:00:00 2001
From: Cristy <urban-warrior@imagemagick.org>
Date: Wed, 9 Nov 2016 15:57:28 -0500
Subject: [PATCH] https://github.com/ImageMagick/ImageMagick/issues/298

---
 MagickCore/property.c |  4 ++--
 coders/tiff.c         | 43 ++++++++++++++++++++++++++++---------------
 coders/txt.c          |  3 +--
 3 files changed, 31 insertions(+), 19 deletions(-)

Index: GraphicsMagick-1.3.20/coders/tiff.c
===================================================================
--- GraphicsMagick-1.3.20.orig/coders/tiff.c	2016-11-28 12:38:37.780341823 +0100
+++ GraphicsMagick-1.3.20/coders/tiff.c	2016-11-28 12:39:13.468935074 +0100
@@ -1727,31 +1727,31 @@ ReadTIFFImage(const ImageInfo *image_inf
       if (TIFFGetField(tiff,TIFFTAG_ARTIST,&text) == 1)
         (void) SetImageAttribute(image,"artist",text);

-      if (TIFFGetField(tiff,TIFFTAG_COPYRIGHT,&text) == 1) /* TIFFTAG_COPYRIGHT */
+      if (TIFFGetField(tiff,TIFFTAG_COPYRIGHT,&text) == 1 && (text != (char *) NULL)) /* TIFFTAG_COPYRIGHT */
         (void) SetImageAttribute(image,"copyright",text);

-      if (TIFFGetField(tiff,TIFFTAG_DATETIME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_DATETIME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"timestamp",text);

-      if (TIFFGetField(tiff,TIFFTAG_DOCUMENTNAME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_DOCUMENTNAME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"document",text);

-      if (TIFFGetField(tiff,TIFFTAG_HOSTCOMPUTER,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_HOSTCOMPUTER,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"hostcomputer",text);

-      if (TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"comment",text);

-      if (TIFFGetField(tiff,TIFFTAG_MAKE,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_MAKE,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"make",text);

-      if (TIFFGetField(tiff,TIFFTAG_MODEL,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_MODEL,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"model",text);

-      if (TIFFGetField(tiff,TIFFTAG_PAGENAME,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_PAGENAME,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"label",text);

-      if (TIFFGetField(tiff,TIFFTAG_SOFTWARE,&text) == 1)
+      if (TIFFGetField(tiff,TIFFTAG_SOFTWARE,&text) == 1 && (text != (char *) NULL))
         (void) SetImageAttribute(image,"software",text);

       /*


[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
- libxml2-2.9.1.orig/parser.c

## Target Source Code

### parser.c

#### region() [lines 55-141]
```c
/* #define DEBUG_PUSH */

static int htmlOmittedDefaultValue = 1;

xmlChar * htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
			     xmlChar end, xmlChar  end2, xmlChar end3);
static void htmlParseComment(htmlParserCtxtPtr ctxt);

/************************************************************************
 *									*
 *		Some factorized error routines				*
 *									*
 ************************************************************************/

/**
 * htmlErrMemory:
 * @ctxt:  an HTML parser context
 * @extra:  extra informations
 *
 * Handle a redefinition of attribute error
 */
static void
htmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
{
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
    if (ctxt != NULL) {
        ctxt->errNo = XML_ERR_NO_MEMORY;
        ctxt->instate = XML_PARSER_EOF;
        ctxt->disableSAX = 1;
    }
    if (extra)
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                        NULL, NULL, 0, 0,
                        "Memory allocation failed : %s\n", extra);
    else
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                        NULL, NULL, 0, 0, "Memory allocation failed\n");
}

/**
 * htmlParseErr:
 * @ctxt:  an HTML parser context
 * @error:  the error number
 * @msg:  the error message
 * @str1:  string infor
 * @str2:  string infor
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
static void
htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const xmlChar *str1, const xmlChar *str2)
{
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
    if (ctxt != NULL)
	ctxt->errNo = error;
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
                    XML_ERR_ERROR, NULL, 0,
		    (const char *) str1, (const char *) str2,
		    NULL, 0, 0,
		    msg, str1, str2);
    if (ctxt != NULL)
	ctxt->wellFormed = 0;
}

/**
 * htmlParseErrInt:
 * @ctxt:  an HTML parser context
 * @error:  the error number
 * @msg:  the error message
 * @val:  integer info
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
static void
htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, int val)
{
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
```

#### xmlGROW() [lines 2031-2120]
```c
		break;
	    c <<= 6;
	    c |= d & 0x3F;
	}

	/* assertion: c is a single UTF-4 value */
	if (c < 0x80) {
	    if (out + 1 >= outend)
		break;
	    *out++ = c;
	} else {
	    int len;
	    const htmlEntityDesc * ent;
	    const char *cp;
	    char nbuf[16];

	    /*
	     * Try to lookup a predefined HTML entity for it
	     */

	    ent = htmlEntityValueLookup(c);
	    if (ent == NULL) {
	      snprintf(nbuf, sizeof(nbuf), "#%u", c);
	      cp = nbuf;
	    }
	    else
	      cp = ent->name;
	    len = strlen(cp);
	    if (out + 2 + len >= outend)
		break;
	    *out++ = '&';
	    memcpy(out, cp, len);
	    out += len;
	    *out++ = ';';
	}
	processed = in;
    }
    *outlen = out - outstart;
    *inlen = processed - instart;
    return(0);
}

/**
 * htmlEncodeEntities:
 * @out:  a pointer to an array of bytes to store the result
 * @outlen:  the length of @out
 * @in:  a pointer to an array of UTF-8 chars
 * @inlen:  the length of @in
 * @quoteChar: the quote character to escape (' or ") or zero.
 *
 * Take a block of UTF-8 chars in and try to convert it to an ASCII
 * plus HTML entities block of chars out.
 *
 * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
 * The value of @inlen after return is the number of octets consumed
 *     as the return value is positive, else unpredictable.
 * The value of @outlen after return is the number of octets consumed.
 */
int
htmlEncodeEntities(unsigned char* out, int *outlen,
		   const unsigned char* in, int *inlen, int quoteChar) {
    const unsigned char* processed = in;
    const unsigned char* outend;
    const unsigned char* outstart = out;
    const unsigned char* instart = in;
    const unsigned char* inend;
    unsigned int c, d;
    int trailing;

    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL))
        return(-1);
    outend = out + (*outlen);
    inend = in + (*inlen);
    while (in < inend) {
	d = *in++;
	if      (d < 0x80)  { c= d; trailing= 0; }
	else if (d < 0xC0) {
	    /* trailing byte in leading position */
	    *outlen = out - outstart;
	    *inlen = processed - instart;
	    return(-2);
        } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
        else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
        else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
	else {
	    /* no chance for this in Ascii */
	    *outlen = out - outstart;
	    *inlen = processed - instart;
	    return(-2);
	}
```

#### xmlCreatePushParserCtxt() [lines 12503-7078]
```c

```

## Upstream Fix
```diff
From 28cd9cb747a94483f4aea7f0968d202c20bb4cfc Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Fri, 20 Nov 2015 14:55:30 +0800
Subject: [PATCH] Add xmlHaltParser() to stop the parser

The problem is doing it in a consistent and safe fashion
It's more complex than just setting ctxt->instate = XML_PARSER_EOF
Update the public function to reuse that new internal routine
---
 parser.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/parser.c b/parser.c
index da6e7292dc..b6e99b1d97 100644
--- a/parser.c
+++ b/parser.c
@@ -94,6 +94,8 @@ static xmlParserCtxtPtr
 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
 	                  const xmlChar *base, xmlParserCtxtPtr pctx);

+static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+
 /************************************************************************
  *									*
  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
@@ -12625,24 +12627,46 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
 #endif /* LIBXML_PUSH_ENABLED */

 /**
- * xmlStopParser:
+ * xmlHaltParser:
  * @ctxt:  an XML parser context
  *
- * Blocks further parser processing
+ * Blocks further parser processing don't override error
+ * for internal use
  */
-void
-xmlStopParser(xmlParserCtxtPtr ctxt) {
+static void
+xmlHaltParser(xmlParserCtxtPtr ctxt) {
     if (ctxt == NULL)
         return;
     ctxt->instate = XML_PARSER_EOF;
-    ctxt->errNo = XML_ERR_USER_STOP;
     ctxt->disableSAX = 1;
     if (ctxt->input != NULL) {
+        /*
+	 * in case there was a specific allocation deallocate before
+	 * overriding base
+	 */
+        if (ctxt->input->free != NULL) {
+	    ctxt->input->free((xmlChar *) ctxt->input->base);
+	    ctxt->input->free = NULL;
+	}
 	ctxt->input->cur = BAD_CAST"";
 	ctxt->input->base = ctxt->input->cur;
     }
 }

+/**
+ * xmlStopParser:
+ * @ctxt:  an XML parser context
+ *
+ * Blocks further parser processing
+ */
+void
+xmlStopParser(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    xmlHaltParser(ctxt);
+    ctxt->errNo = XML_ERR_USER_STOP;
+}
+
 /**
  * xmlCreateIOParserCtxt:
  * @sax:  a SAX handler
```

Generate a backported patch for the SUSE target version.

[Assistant]
From 28cd9cb747a94483f4aea7f0968d202c20bb4cfc Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Fri, 20 Nov 2015 14:55:30 +0800
Subject: Add xmlHaltParser() to stop the parser

The problem is doing it in a consistent and safe fashion
It's more complex than just setting ctxt->instate = XML_PARSER_EOF
Update the public function to reuse that new internal routine

From 35bcb1d758ed70aa7b257c9c3b3ff55e54e3d0da Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Fri, 20 Nov 2015 15:04:09 +0800
Subject: Detect incoherency on GROW

the current pointer to the input has to be between the base and end
if not stop everything we have an internal state error.

Index: libxml2-2.9.1/parser.c
===================================================================
--- libxml2-2.9.1.orig/parser.c
+++ libxml2-2.9.1/parser.c
@@ -94,6 +94,8 @@ static xmlParserCtxtPtr
 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
 	                  const xmlChar *base, xmlParserCtxtPtr pctx);

+static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+
 /************************************************************************
  *									*
  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
@@ -2070,9 +2072,16 @@ static void xmlGROW (xmlParserCtxtPtr ct
          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
-        ctxt->instate = XML_PARSER_EOF;
+        xmlHaltParser(ctxt);
+	return;
     }
     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+    if ((ctxt->input->cur > ctxt->input->end) ||
+        (ctxt->input->cur < ctxt->input->base)) {
+        xmlHaltParser(ctxt);
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
+	return;
+    }
     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 	    xmlPopInput(ctxt);
@@ -12542,25 +12551,47 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr
 #endif /* LIBXML_PUSH_ENABLED */

 /**
- * xmlStopParser:
+ * xmlHaltParser:
  * @ctxt:  an XML parser context
  *
- * Blocks further parser processing
+ * Blocks further parser processing don't override error
+ * for internal use
  */
-void
-xmlStopParser(xmlParserCtxtPtr ctxt) {
+static void
+xmlHaltParser(xmlParserCtxtPtr ctxt) {
     if (ctxt == NULL)
         return;
     ctxt->instate = XML_PARSER_EOF;
-    ctxt->errNo = XML_ERR_USER_STOP;
     ctxt->disableSAX = 1;
     if (ctxt->input != NULL) {
+        /*
+	 * in case there was a specific allocation deallocate before
+	 * overriding base
+	 */
+        if (ctxt->input->free != NULL) {
+	    ctxt->input->free((xmlChar *) ctxt->input->base);
+	    ctxt->input->free = NULL;
+	}
 	ctxt->input->cur = BAD_CAST"";
 	ctxt->input->base = ctxt->input->cur;
     }
 }

 /**
+ * xmlStopParser:
+ * @ctxt:  an XML parser context
+ *
+ * Blocks further parser processing
+ */
+void
+xmlStopParser(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    xmlHaltParser(ctxt);
+    ctxt->errNo = XML_ERR_USER_STOP;
+}
+
+/**
  * xmlCreateIOParserCtxt:
  * @sax:  a SAX handler
  * @user_data:  The user data returned on SAX callbacks


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

Unspecified vulnerability in the MySQL Server component in Oracle MySQL 5.1.x and 5.5.x allows remote authenticated users to affect confidentiality and availability via unknown vectors, a different vulnerability than CVE-2012-0118.

## Package
mariadb

## Files to modify
- mysys/mf_loadpath.c

## Upstream Fix
```diff
PATCH-P0-FIX-UPSTREAM: Fix possible buffer overflow

strncat function is used with n not depending on current length of string we
are appending to. Result might be buffer overflow.

Maintainer: Michal Hrusecky <mhrusecky@suse.cz>

Index: mysys/mf_loadpath.c
===================================================================
--- mysys/mf_loadpath.c.orig
+++ mysys/mf_loadpath.c
@@ -45,7 +45,7 @@ char * my_load_path(char * to, const cha
     if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
     {
       size_t length= strlen(buff);
-      (void) strmake(buff + length, path+is_cur, FN_REFLEN - length);
+      (void) strmake(buff + length, path+is_cur, FN_REFLEN - strlen(buff) - length);
     }
     else
       from= path;                           /* Return org file name */
```

Generate a backported patch for the SUSE target version.

[Assistant]
PATCH-P0-FIX-UPSTREAM: Fix possible buffer overflow

strncat function is used with n not depending on current length of string we
are appending to. Result might be buffer overflow.

Maintainer: Michal Hrusecky <mhrusecky@suse.cz>

Index: mysys/mf_loadpath.c
===================================================================
--- mysys/mf_loadpath.c.orig
+++ mysys/mf_loadpath.c
@@ -45,7 +45,7 @@ char * my_load_path(char * to, const cha
     if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
     {
       size_t length= strlen(buff);
-      (void) strmake(buff + length, path+is_cur, FN_REFLEN - length);
+      (void) strmake(buff + length, path+is_cur, FN_REFLEN - strlen(buff) - length);
     }
     else
       from= path;                           /* Return org file name */


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

The error function in Error.cc in poppler before 0.21.4 allows remote attackers to execute arbitrary commands via a PDF containing an escape sequence for a terminal emulator.

## Package
poppler

## Upstream Fix
```diff
From 71bad47ed6a36d825b0d08992c8db56845c71e40 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Sun, 09 Dec 2012 19:20:00 +0000
Subject: Filter stuff that might end up in the shell

Since it seems shells don't know how to filter stuff and might causing bad things to happen
---
diff --git a/poppler/Error.cc b/poppler/Error.cc
index 9d044bc..ce71820 100644
--- a/poppler/Error.cc
+++ b/poppler/Error.cc
@@ -16,6 +16,7 @@
 // Copyright (C) 2005, 2007 Jeff Muizelaar <jeff@infidigm.net>
 // Copyright (C) 2005 Albert Astals Cid <aacid@kde.org>
 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
+// Copyright (C) 2012 Marek Kasik <mkasik@redhat.com>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -59,7 +60,7 @@ void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,

 void CDECL error(ErrorCategory category, int pos, const char *msg, ...) {
   va_list args;
-  GooString *s;
+  GooString *s, *sanitized;

   // NB: this can be called before the globalParams object is created
   if (!errorCbk && globalParams && globalParams->getErrQuiet()) {
@@ -68,17 +69,29 @@ void CDECL error(ErrorCategory category, int pos, const char *msg, ...) {
   va_start(args, msg);
   s = GooString::formatv(msg, args);
   va_end(args);
+
+  sanitized = new GooString ();
+  for (int i = 0; i < s->getLength(); ++i) {
+    const char c = s->getChar(i);
+    if (c < (char)0x20 || c >= (char)0x7f) {
+      sanitized->appendf("<{0:02x}>", c & 0xff);
+    } else {
+      sanitized->append(c);
+    }
+  }
+
   if (errorCbk) {
-    (*errorCbk)(errorCbkData, category, pos, s->getCString());
+    (*errorCbk)(errorCbkData, category, pos, sanitized->getCString());
   } else {
     if (pos >= 0) {
       fprintf(stderr, "%s (%d): %s\n",
-	      errorCategoryNames[category], pos, s->getCString());
+	      errorCategoryNames[category], pos, sanitized->getCString());
     } else {
       fprintf(stderr, "%s: %s\n",
-	      errorCategoryNames[category], s->getCString());
+	      errorCategoryNames[category], sanitized->getCString());
     }
     fflush(stderr);
   }
   delete s;
+  delete sanitized;
 }
--
cgit v0.9.0.2-2-gbebe
```

Generate a backported patch for the SUSE target version.

[Assistant]
From 71bad47ed6a36d825b0d08992c8db56845c71e40 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Sun, 09 Dec 2012 19:20:00 +0000
Subject: Filter stuff that might end up in the shell

Since it seems shells don't know how to filter stuff and might causing bad things to happen
---
diff --git a/poppler/Error.cc b/poppler/Error.cc
index 9d044bc..ce71820 100644
--- a/poppler/Error.cc
+++ b/poppler/Error.cc
@@ -16,6 +16,7 @@
 // Copyright (C) 2005, 2007 Jeff Muizelaar <jeff@infidigm.net>
 // Copyright (C) 2005 Albert Astals Cid <aacid@kde.org>
 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
+// Copyright (C) 2012 Marek Kasik <mkasik@redhat.com>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -59,7 +60,7 @@ void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,

 void CDECL error(ErrorCategory category, int pos, const char *msg, ...) {
   va_list args;
-  GooString *s;
+  GooString *s, *sanitized;

   // NB: this can be called before the globalParams object is created
   if (!errorCbk && globalParams && globalParams->getErrQuiet()) {
@@ -68,17 +69,29 @@ void CDECL error(ErrorCategory category, int pos, const char *msg, ...) {
   va_start(args, msg);
   s = GooString::formatv(msg, args);
   va_end(args);
+
+  sanitized = new GooString ();
+  for (int i = 0; i < s->getLength(); ++i) {
+    const char c = s->getChar(i);
+    if (c < (char)0x20 || c >= (char)0x7f) {
+      sanitized->appendf("<{0:02x}>", c & 0xff);
+    } else {
+      sanitized->append(c);
+    }
+  }
+
   if (errorCbk) {
-    (*errorCbk)(errorCbkData, category, pos, s->getCString());
+    (*errorCbk)(errorCbkData, category, pos, sanitized->getCString());
   } else {
     if (pos >= 0) {
       fprintf(stderr, "%s (%d): %s\n",
-	      errorCategoryNames[category], pos, s->getCString());
+	      errorCategoryNames[category], pos, sanitized->getCString());
     } else {
       fprintf(stderr, "%s: %s\n",
-	      errorCategoryNames[category], s->getCString());
+	      errorCategoryNames[category], sanitized->getCString());
     }
     fflush(stderr);
   }
   delete s;
+  delete sanitized;
 }
--
cgit v0.9.0.2-2-gbebe


[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_rar.c
- libarchive/archive_read_support_format_rar.c

## Target Source Code

### libarchive/archive_read_support_format_rar.c

#### archive_read_format_rar_read_data() [lines 932-981]
```c
}

static int
archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
                                  size_t *size, int64_t *offset)
{
  struct rar *rar = (struct rar *)(a->format->data);
  int ret;

  if (rar->bytes_unconsumed > 0) {
      /* Consume as much as the decompressor actually used. */
      __archive_read_consume(a, rar->bytes_unconsumed);
      rar->bytes_unconsumed = 0;
  }

  if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
    *buff = NULL;
    *size = 0;
    *offset = rar->offset;
    if (*offset < rar->unp_size)
      *offset = rar->unp_size;
    return (ARCHIVE_EOF);
  }

  switch (rar->compression_method)
  {
  case COMPRESS_METHOD_STORE:
    ret = read_data_stored(a, buff, size, offset);
    break;

  case COMPRESS_METHOD_FASTEST:
  case COMPRESS_METHOD_FAST:
  case COMPRESS_METHOD_NORMAL:
  case COMPRESS_METHOD_GOOD:
  case COMPRESS_METHOD_BEST:
    ret = read_data_compressed(a, buff, size, offset);
    if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
    break;

  default:
    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                      "Unsupported compression method for RAR file.");
    ret = ARCHIVE_FATAL;
    break;
  }
  return (ret);
}

static int
```

## Upstream Fix
```diff
commit aab73938f8914f0def6cdd5d5be3f142ae7c77f6
Author: Tim Kientzle <kientzle@acm.org>
Date:   Tue Mar 3 20:17:37 2015 -0800

    Issue 410: Segfault on invalid rar archive

    Libarchive's API passes a void ** which is set by the format
    to the address of the entry data that was just read.

    In one particular case, the RAR decompression logic uses a
    non-NULL value here to indicate that the internal 128k decompression
    buffer has been filled.  But the RAR code took no steps to ensure
    that the value was set NULL on entry.  As a result, a crafted RAR
    file can trick libarchive into returning to the caller a 128k block
    of data starting at whatever value was previously in the caller's
    variable.

    The fix is simply to set *buff = NULL on entry to the RAR
    decompression logic.

Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c
@@ -944,8 +944,8 @@ archive_read_format_rar_read_data(struct
       rar->bytes_unconsumed = 0;
   }

+  *buff = NULL;
   if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
-    *buff = NULL;
     *size = 0;
     *offset = rar->offset;
     if (*offset < rar->unp_size)
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit aab73938f8914f0def6cdd5d5be3f142ae7c77f6
Author: Tim Kientzle <kientzle@acm.org>
Date:   Tue Mar 3 20:17:37 2015 -0800

    Issue 410: Segfault on invalid rar archive

    Libarchive's API passes a void ** which is set by the format
    to the address of the entry data that was just read.

    In one particular case, the RAR decompression logic uses a
    non-NULL value here to indicate that the internal 128k decompression
    buffer has been filled.  But the RAR code took no steps to ensure
    that the value was set NULL on entry.  As a result, a crafted RAR
    file can trick libarchive into returning to the caller a 128k block
    of data starting at whatever value was previously in the caller's
    variable.

    The fix is simply to set *buff = NULL on entry to the RAR
    decompression logic.

Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c
@@ -944,8 +944,8 @@ archive_read_format_rar_read_data(struct
       rar->bytes_unconsumed = 0;
   }

+  *buff = NULL;
   if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
-    *buff = NULL;
     *size = 0;
     *offset = rar->offset;
     if (*offset < rar->unp_size)


[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
- libxml2-2.9.1.orig/parser.c

## Target Source Code

### parser.c

#### xmlStringLenDecodeEntities() [lines 2818-2849]
```c
    /*
     * Name ::= (Letter | '_') (NameChar)*
     */
    if (CUR == '"') {
        NEXT;
	q = CUR_PTR;
	while (IS_PUBIDCHAR_CH(CUR)) NEXT;
	if (CUR != '"') {
	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
	                 "Unfinished PubidLiteral\n", NULL, NULL);
	} else {
	    ret = xmlStrndup(q, CUR_PTR - q);
	    NEXT;
	}
    } else if (CUR == '\'') {
        NEXT;
	q = CUR_PTR;
	while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\''))
	    NEXT;
	if (CUR != '\'') {
	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
	                 "Unfinished PubidLiteral\n", NULL, NULL);
	} else {
	    ret = xmlStrndup(q, CUR_PTR - q);
	    NEXT;
	}
    } else {
	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
	             "PubidLiteral \" or ' expected\n", NULL, NULL);
    }

    return(ret);
```

## Upstream Fix
```diff
From b1d34de46a11323fccffa9fadeb33be670d602f5 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Mon, 14 Mar 2016 17:19:44 +0800
Subject: [PATCH] Fix inappropriate fetch of entities content

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

libfuzzer regression testing exposed another case where the parser would
fetch content of an external entity while not in validating mode.
Plug that hole
---
 parser.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/parser.c b/parser.c
index c424fc1efd..f6d652ee28 100644
--- a/parser.c
+++ b/parser.c
@@ -2861,7 +2861,21 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
 	        ctxt->nbentities += ent->checked / 2;
 	    if (ent != NULL) {
                 if (ent->content == NULL) {
-		    xmlLoadEntityContent(ctxt, ent);
+		    /*
+		     * Note: external parsed entities will not be loaded,
+		     * it is not required for a non-validating parser to
+		     * complete external PEreferences coming from the
+		     * internal subset
+		     */
+		    if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
+			((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
+			(ctxt->validate != 0)) {
+			xmlLoadEntityContent(ctxt, ent);
+		    } else {
+			xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+		  "not validating will not read content for PE entity %s\n",
+		                      ent->name, NULL);
+		    }
 		}
 		ctxt->depth++;
 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
```

Generate a backported patch for the SUSE target version.

[Assistant]
From b1d34de46a11323fccffa9fadeb33be670d602f5 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Mon, 14 Mar 2016 17:19:44 +0800
Subject: Fix inappropriate fetch of entities content

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

libfuzzer regression testing exposed another case where the parser would
fetch content of an external entity while not in validating mode.
Plug that hole
---
 parser.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

Index: libxml2-2.9.1/parser.c
===================================================================
--- libxml2-2.9.1.orig/parser.c
+++ libxml2-2.9.1/parser.c
@@ -2837,7 +2837,21 @@ xmlStringLenDecodeEntities(xmlParserCtxt
 	        ctxt->nbentities += ent->checked / 2;
 	    if (ent != NULL) {
                 if (ent->content == NULL) {
-		    xmlLoadEntityContent(ctxt, ent);
+		    /*
+		     * Note: external parsed entities will not be loaded,
+		     * it is not required for a non-validating parser to
+		     * complete external PEreferences coming from the
+		     * internal subset
+		     */
+		    if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
+			((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
+			(ctxt->validate != 0)) {
+			xmlLoadEntityContent(ctxt, ent);
+		    } else {
+			xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+		  "not validating will not read content for PE entity %s\n",
+		                      ent->name, NULL);
+		    }
 		}
 		ctxt->depth++;
 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,