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

Squid 3.2.x before 3.2.14, 3.3.x before 3.3.14, 3.4.x before 3.4.13, and 3.5.x before 3.5.4, when configured with client-first SSL-bump, do not properly validate the domain or hostname fields of X.509 certificates, which allows man-in-the-middle attackers to spoof SSL servers via a valid certificate.

## Package
squid

## Files to modify
- src/MemObject.h
- squid-3.3.13.orig/src/MemObject.h
- src/HttpRequest.h
- src/http.h
- squid-3.3.13.orig/src/http.h

## Upstream Fix
```diff
Index: squid-3.3.13/src/HttpRequest.cc
===================================================================
--- squid-3.3.13.orig/src/HttpRequest.cc
+++ squid-3.3.13/src/HttpRequest.cc
@@ -112,7 +112,7 @@ HttpRequest::init()
     errDetail = ERR_DETAIL_NONE;
     peer_login = NULL;		// not allocated/deallocated by this class
     peer_domain = NULL;		// not allocated/deallocated by this class
-    vary_headers = NULL;
+    vary_headers = SBuf();
     myportname = null_string;
     tag = null_string;
 #if USE_AUTH
@@ -145,8 +145,7 @@ HttpRequest::clean()
 #endif
     safe_free(canonical);

-    safe_free(vary_headers);
-
+    vary_headers.clear();
     urlpath.clean();

     header.clean();
@@ -220,7 +219,7 @@ HttpRequest::clone() const

     copy->lastmod = lastmod;
     copy->etag = etag;
-    copy->vary_headers = vary_headers ? xstrdup(vary_headers) : NULL;
+    copy->vary_headers = vary_headers;
     // XXX: what to do with copy->peer_domain?

     copy->tag = tag;
Index: squid-3.3.13/src/HttpRequest.h
===================================================================
--- squid-3.3.13.orig/src/HttpRequest.h
+++ squid-3.3.13/src/HttpRequest.h
@@ -38,6 +38,7 @@
 #include "HttpMsg.h"
 #include "HttpRequestMethod.h"
 #include "RequestFlags.h"
+#include "SBuf.h"

 #if USE_AUTH
 #include "auth/UserRequest.h"
@@ -191,7 +192,8 @@ public:

     time_t lastmod;		/* Used on refreshes */

-    const char *vary_headers;	/* Used when varying entities are detected. Changes how the store key is calculated */
+    /// The variant second-stage cache key. Generated from Vary header pattern for this request.
+    SBuf vary_headers;

     char *peer_domain;		/* Configured peer forceddomain */

Index: squid-3.3.13/src/MemObject.cc
===================================================================
--- squid-3.3.13.orig/src/MemObject.cc
+++ squid-3.3.13/src/MemObject.cc
@@ -138,8 +138,6 @@ MemObject::~MemObject()
     safe_free(url);

     safe_free(log_url);    /* XXX account log_url */
-
-    safe_free(vary_headers);
 }

 void
@@ -226,8 +224,8 @@ MemObject::stat(MemBuf * mb) const
 {
     mb->Printf("\t%s %s\n",
                RequestMethodStr(method), log_url);
-    if (vary_headers)
-        mb->Printf("\tvary_headers: %s\n", vary_headers);
+    if (!vary_headers.isEmpty())
+        mb->Printf("\tvary_headers: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(vary_headers));
     mb->Printf("\tinmem_lo: %" PRId64 "\n", inmem_lo);
     mb->Printf("\tinmem_hi: %" PRId64 "\n", data_hdr.endOffset());
     mb->Printf("\tswapout: %" PRId64 " bytes queued\n",
Index: squid-3.3.13/src/MemObject.h
===================================================================
--- squid-3.3.13.orig/src/MemObject.h
+++ squid-3.3.13/src/MemObject.h
@@ -35,6 +35,7 @@
 #include "dlink.h"
 #include "HttpRequestMethod.h"
 #include "RemovalPolicy.h"
+#include "SBuf.h"
 #include "stmem.h"
 #include "StoreIOBuffer.h"
 #include "StoreIOState.h"
@@ -147,7 +148,7 @@ public:
     unsigned int chksum;
 #endif

-    const char *vary_headers;
+    SBuf vary_headers;

     void delayRead(DeferredRead const &);
     void kickReads();
Index: squid-3.3.13/src/MemStore.cc
===================================================================
--- squid-3.3.13.orig/src/MemStore.cc
+++ squid-3.3.13/src/MemStore.cc
@@ -310,7 +310,7 @@ MemStore::considerKeeping(StoreEntry &e)
         return;
     }

-    if (e.mem_obj->vary_headers) {
+    if (!e.mem_obj->vary_headers.isEmpty()) {
         // XXX: We must store/load SerialisedMetaData to cache Vary in RAM
         debugs(20, 5, "Vary not yet supported: " << e.mem_obj->vary_headers);
         return;
Index: squid-3.3.13/src/StoreMetaVary.cc
===================================================================
--- squid-3.3.13.orig/src/StoreMetaVary.cc
+++ squid-3.3.13/src/StoreMetaVary.cc
@@ -41,14 +41,14 @@ StoreMetaVary::checkConsistency(StoreEnt
 {
     assert (getType() == STORE_META_VARY_HEADERS);

-    if (!e->mem_obj->vary_headers) {
+    if (e->mem_obj->vary_headers.isEmpty()) {
         /* XXX separate this mutator from the query */
         /* Assume the object is OK.. remember the vary request headers */
-        e->mem_obj->vary_headers = xstrdup((char *)value);
+        e->mem_obj->vary_headers.assign(static_cast<const char*>(value), length);
         return true;
     }

-    if (strcmp(e->mem_obj->vary_headers, (char *)value) != 0)
+    if (e->mem_obj->vary_headers.cmp(static_cast<const char*>(value), length) != 0)
         return false;

     return true;
Index: squid-3.3.13/src/client_side.cc
===================================================================
--- squid-3.3.13.orig/src/client_side.cc
+++ squid-3.3.13/src/client_side.cc
@@ -4178,20 +4178,19 @@ clientHttpConnectionsClose(void)
 int
 varyEvaluateMatch(StoreEntry * entry, HttpRequest * request)
 {
-    const char *vary = request->vary_headers;
+    SBuf vary(request->vary_headers);
     int has_vary = entry->getReply()->header.has(HDR_VARY);
 #if X_ACCELERATOR_VARY
-
     has_vary |=
         entry->getReply()->header.has(HDR_X_ACCELERATOR_VARY);
 #endif

-    if (!has_vary || !entry->mem_obj->vary_headers) {
-        if (vary) {
+    if (!has_vary || entry->mem_obj->vary_headers.isEmpty()) {
+        if (!vary.isEmpty()) {
             /* Oops... something odd is going on here.. */
             debugs(33, DBG_IMPORTANT, "varyEvaluateMatch: Oops. Not a Vary object on second attempt, '" <<
                    entry->mem_obj->url << "' '" << vary << "'");
-            safe_free(request->vary_headers);
+            request->vary_headers.clear();
             return VARY_CANCEL;
         }

@@ -4205,8 +4204,8 @@ varyEvaluateMatch(StoreEntry * entry, Ht
          */
         vary = httpMakeVaryMark(request, entry->getReply());

-        if (vary) {
-            request->vary_headers = xstrdup(vary);
+        if (!vary.isEmpty()) {
+            request->vary_headers = vary;
             return VARY_OTHER;
         } else {
             /* Ouch.. we cannot handle this kind of variance */
@@ -4214,18 +4213,18 @@ varyEvaluateMatch(StoreEntry * entry, Ht
             return VARY_CANCEL;
         }
     } else {
-        if (!vary) {
+        if (vary.isEmpty()) {
             vary = httpMakeVaryMark(request, entry->getReply());

-            if (vary)
-                request->vary_headers = xstrdup(vary);
+            if (!vary.isEmpty())
+                request->vary_headers = vary;
         }

-        if (!vary) {
+        if (vary.isEmpty()) {
             /* Ouch.. we cannot handle this kind of variance */
             /* XXX This cannot really happen, but just to be complete */
             return VARY_CANCEL;
-        } else if (strcmp(vary, entry->mem_obj->vary_headers) == 0) {
+        } else if (vary.cmp(entry->mem_obj->vary_headers) == 0) {
             return VARY_MATCH;
         } else {
             /* Oops.. we have already been here and still haven't
Index: squid-3.3.13/src/client_side_reply.cc
===================================================================
--- squid-3.3.13.orig/src/client_side_reply.cc
+++ squid-3.3.13/src/client_side_reply.cc
@@ -982,8 +982,8 @@ clientReplyContext::purgeDoPurgeHead(Sto

     /* And for Vary, release the base URI if none of the headers was included in the request */

-    if (http->request->vary_headers
-            && !strstr(http->request->vary_headers, "=")) {
+    if (!http->request->vary_headers.isEmpty()
+            && http->request->vary_headers.find('=') != SBuf::npos) {
         StoreEntry *entry = storeGetPublic(urlCanonical(http->request), METHOD_GET);

         if (entry) {
Index: squid-3.3.13/src/http.cc
===================================================================
--- squid-3.3.13.orig/src/http.cc
+++ squid-3.3.13/src/http.cc
@@ -598,9 +598,9 @@ HttpStateData::cacheableReply()
 /*
  * For Vary, store the relevant request headers as
  * virtual headers in the reply
- * Returns false if the variance cannot be sto
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: squid-3.3.13/src/HttpRequest.cc
===================================================================
--- squid-3.3.13.orig/src/HttpRequest.cc
+++ squid-3.3.13/src/HttpRequest.cc
@@ -112,7 +112,7 @@ HttpRequest::init()
     errDetail = ERR_DETAIL_NONE;
     peer_login = NULL;		// not allocated/deallocated by this class
     peer_domain = NULL;		// not allocated/deallocated by this class
-    vary_headers = NULL;
+    vary_headers = SBuf();
     myportname = null_string;
     tag = null_string;
 #if USE_AUTH
@@ -145,8 +145,7 @@ HttpRequest::clean()
 #endif
     safe_free(canonical);

-    safe_free(vary_headers);
-
+    vary_headers.clear();
     urlpath.clean();

     header.clean();
@@ -220,7 +219,7 @@ HttpRequest::clone() const

     copy->lastmod = lastmod;
     copy->etag = etag;
-    copy->vary_headers = vary_headers ? xstrdup(vary_headers) : NULL;
+    copy->vary_headers = vary_headers;
     // XXX: what to do with copy->peer_domain?

     copy->tag = tag;
Index: squid-3.3.13/src/HttpRequest.h
===================================================================
--- squid-3.3.13.orig/src/HttpRequest.h
+++ squid-3.3.13/src/HttpRequest.h
@@ -38,6 +38,7 @@
 #include "HttpMsg.h"
 #include "HttpRequestMethod.h"
 #include "RequestFlags.h"
+#include "SBuf.h"

 #if USE_AUTH
 #include "auth/UserRequest.h"
@@ -191,7 +192,8 @@ public:

     time_t lastmod;		/* Used on refreshes */

-    const char *vary_headers;	/* Used when varying entities are detected. Changes how the store key is calculated */
+    /// The variant second-stage cache key. Generated from Vary header pattern for this request.
+    SBuf vary_headers;

     char *peer_domain;		/* Configured peer forceddomain */

Index: squid-3.3.13/src/MemObject.cc
===================================================================
--- squid-3.3.13.orig/src/MemObject.cc
+++ squid-3.3.13/src/MemObject.cc
@@ -138,8 +138,6 @@ MemObject::~MemObject()
     safe_free(url);

     safe_free(log_url);    /* XXX account log_url */
-
-    safe_free(vary_headers);
 }

 void
@@ -226,8 +224,8 @@ MemObject::stat(MemBuf * mb) const
 {
     mb->Printf("\t%s %s\n",
                RequestMethodStr(method), log_url);
-    if (vary_headers)
-        mb->Printf("\tvary_headers: %s\n", vary_headers);
+    if (!vary_headers.isEmpty())
+        mb->Printf("\tvary_headers: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(vary_headers));
     mb->Printf("\tinmem_lo: %" PRId64 "\n", inmem_lo);
     mb->Printf("\tinmem_hi: %" PRId64 "\n", data_hdr.endOffset());
     mb->Printf("\tswapout: %" PRId64 " bytes queued\n",
Index: squid-3.3.13/src/MemObject.h
===================================================================
--- squid-3.3.13.orig/src/MemObject.h
+++ squid-3.3.13/src/MemObject.h
@@ -35,6 +35,7 @@
 #include "dlink.h"
 #include "HttpRequestMethod.h"
 #include "RemovalPolicy.h"
+#include "SBuf.h"
 #include "stmem.h"
 #include "StoreIOBuffer.h"
 #include "StoreIOState.h"
@@ -147,7 +148,7 @@ public:
     unsigned int chksum;
 #endif

-    const char *vary_headers;
+    SBuf vary_headers;

     void delayRead(DeferredRead const &);
     void kickReads();
Index: squid-3.3.13/src/MemStore.cc
===================================================================
--- squid-3.3.13.orig/src/MemStore.cc
+++ squid-3.3.13/src/MemStore.cc
@@ -310,7 +310,7 @@ MemStore::considerKeeping(StoreEntry &e)
         return;
     }

-    if (e.mem_obj->vary_headers) {
+    if (!e.mem_obj->vary_headers.isEmpty()) {
         // XXX: We must store/load SerialisedMetaData to cache Vary in RAM
         debugs(20, 5, "Vary not yet supported: " << e.mem_obj->vary_headers);
         return;
Index: squid-3.3.13/src/StoreMetaVary.cc
===================================================================
--- squid-3.3.13.orig/src/StoreMetaVary.cc
+++ squid-3.3.13/src/StoreMetaVary.cc
@@ -41,14 +41,14 @@ StoreMetaVary::checkConsistency(StoreEnt
 {
     assert (getType() == STORE_META_VARY_HEADERS);

-    if (!e->mem_obj->vary_headers) {
+    if (e->mem_obj->vary_headers.isEmpty()) {
         /* XXX separate this mutator from the query */
         /* Assume the object is OK.. remember the vary request headers */
-        e->mem_obj->vary_headers = xstrdup((char *)value);
+        e->mem_obj->vary_headers.assign(static_cast<const char*>(value), length);
         return true;
     }

-    if (strcmp(e->mem_obj->vary_headers, (char *)value) != 0)
+    if (e->mem_obj->vary_headers.cmp(static_cast<const char*>(value), length) != 0)
         return false;

     return true;
Index: squid-3.3.13/src/client_side.cc
===================================================================
--- squid-3.3.13.orig/src/client_side.cc
+++ squid-3.3.13/src/client_side.cc
@@ -4178,20 +4178,19 @@ clientHttpConnectionsClose(void)
 int
 varyEvaluateMatch(StoreEntry * entry, HttpRequest * request)
 {
-    const char *vary = request->vary_headers;
+    SBuf vary(request->vary_headers);
     int has_vary = entry->getReply()->header.has(HDR_VARY);
 #if X_ACCELERATOR_VARY
-
     has_vary |=
         entry->getReply()->header.has(HDR_X_ACCELERATOR_VARY);
 #endif

-    if (!has_vary || !entry->mem_obj->vary_headers) {
-        if (vary) {
+    if (!has_vary || entry->mem_obj->vary_headers.isEmpty()) {
+        if (!vary.isEmpty()) {
             /* Oops... something odd is going on here.. */
             debugs(33, DBG_IMPORTANT, "varyEvaluateMatch: Oops. Not a Vary object on second attempt, '" <<
                    entry->mem_obj->url << "' '" << vary << "'");
-            safe_free(request->vary_headers);
+            request->vary_headers.clear();
             return VARY_CANCEL;
         }

@@ -4205,8 +4204,8 @@ varyEvaluateMatch(StoreEntry * entry, Ht
          */
         vary = httpMakeVaryMark(request, entry->getReply());

-        if (vary) {
-            request->vary_headers = xstrdup(vary);
+        if (!vary.isEmpty()) {
+            request->vary_headers = vary;
             return VARY_OTHER;
         } else {
             /* Ouch.. we cannot handle this kind of variance */
@@ -4214,18 +4213,18 @@ varyEvaluateMatch(StoreEntry * entry, Ht
             return VARY_CANCEL;
         }
     } else {
-        if (!vary) {
+        if (vary.isEmpty()) {
             vary = httpMakeVaryMark(request, entry->getReply());

-            if (vary)
-                request->vary_headers = xstrdup(vary);
+            if (!vary.isEmpty())
+                request->vary_headers = vary;
         }

-        if (!vary) {
+        if (vary.isEmpty()) {
             /* Ouch.. we cannot handle this kind of variance */
             /* XXX This cannot really happen, but just to be complete */
             return VARY_CANCEL;
-        } else if (strcmp(vary, entry->mem_obj->vary_headers) == 0) {
+        } else if (vary.cmp(entry->mem_obj->vary_headers) == 0) {
             return VARY_MATCH;
         } else {
             /* Oops.. we have already been here and still haven't
Index: squid-3.3.13/src/client_side_reply.cc
===================================================================
--- squid-3.3.13.orig/src/client_side_reply.cc
+++ squid-3.3.13/src/client_side_reply.cc
@@ -982,8 +982,8 @@ clientReplyContext::purgeDoPurgeHead(Sto

     /* And for Vary, release the base URI if none of the headers was included in the request */

-    if (http->request->vary_headers
-            && !strstr(http->request->vary_headers, "=")) {
+    if (!http->request->vary_headers.isEmpty()
+            && http->request->vary_headers.find('=') != SBuf::npos) {
         StoreEntry *entry = storeGetPublic(urlCanonical(http->request), METHOD_GET);

         if (entry) {
Index: squid-3.3.13/src/http.cc
===================================================================
--- squid-3.3.13.orig/src/http.cc
+++ squid-3.3.13/src/http.cc
@@ -598,9 +598,9 @@ HttpStateData::cacheableReply()
 /*
  * For Vary, store the relevant request headers as
  * virtual headers in the reply
- * Returns false if the variance cannot be stored
+ * Returns an empty SBuf if the variance cannot be stored
  */
-const char *
+SBuf
 httpMakeVaryMark(HttpRequest * request, HttpReply const * reply)
 {
     String vary, hdr;
@@ -608,9 +608,9 @@ httpMakeVaryMark(HttpRequest * request,
     const char *item;
     const char *value;
     int ilen;
-    static String vstr;
+    SBuf vstr;
+    static const SBuf asterisk("*");

-    vstr.clean();
     vary = reply->header.getList(HDR_VARY);

     while (strListGetItem(&vary, ',', &item, &ilen, &pos)) {
@@ -621,11 +621,13 @@ httpMakeVaryMark(HttpRequest * request,
         if (strcmp(name, "*") == 0) {
             /* Can not handle "Vary: *" withtout ETag support */
             safe_free(name);
-            vstr.clean();
+            vstr.clear();
             break;
         }

-        strListAdd(&vstr, name, ',');
+        if (!vstr.isEmpty())
+            vstr.append(", ", 2);
+        vstr.append(name);
         hdr = request->header.getByName(name);
         safe_free(name);
         value = hdr.termedBuf();
@@ -650,7 +652,17 @@ httpMakeVaryMark(HttpRequest * request,
         char *name = (char *)xmalloc(ilen + 1);
         xstrncpy(name, item, ilen + 1);
         Tolower(name);
-        strListAdd(&vstr, name, ',');
+
+        if (strcmp(name, "*") == 0) {
+            /* Can not handle "Vary: *" withtout ETag support */
+            safe_free(name);
+            vstr.clear();
+            break;
+        }
+
+        if (!vstr.isEmpty())
+            vstr.append(", ", 2);
+        vstr.append(name);
         hdr = request->header.getByName(name);
         safe_free(name);
         value = hdr.termedBuf();
@@ -668,8 +680,8 @@ httpMakeVaryMark(HttpRequest * request,
     vary.clean();
 #endif

-    debugs(11, 3, "httpMakeVaryMark: " << vstr);
-    return vstr.termedBuf();
+    debugs(11, 3, vstr);
+    return vstr;
 }

 void
@@ -938,16 +950,16 @@ HttpStateData::haveParsedReplyHeaders()
             || rep->header.has(HDR_X_ACCELERATOR_VARY)
 #endif
        ) {
-        const char *vary = httpMakeVaryMark(request, rep);
+        const SBuf vary(httpMakeVaryMark(request, rep));

-        if (!vary) {
+        if (vary.isEmpty()) {
             entry->makePrivate();
             if (!fwd->reforwardableStatus(rep->sline.status))
                 EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
             goto no_cache;
         }

-        entry->mem_obj->vary_headers = xstrdup(vary);
+        entry->mem_obj->vary_headers = vary;
     }

     /*
Index: squid-3.3.13/src/http.h
===================================================================
--- squid-3.3.13.orig/src/http.h
+++ squid-3.3.13/src/http.h
@@ -34,6 +34,7 @@

 #include "comm.h"
 #include "HttpStateFlags.h"
+#include "SBuf.h"
 #include "Server.h"

 class ChunkedCodingParser;
@@ -138,6 +139,6 @@ private:

 int httpCachable(const HttpRequestMethod&);
 void httpStart(FwdState *);
-const char *httpMakeVaryMark(HttpRequest * request, HttpReply const * reply);
+SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply);

 #endif /* SQUID_HTTP_H */
Index: squid-3.3.13/src/store.cc
===================================================================
--- squid-3.3.13.orig/src/store.cc
+++ squid-3.3.13/src/store.cc
@@ -729,15 +729,15 @@ StoreEntry::setPublicKey()
     if (mem_obj->request) {
         HttpRequest *request = mem_obj->request;

-        if (!mem_obj->vary_headers) {
+        if (mem_obj->vary_headers.isEmpty()) {
             /* First handle the case where the object no longer varies */
-            safe_free(request->vary_headers);
+            request->vary_headers.clear();
         } else {
-            if (request->vary_headers && strcmp(request->vary_headers, mem_obj->vary_headers) != 0) {
+            if (!request->vary_headers.isEmpty() && request->vary_headers.cmp(mem_obj->vary_headers) != 0) {
                 /* Oops.. the variance has changed. Kill the base object
                  * to record the new variance key
                  */
-                safe_free(request->vary_headers);       /* free old "bad" variance key */
+                request->vary_headers.clear();       /* free old "bad" variance key */
                 StoreEntry *pe = storeGetPublic(mem_obj->url, mem_obj->method);

                 if (pe)
@@ -745,17 +745,14 @@ StoreEntry::setPublicKey()
             }

             /* Make sure the request knows the variance status */
-            if (!request->vary_headers) {
-                const char *vary = httpMakeVaryMark(request, mem_obj->getReply());
-
-                if (vary)
-                    request->vary_headers = xstrdup(vary);
+            if (request->vary_headers.isEmpty()) {
+                request->vary_headers = httpMakeVaryMark(request, mem_obj->getReply());
             }
         }

         // TODO: storeGetPublic() calls below may create unlocked entries.
         // We should add/use storeHas() API or lock/unlock those entries.
-        if (mem_obj->vary_headers && !storeGetPublic(mem_obj->url, mem_obj->method)) {
+        if (!mem_obj->vary_headers.isEmpty() && !storeGetPublic(mem_obj->url, mem_obj->method)) {
             /* Create "vary" base object */
             String vary;
             StoreEntry *pe = storeCreateEntry(mem_obj->url, mem_obj->log_url, request->flags, request->method);
Index: squid-3.3.13/src/store_key_md5.cc
===================================================================
--- squid-3.3.13.orig/src/store_key_md5.cc
+++ squid-3.3.13/src/store_key_md5.cc
@@ -145,8 +145,8 @@ storeKeyPublicByRequestMethod(HttpReques
     SquidMD5Update(&M, &m, sizeof(m));
     SquidMD5Update(&M, (unsigned char *) url, strlen(url));

-    if (request->vary_headers)
-        SquidMD5Update(&M, (unsigned char *) request->vary_headers, strlen(request->vary_headers));
+    if (!request->vary_headers.isEmpty())
+        SquidMD5Update(&M, request->vary_headers.rawContent(), request->vary_headers.length());

     SquidMD5Final(digest, &M);

Index: squid-3.3.13/src/store_swapmeta.cc
===================================================================
--- squid-3.3.13.orig/src/store_swapmeta.cc
+++ squid-3.3.13/src/store_swapmeta.cc
@@ -63,7 +63,6 @@ storeSwapMetaBuild(StoreEntry * e)
     tlv *TLV = NULL;		/* we'll return this */
     tlv **T = &TLV;
     const char *url;
-    const char *vary;
     assert(e->mem_obj != NULL);
     const int64_t objsize = e->mem_obj->expectedReplySize();
     assert(e->swap_status == SWAPOUT_WRITING);
@@ -103,10 +102,12 @@ storeSwapMetaBuild(StoreEntry * e)
     }

     T = StoreMeta::Add(T, t);
-    vary = e->mem_obj->vary_headers;
+    SBuf vary(e->mem_obj->vary_headers);

-    if (vary) {
-        t =StoreMeta::Factory(STORE_META_VARY_HEADERS, strlen(vary) + 1, vary);
+    if (!vary.isEmpty()) {
+        // TODO: do we still need +1 here? StoreMetaVary::checkConsistency
+        //       no longer relies on nul-termination, but other things might.
+        t = StoreMeta::Factory(STORE_META_VARY_HEADERS, vary.length() + 1, vary.c_str());

         if (!t) {
             storeSwapTLVFree(TLV);
Index: squid-3.3.13/src/tests/stub_MemObject.cc
===================================================================
--- squid-3.3.13.orig/src/tests/stub_MemObject.cc
+++ squid-3.3.13/src/tests/stub_MemObject.cc
@@ -32,7 +32,6 @@ MemObject::MemObject(char const *, char
         id(0),
         object_sz(-1),
         swap_hdr_sz(0),
-        vary_headers(NULL),
         _reply(NULL)
 {
     memset(&clients, 0, sizeof(clients));
Index: squid-3.3.13/src/tests/stub_http.cc
===================================================================
--- squid-3.3.13.orig/src/tests/stub_http.cc
+++ squid-3.3.13/src/tests/stub_http.cc
@@ -6,4 +6,4 @@
 #define STUB_API "http.cc"
 #include "tests/STUB.h"

-const char * httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) STUB_RETVAL(NULL)
+SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) STUB_RETVAL(SBuf())


[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_mtree.c
- libarchive-3.1.2.orig/libarchive/archive_platform.h
- libarchive/archive_pack_dev.h
- libarchive/archive_platform.h
- libarchive/archive_read_support_format_mtree.c

## Target Source Code

### libarchive/CMakeLists.txt

#### SET() [lines 1-82]
```c

############################################
#
# How to build libarchive
#
############################################

# Public headers
SET(include_HEADERS
  archive.h
  archive_entry.h
)

# Sources and private headers
SET(libarchive_SOURCES
  archive_acl.c
  archive_check_magic.c
  archive_cmdline.c
  archive_cmdline_private.h
  archive_crc32.h
  archive_crypto.c
  archive_crypto_private.h
  archive_endian.h
  archive_entry.c
  archive_entry.h
  archive_entry_copy_stat.c
  archive_entry_link_resolver.c
  archive_entry_locale.h
  archive_entry_private.h
  archive_entry_sparse.c
  archive_entry_stat.c
  archive_entry_strmode.c
  archive_entry_xattr.c
  archive_getdate.c
  archive_match.c
  archive_options.c
  archive_options_private.h
  archive_pathmatch.c
  archive_pathmatch.h
  archive_platform.h
  archive_ppmd_private.h
  archive_ppmd7.c
  archive_ppmd7_private.h
  archive_private.h
  archive_rb.c
  archive_rb.h
  archive_read.c
  archive_read_append_filter.c
  archive_read_data_into_fd.c
  archive_read_disk_entry_from_file.c
  archive_read_disk_posix.c
  archive_read_disk_private.h
  archive_read_disk_set_standard_lookup.c
  archive_read_extract.c
  archive_read_open_fd.c
  archive_read_open_file.c
  archive_read_open_filename.c
  archive_read_open_memory.c
  archive_read_private.h
  archive_read_set_format.c
  archive_read_set_options.c
  archive_read_support_filter_all.c
  archive_read_support_filter_bzip2.c
  archive_read_support_filter_compress.c
  archive_read_support_filter_gzip.c
  archive_read_support_filter_grzip.c
  archive_read_support_filter_lrzip.c
  archive_read_support_filter_lzop.c
  archive_read_support_filter_none.c
  archive_read_support_filter_program.c
  archive_read_support_filter_rpm.c
  archive_read_support_filter_uu.c
  archive_read_support_filter_xz.c
  archive_read_support_format_7zip.c
  archive_read_support_format_all.c
  archive_read_support_format_ar.c
  archive_read_support_format_by_code.c
  archive_read_support_format_cab.c
  archive_read_support_format_cpio.c
  archive_read_support_format_empty.c
  archive_read_su
/* ... truncated ... */
```

### libarchive/archive_platform.h

#### region() [lines 27-122]
```c

/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */

/*
 * This header is the first thing included in any of the libarchive
 * source files.  As far as possible, platform-specific issues should
 * be dealt with here and not within individual source files.  I'm
 * actively trying to minimize #if blocks within the main source,
 * since they obfuscate the code.
 */

#ifndef ARCHIVE_PLATFORM_H_INCLUDED
#define	ARCHIVE_PLATFORM_H_INCLUDED

/* archive.h and archive_entry.h require this. */
#define	__LIBARCHIVE_BUILD 1

#if defined(PLATFORM_CONFIG_H)
/* Use hand-built config.h in environments that need it. */
#include PLATFORM_CONFIG_H
#elif defined(HAVE_CONFIG_H)
/* Most POSIX platforms use the 'configure' script to build config.h */
#include "config.h"
#else
/* Warn if the library hasn't been (automatically or manually) configured. */
#error Oops: No config.h and no pre-built configuration in archive_platform.h.
#endif

/* It should be possible to get rid of this by extending the feature-test
 * macros to cover Windows API functions, probably along with non-trivial
 * refactoring of code to find structures that sit more cleanly on top of
 * either Windows or Posix APIs. */
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
#include "archive_windows.h"
#endif

/*
 * The config files define a lot of feature macros.  The following
 * uses those macros to select/define replacements and include key
 * headers as required.
 */

/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif

/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define	__FBSDID(a)     struct _undefined_hack
#endif

/* Try to get standard C99-style integer type definitions. */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#if HAVE_STDINT_H
#include <stdint.h>
#endif

/* Borland warns about its own constants!  */
#if defined(__BORLANDC__)
# if HAVE_DECL_UINT64_MAX
#  undef	UINT64_MAX
#  undef	HAVE_DECL_UINT64_MAX
# endif
# if HAVE_DECL_UINT64_MIN
#  undef	UINT64_MIN
#  undef	HAVE_DE
/* ... truncated ... */
```

### libarchive/archive_read_support_format_mtree.c

#### __FBSDID() [lines 12-98]
```c
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");

#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stddef.h>
/* #include <stdint.h> */ /* See archive_platform.h */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_string.h"

#ifndef O_BINARY
#define	O_BINARY 0
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC	0
#endif

#define	MTREE_HAS_DEVICE	0x0001
#define	MTREE_HAS_FFLAGS	0x0002
#define	MTREE_HAS_GID		0x0004
#define	MTREE_HAS_GNAME		0x0008
#define	MTREE_HAS_MTIME		0x0010
#define	MTREE_HAS_NLINK		0x0020
#define	MTREE_HAS_PERM		0x0040
#define	MTREE_HAS_SIZE		0x0080
#define	MTREE_HAS_TYPE		0x0100
#define	MTREE_HAS_UID		0x0200
#define	MTREE_HAS_UNAME		0x0400

#define	MTREE_HAS_OPTIONAL	0x0800
#define	MTREE_HAS_NOCHANGE	0x1000 /* Free
/* ... truncated ... */
```

### Makefile.am

#### region() [lines 71-157]
```c
distclean-local:
	-rm -rf .ref
	-rm -rf autom4te.cache/
	-rm -f *~
	-[ -f libarchive/Makefile ] && cd libarchive && make clean
	-[ -f libarchive/test/Makefile ] && cd libarchive/test && make clean
	-[ -f tar/Makefile ] && cd tar && make clean
	-[ -f tar/test/Makefile ] && cd tar/test && make clean
	-[ -f cpio/Makefile ] && cd cpio && make clean
	-[ -f cpio/test/Makefile ] && cd cpio/test && make clean

#
# Libarchive headers, source, etc.
#
#

include_HEADERS= libarchive/archive.h libarchive/archive_entry.h

libarchive_la_SOURCES=						\
	libarchive/archive_acl.c				\
	libarchive/archive_acl_private.h			\
	libarchive/archive_check_magic.c			\
	libarchive/archive_cmdline.c				\
	libarchive/archive_cmdline_private.h			\
	libarchive/archive_crc32.h				\
	libarchive/archive_crypto.c				\
	libarchive/archive_crypto_private.h			\
	libarchive/archive_endian.h				\
	libarchive/archive_entry.c				\
	libarchive/archive_entry.h				\
	libarchive/archive_entry_copy_stat.c			\
	libarchive/archive_entry_link_resolver.c		\
	libarchive/archive_entry_locale.h			\
	libarchive/archive_entry_private.h			\
	libarchive/archive_entry_sparse.c			\
	libarchive/archive_entry_stat.c				\
	libarchive/archive_entry_strmode.c			\
	libarchive/archive_entry_xattr.c			\
	libarchive/archive_getdate.c				\
	libarchive/archive_match.c				\
	libarchive/archive_options.c				\
	libarchive/archive_options_private.h			\
	libarchive/archive_pathmatch.c				\
	libarchive/archive_pathmatch.h				\
	libarchive/archive_platform.h				\
	libarchive/archive_ppmd_private.h			\
	libarchive/archive_ppmd7.c				\
	libarchive/archive_ppmd7_private.h			\
	libarchive/archive_private.h				\
	libarchive/archive_rb.c					\
	libarchive/archive_rb.h					\
	libarchive/archive_read.c				\
	libarchive/archive_read_append_filter.c			\
	libarchive/archive_read_data_into_fd.c			\
	libarchive/archive_read_disk_entry_from_file.c		\
	libarchive/archive_read_disk_posix.c			\
	libarchive/archive_read_disk_private.h			\
	libarchive/archive_read_disk_set_standard_lookup.c	\
	libarchive/archive_read_extract.c			\
	libarchive/a
/* ... truncated ... */
```

### Type definitions

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

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

	int		  archive_format;
	const char	 *archive_format_name;

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

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

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

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

## Upstream Fix
```diff
commit 4e002d9a92ecd7cec0fb98b0bedbace8aad81f6e
Author: Jean-Yves Migeon <jeanyves.migeon@free.fr>
Date:   Tue Sep 3 16:12:37 2013 +0200

    Add the device parsing logic. It allows mtree's libarchive to
    parse device entries like NetBSD's mtree and its multiple possible
    format: native, 386bsd, 4bsd, bsdos, freebsd, hpux, isc, linux, netbsd,
    osf1, sco, solaris, sunos, svr3, svr4, and ultrix.

Index: libarchive-3.1.2/libarchive/CMakeLists.txt
===================================================================
--- libarchive-3.1.2.orig/libarchive/CMakeLists.txt
+++ libarchive-3.1.2/libarchive/CMakeLists.txt
@@ -35,6 +35,8 @@ SET(libarchive_SOURCES
   archive_match.c
   archive_options.c
   archive_options_private.h
+  archive_pack_dev.h
+  archive_pack_dev.c
   archive_pathmatch.c
   archive_pathmatch.h
   archive_platform.h
Index: libarchive-3.1.2/libarchive/archive_pack_dev.c
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/archive_pack_dev.c
@@ -0,0 +1,304 @@
+/*	$NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#include "archive_platform.h"
+
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* not lint */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive_pack_dev.h"
+
+static	pack_t	pack_netbsd;
+static	pack_t	pack_freebsd;
+static	pack_t	pack_8_8;
+static	pack_t	pack_12_20;
+static	pack_t	pack_14_18;
+static	pack_t	pack_8_24;
+static	pack_t	pack_bsdos;
+static	int	compare_format(const void *, const void *);
+
+static const char iMajorError[] = "invalid major number";
+static const char iMinorError[] = "invalid minor number";
+static const char tooManyFields[] = "too many fields for format";
+
+	/* exported */
+dev_t
+pack_native(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev(numbers[0], numbers[1]);
+		if ((u_long)major(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((u_long)minor(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+static dev_t
+pack_netbsd(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_netbsd(numbers[0], numbers[1]);
+		if ((u_long)major_netbsd(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((u_long)minor_netbsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_freebsd(x)	((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_freebsd(x)	((int32_t)(((x) & 0xffff00ff) >> 0))
+#define	makedev_freebsd(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0xffff00ff)))
+
+static dev_t
+pack_freebsd(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_freebsd(numbers[0], numbers[1]);
+		if ((u_long)major_freebsd(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_freebsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_8(x)		((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_8_8(x)		((int32_t)(((x) & 0x000000ff) >> 0))
+#define	makedev_8_8(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0x000000ff)))
+
+static dev_t
+pack_8_8(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_8(numbers[0], numbers[1]);
+		if ((u_long)major_8_8(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_8_8(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_20(x)		((int32_t)(((x) & 0xfff00000) >> 20))
+#define	minor_12_20(x)		((int32_t)(((x) & 0x000fffff) >>  0))
+#define	makedev_12_20(x,y)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  0) & 0x000fffff)))
+
+static dev_t
+pack_12_20(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((u_long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_14_18(x)		((int32_t)(((x) & 0xfffc0000) >> 18))
+#define	minor_14_18(x)		((int32_t)(((x) & 0x0003ffff) >>  0))
+#define	makedev_14_18(x,y)	((dev_t)((((x) << 18) & 0xfffc0000) | \
+					 (((y) <<  0) & 0x0003ffff)))
+
+static dev_t
+pack_14_18(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_14_18(numbers[0], numbers[1]);
+		if ((u_long)major_14_18(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_14_18(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_24(x)		((int32_t)(((x) & 0xff000000) >> 24))
+#define	minor_8_24(x)		((int32_t)(((x) & 0x00ffffff) >>  0))
+#define	makedev_8_24(x,y)	((dev_t)((((x) << 24) & 0xff000000) | \
+					 (((y) <<  0) & 0x00ffffff)))
+
+static dev_t
+pack_8_24(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_24(numbers[0], numbers[1]);
+		if ((u_long)major_8_24(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_8_24(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_12_8(x)	((int32_t)(((x) & 0xfff00000) >> 20))
+#define	unit_12_12_8(x)		((int32_t)(((x) & 0x000fff00) >>  8))
+#define	subunit_12_12_8(x)	((int32_t)(((x) & 0x000000ff) >>  0))
+#define	makedev_12_12_8(x,y,z)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  8) & 0x000fff00) | \
+					 (((z) <<  0) & 0x000000ff)))
+
+static dev_t
+pack_bsdos(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((u_long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
commit 4e002d9a92ecd7cec0fb98b0bedbace8aad81f6e
Author: Jean-Yves Migeon <jeanyves.migeon@free.fr>
Date:   Tue Sep 3 16:12:37 2013 +0200

    Add the device parsing logic. It allows mtree's libarchive to
    parse device entries like NetBSD's mtree and its multiple possible
    format: native, 386bsd, 4bsd, bsdos, freebsd, hpux, isc, linux, netbsd,
    osf1, sco, solaris, sunos, svr3, svr4, and ultrix.

Index: libarchive-3.1.2/libarchive/CMakeLists.txt
===================================================================
--- libarchive-3.1.2.orig/libarchive/CMakeLists.txt
+++ libarchive-3.1.2/libarchive/CMakeLists.txt
@@ -35,6 +35,8 @@ SET(libarchive_SOURCES
   archive_match.c
   archive_options.c
   archive_options_private.h
+  archive_pack_dev.h
+  archive_pack_dev.c
   archive_pathmatch.c
   archive_pathmatch.h
   archive_platform.h
Index: libarchive-3.1.2/libarchive/archive_pack_dev.c
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/archive_pack_dev.c
@@ -0,0 +1,304 @@
+/*	$NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#include "archive_platform.h"
+
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* not lint */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive_pack_dev.h"
+
+static	pack_t	pack_netbsd;
+static	pack_t	pack_freebsd;
+static	pack_t	pack_8_8;
+static	pack_t	pack_12_20;
+static	pack_t	pack_14_18;
+static	pack_t	pack_8_24;
+static	pack_t	pack_bsdos;
+static	int	compare_format(const void *, const void *);
+
+static const char iMajorError[] = "invalid major number";
+static const char iMinorError[] = "invalid minor number";
+static const char tooManyFields[] = "too many fields for format";
+
+	/* exported */
+dev_t
+pack_native(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev(numbers[0], numbers[1]);
+		if ((u_long)major(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((u_long)minor(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+static dev_t
+pack_netbsd(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_netbsd(numbers[0], numbers[1]);
+		if ((u_long)major_netbsd(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((u_long)minor_netbsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_freebsd(x)	((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_freebsd(x)	((int32_t)(((x) & 0xffff00ff) >> 0))
+#define	makedev_freebsd(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0xffff00ff)))
+
+static dev_t
+pack_freebsd(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_freebsd(numbers[0], numbers[1]);
+		if ((u_long)major_freebsd(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_freebsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_8(x)		((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_8_8(x)		((int32_t)(((x) & 0x000000ff) >> 0))
+#define	makedev_8_8(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0x000000ff)))
+
+static dev_t
+pack_8_8(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_8(numbers[0], numbers[1]);
+		if ((u_long)major_8_8(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_8_8(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_20(x)		((int32_t)(((x) & 0xfff00000) >> 20))
+#define	minor_12_20(x)		((int32_t)(((x) & 0x000fffff) >>  0))
+#define	makedev_12_20(x,y)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  0) & 0x000fffff)))
+
+static dev_t
+pack_12_20(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((u_long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_14_18(x)		((int32_t)(((x) & 0xfffc0000) >> 18))
+#define	minor_14_18(x)		((int32_t)(((x) & 0x0003ffff) >>  0))
+#define	makedev_14_18(x,y)	((dev_t)((((x) << 18) & 0xfffc0000) | \
+					 (((y) <<  0) & 0x0003ffff)))
+
+static dev_t
+pack_14_18(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_14_18(numbers[0], numbers[1]);
+		if ((u_long)major_14_18(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_14_18(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_24(x)		((int32_t)(((x) & 0xff000000) >> 24))
+#define	minor_8_24(x)		((int32_t)(((x) & 0x00ffffff) >>  0))
+#define	makedev_8_24(x,y)	((dev_t)((((x) << 24) & 0xff000000) | \
+					 (((y) <<  0) & 0x00ffffff)))
+
+static dev_t
+pack_8_24(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_24(numbers[0], numbers[1]);
+		if ((u_long)major_8_24(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_8_24(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_12_8(x)	((int32_t)(((x) & 0xfff00000) >> 20))
+#define	unit_12_12_8(x)		((int32_t)(((x) & 0x000fff00) >>  8))
+#define	subunit_12_12_8(x)	((int32_t)(((x) & 0x000000ff) >>  0))
+#define	makedev_12_12_8(x,y,z)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  8) & 0x000fff00) | \
+					 (((z) <<  0) & 0x000000ff)))
+
+static dev_t
+pack_bsdos(int n, u_long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((u_long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else if (n == 3) {
+		dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
+		if ((u_long)major_12_12_8(dev) != numbers[0])
+			*error = iMajorError;
+		if ((u_long)unit_12_12_8(dev) != numbers[1])
+			*error = "invalid unit number";
+		if ((u_long)subunit_12_12_8(dev) != numbers[2])
+			*error = "invalid subunit number";
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+		/* list of formats and pack functions */
+		/* this list must be sorted lexically */
+static struct format {
+	const char	*name;
+	pack_t		*pack;
+} formats[] = {
+	{"386bsd",  pack_8_8},
+	{"4bsd",    pack_8_8},
+	{"bsdos",   pack_bsdos},
+	{"freebsd", pack_freebsd},
+	{"hpux",    pack_8_24},
+	{"isc",     pack_8_8},
+	{"linux",   pack_8_8},
+	{"native",  pack_native},
+	{"netbsd",  pack_netbsd},
+	{"osf1",    pack_12_20},
+	{"sco",     pack_8_8},
+	{"solaris", pack_14_18},
+	{"sunos",   pack_8_8},
+	{"svr3",    pack_8_8},
+	{"svr4",    pack_14_18},
+	{"ultrix",  pack_8_8},
+};
+
+static int
+compare_format(const void *key, const void *element)
+{
+	const char		*name;
+	const struct format	*format;
+
+	name = key;
+	format = element;
+
+	return (strcmp(name, format->name));
+}
+
+
+pack_t *
+pack_find(const char *name)
+{
+	struct format	*format;
+
+	format = bsearch(name, formats,
+	    sizeof(formats)/sizeof(formats[0]),
+	    sizeof(formats[0]), compare_format);
+	if (format == 0)
+		return (NULL);
+	return (format->pack);
+}
Index: libarchive-3.1.2/libarchive/archive_pack_dev.h
===================================================================
--- /dev/null
+++ libarchive-3.1.2/libarchive/archive_pack_dev.h
@@ -0,0 +1,50 @@
+/*	$NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#ifndef	_PACK_DEV_H
+#define	_PACK_DEV_H
+
+typedef	dev_t pack_t(int, u_long [], const char **);
+typedef unsigned long u_long;
+
+pack_t	*pack_find(const char *);
+pack_t	 pack_native;
+
+#define	major_netbsd(x)		((int32_t)((((x) & 0x000fff00) >>  8)))
+#define	minor_netbsd(x)		((int32_t)((((x) & 0xfff00000) >> 12) | \
+					   (((x) & 0x000000ff) >>  0)))
+#define	makedev_netbsd(x,y)	((dev_t)((((x) <<  8) & 0x000fff00) | \
+					 (((y) << 12) & 0xfff00000) | \
+					 (((y) <<  0) & 0x000000ff)))
+
+#endif	/* _PACK_DEV_H */
Index: libarchive-3.1.2/libarchive/archive_platform.h
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_platform.h
+++ libarchive-3.1.2/libarchive/archive_platform.h
@@ -66,15 +66,18 @@
  * headers as required.
  */

-/* Get a real definition for __FBSDID if we can */
+/* Get a real definition for __FBSDID or __RCSID if we can */
 #if HAVE_SYS_CDEFS_H
 #include <sys/cdefs.h>
 #endif

-/* If not, define it so as to avoid dangling semicolons. */
+/* If not, define them so as to avoid dangling semicolons. */
 #ifndef __FBSDID
 #define	__FBSDID(a)     struct _undefined_hack
 #endif
+#ifndef __RCSID
+#define	__RCSID(a)     struct _undefined_hack
+#endif

 /* Try to get standard C99-style integer type definitions. */
 #if HAVE_INTTYPES_H
Index: libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_mtree.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/
 #include "archive_private.h"
 #include "archive_read_private.h"
 #include "archive_string.h"
+#include "archive_pack_dev.h"

 #ifndef O_BINARY
 #define	O_BINARY 0
@@ -1300,33 +1301,63 @@ parse_line(struct archive_read *a, struc

 /*
  * Device entries have one of the following forms:
- * raw dev_t
- * format,major,minor[,subdevice]
- *
- * Just use major and minor, no translation etc is done
- * between formats.
+ *  - raw dev_t
+ *  - format,major,minor[,subdevice]
  */
 static int
 parse_device(struct archive *a, struct archive_entry *entry, char *val)
 {
-	char *comma1, *comma2;
+#define MAX_PACK_ARGS 3
+	unsigned long numbers[MAX_PACK_ARGS];
+	char *p, *dev;
+	int argc;
+	pack_t *pack;
+	dev_t result;
+	const char *error = NULL;

-	comma1 = strchr(val, ',');
-	if (comma1 == NULL) {
-		archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
-		return (ARCHIVE_OK);
-	}
-	++comma1;
-	comma2 = strchr(comma1, ',');
-	if (comma2 == NULL) {
-		archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Malformed device attribute");
-		return (ARCHIVE_WARN);
+	if ((dev = strchr(val, ',')) != NULL) {
+		/*
+		 * Device's major/minor are given in a specified format.
+		 * Decode and pack it accordingly.
+		 */
+		*dev++ = '\0';
+		if ((pack = pack_find(val)) == NULL) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Unknown format `%s'", val);
+			return ARCHIVE_WARN;
+		}
+		argc = 0;
+		while ((p = strsep(&dev, ",")) != NULL) {
+			if (*p == '\0') {
+				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Missing number");
+				return ARCHIVE_WARN;
+			}
+			numbers[argc++] = mtree_atol(&p);
+			if (argc > MAX_PACK_ARGS) {
+				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Too many arguments");
+				return ARCHIVE_WARN;
+			}
+		}
+		if (argc < 2) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Not enough arguments");
+			return ARCHIVE_WARN;
+		}
+		result = (*pack)(argc, numbers, &error);
+		if (error != NULL) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "%s", error);
+			return ARCHIVE_WARN;
+		}
+		archive_entry_set_rdev(entry, result);
+	} else {
+		/* file system raw value. */
+		archive_entry_set_rdev(entry, (dev_t)mtree_atol(&val));
 	}
-	++comma2;
-	archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
-	archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
-	return (ARCHIVE_OK);
+	return ARCHIVE_OK;
+#undef MAX_PACK_ARGS
 }

 /*
Index: libarchive-3.1.2/Makefile.am
===================================================================
--- libarchive-3.1.2.orig/Makefile.am
+++ libarchive-3.1.2/Makefile.am
@@ -110,6 +110,8 @@ libarchive_la_SOURCES=						\
 	libarchive/archive_match.c				\
 	libarchive/archive_options.c				\
 	libarchive/archive_options_private.h			\
+	libarchive/archive_pack_dev.h				\
+	libarchive/archive_pack_dev.c				\
 	libarchive/archive_pathmatch.c				\
 	libarchive/archive_pathmatch.h				\
 	libarchive/archive_platform.h				\


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

Squid 3.2.x before 3.2.14, 3.3.x before 3.3.14, 3.4.x before 3.4.13, and 3.5.x before 3.5.4, when configured with client-first SSL-bump, do not properly validate the domain or hostname fields of X.509 certificates, which allows man-in-the-middle attackers to spoof SSL servers via a valid certificate.

## Package
squid

## Files to modify
- src/comm.h
- src/forward.h
- squid-3.3.13.orig/src/forward.h
- squid-3.3.13.orig/src/comm.h
- src/Server.h

## Upstream Fix
```diff
Index: squid-3.3.13/src/forward.h
===================================================================
--- squid-3.3.13.orig/src/forward.h
+++ squid-3.3.13/src/forward.h
@@ -86,6 +86,9 @@ private:
     ErrorState *makeConnectingError(const err_type type) const;
     static void RegisterWithCacheManager(void);

+    /// stops monitoring server connection for closure and updates pconn stats
+    void closeServerConnection(const char *reason);
+
 public:
     StoreEntry *entry;
     HttpRequest *request;
@@ -116,6 +119,8 @@ private:

     Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.

+    AsyncCall::Pointer closeHandler; ///< The serverConn close handler
+
     /// possible pconn race states
     typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
     PconnRace pconnRace; ///< current pconn race state
Index: squid-3.3.13/src/forward.cc
===================================================================
--- squid-3.3.13.orig/src/forward.cc
+++ squid-3.3.13/src/forward.cc
@@ -102,10 +102,7 @@ FwdState::abort(void* d)
     Pointer tmp = fwd; // Grab a temporary pointer to keep the object alive during our scope.

     if (Comm::IsConnOpen(fwd->serverConnection())) {
-        comm_remove_close_handler(fwd->serverConnection()->fd, fwdServerClosedWrapper, fwd);
-        debugs(17, 3, HERE << "store entry aborted; closing " <<
-               fwd->serverConnection());
-        fwd->serverConnection()->close();
+        fwd->closeServerConnection("store entry aborted");
     } else {
         debugs(17, 7, HERE << "store entry aborted; no connection to close");
     }
@@ -113,6 +110,16 @@ FwdState::abort(void* d)
     fwd->self = NULL;
 }

+void
+FwdState::closeServerConnection(const char *reason)
+{
+    debugs(17, 3, "because " << reason << "; " << serverConn);
+    comm_remove_close_handler(serverConn->fd, closeHandler);
+    closeHandler = NULL;
+    fwdPconnPool->noteUses(fd_table[serverConn->fd].pconn.uses);
+    serverConn->close();
+}
+
 /**** PUBLIC INTERFACE ********************************************************/

 FwdState::FwdState(const Comm::ConnectionPointer &client, StoreEntry * e, HttpRequest * r, const AccessLogEntryPointer &alp):
@@ -268,9 +275,7 @@ FwdState::~FwdState()
     }

     if (Comm::IsConnOpen(serverConn)) {
-        comm_remove_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
-        debugs(17, 3, HERE << "closing FD " << serverConnection()->fd);
-        serverConn->close();
+        closeServerConnection(__FUNCTION__);
     }

     serverDestinations.clean();
@@ -426,7 +431,8 @@ FwdState::unregister(Comm::ConnectionPoi
     debugs(17, 3, HERE << entry->url() );
     assert(serverConnection() == conn);
     assert(Comm::IsConnOpen(conn));
-    comm_remove_close_handler(conn->fd, fwdServerClosedWrapper, this);
+    comm_remove_close_handler(conn->fd, closeHandler);
+    closeHandler = NULL;
     serverConn = NULL;
 }

@@ -884,7 +890,7 @@ FwdState::connectDone(const Comm::Connec

     debugs(17, 3, HERE << serverConnection() << ": '" << entry->url() << "'" );

-    comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+    closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);

     if (serverConnection()->getPeer())
         peerConnectSucceded(serverConnection()->getPeer());
@@ -988,7 +994,7 @@ FwdState::connectStart()
             request->hier.note(serverConn, pinned_connection->pinning.host);
             if (pinned_connection->pinnedAuth())
                 request->flags.auth = 1;
-            comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
+            closeHandler = comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
             // the server may close the pinned connection before this request
             pconnRace = racePossible;
             dispatch();
@@ -1024,7 +1030,7 @@ FwdState::connectStart()
         debugs(17, 3, HERE << "reusing pconn " << serverConnection());
         ++n_tries;

-        comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+        closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);

         /* Update server side TOS and Netfilter mark on the connection. */
         if (Ip::Qos::TheConfig.isAclTosActive()) {
Index: squid-3.3.13/src/Server.h
===================================================================
--- squid-3.3.13.orig/src/Server.h
+++ squid-3.3.13/src/Server.h
@@ -125,7 +125,9 @@ protected:
     virtual void sentRequestBody(const CommIoCbParams &io) = 0;
     virtual void doneSendingRequestBody() = 0;

-    virtual void closeServer() = 0;            /**< end communication with the server */
+    /// Use this to end communication with the server. The call cancels our
+    /// closure handler and tells FwdState to forget about the connection.
+    virtual void closeServer() = 0;
     virtual bool doneWithServer() const = 0;   /**< did we end communication? */

     /// Entry-dependent callbacks use this check to quit if the entry went bad
Index: squid-3.3.13/src/comm.cc
===================================================================
--- squid-3.3.13.orig/src/comm.cc
+++ squid-3.3.13/src/comm.cc
@@ -1221,7 +1221,7 @@ comm_udp_sendto(int fd,
     return COMM_ERROR;
 }

-void
+AsyncCall::Pointer
 comm_add_close_handler(int fd, CLCB * handler, void *data)
 {
     debugs(5, 5, "comm_add_close_handler: FD " << fd << ", handler=" <<
@@ -1230,6 +1230,7 @@ comm_add_close_handler(int fd, CLCB * ha
     AsyncCall::Pointer call=commCbCall(5,4, "SomeCloseHandler",
                                        CommCloseCbPtrFun(handler, data));
     comm_add_close_handler(fd, call);
+    return call;
 }

 void
Index: squid-3.3.13/src/comm.h
===================================================================
--- squid-3.3.13.orig/src/comm.h
+++ squid-3.3.13/src/comm.h
@@ -75,7 +75,7 @@ void commCloseAllSockets(void);
 void checkTimeouts(void);

 //typedef void IOACB(int fd, int nfd, Comm::ConnectionPointer details, comm_err_t flag, int xerrno, void *data);
-void comm_add_close_handler(int fd, CLCB *, void *);
+AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *, void *);
 void comm_add_close_handler(int fd, AsyncCall::Pointer &);
 void comm_remove_close_handler(int fd, CLCB *, void *);
 void comm_remove_close_handler(int fd, AsyncCall::Pointer &);
Index: squid-3.3.13/src/http.cc
===================================================================
--- squid-3.3.13.orig/src/http.cc
+++ squid-3.3.13/src/http.cc
@@ -199,7 +199,8 @@ HttpStateData::httpTimeout(const CommTim
         fwd->fail(new ErrorState(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT, fwd->request));
     }

-    serverConnection->close();
+    closeServer();
+    mustStop("HttpStateData::httpTimeout");
 }

 static void
@@ -1174,7 +1175,8 @@ HttpStateData::readReply(const CommIoCbP
             err->xerrno = io.xerrno;
             fwd->fail(err);
             flags.do_next_read = false;
-            serverConnection->close();
+            closeServer();
+            mustStop("HttpStateData::readReply");
         }

         return;
@@ -1327,7 +1329,8 @@ HttpStateData::continueAfterParsingHeade
     entry->reset();
     fwd->fail(new ErrorState(error, HTTP_BAD_GATEWAY, fwd->request));
     flags.do_next_read = false;
-    serverConnection->close();
+    closeServer();
+    mustStop("HttpStateData::continueAfterParsingHeader");
     return false; // quit on error
 }

@@ -1552,7 +1555,8 @@ HttpStateData::wroteLast(const CommIoCbP
         ErrorState *err = new ErrorState(ERR_WRITE_ERROR, HTTP_BAD_GATEWAY, fwd->request);
         err->xerrno = io.xerrno;
         fwd->fail(err);
-        serverConnection->close();
+        closeServer();
+        mustStop("HttpStateData::wroteLast");
         return;
     }

@@ -1580,7 +1584,6 @@ HttpStateData::sendComplete()
     requ
... (truncated)
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: squid-3.3.13/src/forward.h
===================================================================
--- squid-3.3.13.orig/src/forward.h
+++ squid-3.3.13/src/forward.h
@@ -86,6 +86,9 @@ private:
     ErrorState *makeConnectingError(const err_type type) const;
     static void RegisterWithCacheManager(void);

+    /// stops monitoring server connection for closure and updates pconn stats
+    void closeServerConnection(const char *reason);
+
 public:
     StoreEntry *entry;
     HttpRequest *request;
@@ -116,6 +119,8 @@ private:

     Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.

+    AsyncCall::Pointer closeHandler; ///< The serverConn close handler
+
     /// possible pconn race states
     typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
     PconnRace pconnRace; ///< current pconn race state
Index: squid-3.3.13/src/forward.cc
===================================================================
--- squid-3.3.13.orig/src/forward.cc
+++ squid-3.3.13/src/forward.cc
@@ -102,10 +102,7 @@ FwdState::abort(void* d)
     Pointer tmp = fwd; // Grab a temporary pointer to keep the object alive during our scope.

     if (Comm::IsConnOpen(fwd->serverConnection())) {
-        comm_remove_close_handler(fwd->serverConnection()->fd, fwdServerClosedWrapper, fwd);
-        debugs(17, 3, HERE << "store entry aborted; closing " <<
-               fwd->serverConnection());
-        fwd->serverConnection()->close();
+        fwd->closeServerConnection("store entry aborted");
     } else {
         debugs(17, 7, HERE << "store entry aborted; no connection to close");
     }
@@ -113,6 +110,16 @@ FwdState::abort(void* d)
     fwd->self = NULL;
 }

+void
+FwdState::closeServerConnection(const char *reason)
+{
+    debugs(17, 3, "because " << reason << "; " << serverConn);
+    comm_remove_close_handler(serverConn->fd, closeHandler);
+    closeHandler = NULL;
+    fwdPconnPool->noteUses(fd_table[serverConn->fd].pconn.uses);
+    serverConn->close();
+}
+
 /**** PUBLIC INTERFACE ********************************************************/

 FwdState::FwdState(const Comm::ConnectionPointer &client, StoreEntry * e, HttpRequest * r, const AccessLogEntryPointer &alp):
@@ -268,9 +275,7 @@ FwdState::~FwdState()
     }

     if (Comm::IsConnOpen(serverConn)) {
-        comm_remove_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
-        debugs(17, 3, HERE << "closing FD " << serverConnection()->fd);
-        serverConn->close();
+        closeServerConnection(__FUNCTION__);
     }

     serverDestinations.clean();
@@ -426,7 +431,8 @@ FwdState::unregister(Comm::ConnectionPoi
     debugs(17, 3, HERE << entry->url() );
     assert(serverConnection() == conn);
     assert(Comm::IsConnOpen(conn));
-    comm_remove_close_handler(conn->fd, fwdServerClosedWrapper, this);
+    comm_remove_close_handler(conn->fd, closeHandler);
+    closeHandler = NULL;
     serverConn = NULL;
 }

@@ -884,7 +890,7 @@ FwdState::connectDone(const Comm::Connec

     debugs(17, 3, HERE << serverConnection() << ": '" << entry->url() << "'" );

-    comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+    closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);

     if (serverConnection()->getPeer())
         peerConnectSucceded(serverConnection()->getPeer());
@@ -988,7 +994,7 @@ FwdState::connectStart()
             request->hier.note(serverConn, pinned_connection->pinning.host);
             if (pinned_connection->pinnedAuth())
                 request->flags.auth = 1;
-            comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
+            closeHandler = comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
             // the server may close the pinned connection before this request
             pconnRace = racePossible;
             dispatch();
@@ -1024,7 +1030,7 @@ FwdState::connectStart()
         debugs(17, 3, HERE << "reusing pconn " << serverConnection());
         ++n_tries;

-        comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+        closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);

         /* Update server side TOS and Netfilter mark on the connection. */
         if (Ip::Qos::TheConfig.isAclTosActive()) {
Index: squid-3.3.13/src/Server.h
===================================================================
--- squid-3.3.13.orig/src/Server.h
+++ squid-3.3.13/src/Server.h
@@ -125,7 +125,9 @@ protected:
     virtual void sentRequestBody(const CommIoCbParams &io) = 0;
     virtual void doneSendingRequestBody() = 0;

-    virtual void closeServer() = 0;            /**< end communication with the server */
+    /// Use this to end communication with the server. The call cancels our
+    /// closure handler and tells FwdState to forget about the connection.
+    virtual void closeServer() = 0;
     virtual bool doneWithServer() const = 0;   /**< did we end communication? */

     /// Entry-dependent callbacks use this check to quit if the entry went bad
Index: squid-3.3.13/src/comm.cc
===================================================================
--- squid-3.3.13.orig/src/comm.cc
+++ squid-3.3.13/src/comm.cc
@@ -1221,7 +1221,7 @@ comm_udp_sendto(int fd,
     return COMM_ERROR;
 }

-void
+AsyncCall::Pointer
 comm_add_close_handler(int fd, CLCB * handler, void *data)
 {
     debugs(5, 5, "comm_add_close_handler: FD " << fd << ", handler=" <<
@@ -1230,6 +1230,7 @@ comm_add_close_handler(int fd, CLCB * ha
     AsyncCall::Pointer call=commCbCall(5,4, "SomeCloseHandler",
                                        CommCloseCbPtrFun(handler, data));
     comm_add_close_handler(fd, call);
+    return call;
 }

 void
Index: squid-3.3.13/src/comm.h
===================================================================
--- squid-3.3.13.orig/src/comm.h
+++ squid-3.3.13/src/comm.h
@@ -75,7 +75,7 @@ void commCloseAllSockets(void);
 void checkTimeouts(void);

 //typedef void IOACB(int fd, int nfd, Comm::ConnectionPointer details, comm_err_t flag, int xerrno, void *data);
-void comm_add_close_handler(int fd, CLCB *, void *);
+AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *, void *);
 void comm_add_close_handler(int fd, AsyncCall::Pointer &);
 void comm_remove_close_handler(int fd, CLCB *, void *);
 void comm_remove_close_handler(int fd, AsyncCall::Pointer &);
Index: squid-3.3.13/src/http.cc
===================================================================
--- squid-3.3.13.orig/src/http.cc
+++ squid-3.3.13/src/http.cc
@@ -199,7 +199,8 @@ HttpStateData::httpTimeout(const CommTim
         fwd->fail(new ErrorState(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT, fwd->request));
     }

-    serverConnection->close();
+    closeServer();
+    mustStop("HttpStateData::httpTimeout");
 }

 static void
@@ -1174,7 +1175,8 @@ HttpStateData::readReply(const CommIoCbP
             err->xerrno = io.xerrno;
             fwd->fail(err);
             flags.do_next_read = false;
-            serverConnection->close();
+            closeServer();
+            mustStop("HttpStateData::readReply");
         }

         return;
@@ -1327,7 +1329,8 @@ HttpStateData::continueAfterParsingHeade
     entry->reset();
     fwd->fail(new ErrorState(error, HTTP_BAD_GATEWAY, fwd->request));
     flags.do_next_read = false;
-    serverConnection->close();
+    closeServer();
+    mustStop("HttpStateData::continueAfterParsingHeader");
     return false; // quit on error
 }

@@ -1552,7 +1555,8 @@ HttpStateData::wroteLast(const CommIoCbP
         ErrorState *err = new ErrorState(ERR_WRITE_ERROR, HTTP_BAD_GATEWAY, fwd->request);
         err->xerrno = io.xerrno;
         fwd->fail(err);
-        serverConnection->close();
+        closeServer();
+        mustStop("HttpStateData::wroteLast");
         return;
     }

@@ -1580,7 +1584,6 @@ HttpStateData::sendComplete()
     request->hier.peer_http_request_sent = current_time;
 }

-// Close the HTTP server connection. Used by serverComplete().
 void
 HttpStateData::closeServer()
 {
@@ -2377,7 +2380,8 @@ HttpStateData::handleMoreRequestBodyAvai
             debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->client_addr << "' -> '" << entry->url() << "'" );

             if (virginReply()->sline.status == HTTP_INVALID_HEADER) {
-                serverConnection->close();
+                closeServer();
+                mustStop("HttpStateData::handleMoreRequestBodyAvailable");
                 return;
             }
         }


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

## Target Source Code

### crypto/rsa/rsa_ameth.c

#### region() [lines 248-335]
```c
		}
	ret=1;
err:
	if (m != NULL) OPENSSL_free(m);
	return(ret);
	}

static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
							ASN1_PCTX *ctx)
	{
	return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
	}

static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
							ASN1_PCTX *ctx)
	{
	return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
	}

static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
					X509_ALGOR **pmaskHash)
	{
	const unsigned char *p;
	int plen;
	RSA_PSS_PARAMS *pss;

	*pmaskHash = NULL;

	if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
		return NULL;
	p = alg->parameter->value.sequence->data;
	plen = alg->parameter->value.sequence->length;
	pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);

	if (!pss)
		return NULL;

	if (pss->maskGenAlgorithm)
		{
		ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
			&& param->type == V_ASN1_SEQUENCE)
			{
			p = param->value.sequence->data;
			plen = param->value.sequence->length;
			*pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
			}
		}

	return pss;
	}

static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
				X509_ALGOR *maskHash, int indent)
	{
	int rv = 0;
	if (!pss)
		{
		if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
			return 0;
		return 1;
		}
	if (BIO_puts(bp, "\n") <= 0)
		goto err;
	if (!BIO_indent(bp, indent, 128))
		goto err;
	if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
		goto err;

	if (pss->hashAlgorithm)
		{
		if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
			goto err;
		}
	else if (BIO_puts(bp, "sha1 (default)") <= 0)
		goto err;

	if (BIO_puts(bp, "\n") <= 0)
		goto err;

	if (!BIO_indent(bp, indent, 128))
		goto err;

	if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
			goto err;
	if (pss->maskGenAlgorithm)
		{
```

## Upstream Fix
```diff
From d8541d7e9e63bf5f343af24644046c8d96498c17 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Fri, 2 Oct 2015 13:10:29 +0100
Subject: [PATCH] Add PSS parameter check.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Avoid seg fault by checking mgf1 parameter is not NULL. This can be
triggered during certificate verification so could be a DoS attack
against a client or a server enabling client authentication.

Thanks to Loïc Jonas Etienne (Qnective AG) for discovering this bug.

CVE-2015-3194

Reviewed-by: Matt Caswell <matt@openssl.org>
---
 crypto/rsa/rsa_ameth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 93e071de75e2a..c7f1148a1ded1 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -279,7 +279,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
     if (pss->maskGenAlgorithm) {
         ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
         if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
-            && param->type == V_ASN1_SEQUENCE) {
+            && param && param->type == V_ASN1_SEQUENCE) {
             p = param->value.sequence->data;
             plen = param->value.sequence->length;
             *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
```

Generate a backported patch for the SUSE target version.

[Assistant]
From d8541d7e9e63bf5f343af24644046c8d96498c17 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Fri, 2 Oct 2015 13:10:29 +0100
Subject: [PATCH] Add PSS parameter check.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Avoid seg fault by checking mgf1 parameter is not NULL. This can be
triggered during certificate verification so could be a DoS attack
against a client or a server enabling client authentication.

Thanks to Loïc Jonas Etienne (Qnective AG) for discovering this bug.

CVE-2015-3194

Reviewed-by: Matt Caswell <matt@openssl.org>
---
 crypto/rsa/rsa_ameth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: openssl-1.0.1i/crypto/rsa/rsa_ameth.c
===================================================================
--- openssl-1.0.1i.orig/crypto/rsa/rsa_ameth.c	2015-12-03 17:56:38.292632624 +0100
+++ openssl-1.0.1i/crypto/rsa/rsa_ameth.c	2015-12-03 17:58:11.106130819 +0100
@@ -287,7 +287,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(co
 		{
 		ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
 		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
-			&& param->type == V_ASN1_SEQUENCE)
+			&& param && param->type == V_ASN1_SEQUENCE)
 			{
 			p = param->value.sequence->data;
 			plen = param->value.sequence->length;


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

epan/dissectors/packet-reload.c in the REsource LOcation And Discovery (aka RELOAD) dissector in Wireshark 1.8.x before 1.8.6 uses incorrect integer data types, which allows remote attackers to cause a denial of service (infinite loop) via crafted integer values in a packet, related to the (1) dissect_icecandidates, (2) dissect_kinddata, (3) dissect_nodeid_list, (4) dissect_storeans, (5) dissect_storereq, (6) dissect_storeddataspecifier, (7) dissect_fetchreq, (8) dissect_findans, (9) dissect_diagnosticinfo, (10) dissect_diagnosticresponse, (11) dissect_reload_messagecontents, and (12) dissect_reload_message functions, a different vulnerability than CVE-2013-2486.

## Package
wireshark

## Files to modify
- ui/gtk/main.c

## Upstream Fix
```diff
Index: ui/gtk/main.c
===================================================================
--- ui/gtk/main.c.orig	2012-08-10 01:35:00.000000000 +0100
+++ ui/gtk/main.c	2012-08-15 20:28:59.000000000 +0100
@@ -1399,11 +1399,13 @@ main_colorize_changed(gboolean packet_li

 static GtkWidget           *close_dlg = NULL;

+/*
 static void
 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
 {
     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
 }
+*/

 #ifdef _WIN32
 static void
@@ -2081,9 +2083,10 @@ check_and_warn_user_startup(gchar *cf_na
 #endif
 {
   gchar               *cur_user, *cur_group;
-  gpointer             priv_warning_dialog;
+//  gpointer             priv_warning_dialog;

   /* Tell the user not to run as root. */
+/*
   if (running_with_special_privs() && recent.privs_warn_if_elevated) {
     cur_user = get_cur_username();
     cur_group = get_cur_groupname();
@@ -2098,6 +2101,7 @@ check_and_warn_user_startup(gchar *cf_na
     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
     simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
   }
+*/

 #ifdef _WIN32
   /* Warn the user if npf.sys isn't loaded. */
```

Generate a backported patch for the SUSE target version.

[Assistant]
Index: ui/gtk/main.c
===================================================================
--- ui/gtk/main.c.orig	2012-08-10 01:35:00.000000000 +0100
+++ ui/gtk/main.c	2012-08-15 20:28:59.000000000 +0100
@@ -1399,11 +1399,13 @@ main_colorize_changed(gboolean packet_li

 static GtkWidget           *close_dlg = NULL;

+/*
 static void
 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
 {
     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
 }
+*/

 #ifdef _WIN32
 static void
@@ -2081,9 +2083,10 @@ check_and_warn_user_startup(gchar *cf_na
 #endif
 {
   gchar               *cur_user, *cur_group;
-  gpointer             priv_warning_dialog;
+//  gpointer             priv_warning_dialog;

   /* Tell the user not to run as root. */
+/*
   if (running_with_special_privs() && recent.privs_warn_if_elevated) {
     cur_user = get_cur_username();
     cur_group = get_cur_groupname();
@@ -2098,6 +2101,7 @@ check_and_warn_user_startup(gchar *cf_na
     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
     simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
   }
+*/

 #ifdef _WIN32
   /* Warn the user if npf.sys isn't loaded. */