Date: Sunday, June 16, 2019 @ 14:20:03
  Author: dreisner
Revision: 356201

upgpkg: curl 7.65.1-3

- backport more upstream fixes for crashes in multi stack (FS#62892)

Added:
  curl/trunk/0001-multi-fix-the-transfer-hash-function.patch
  curl/trunk/0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch
Modified:
  curl/trunk/PKGBUILD

-----------------------------------------------------------------+
 0001-multi-fix-the-transfer-hash-function.patch                 |   30 +
 0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch |  247 
++++++++++
 PKGBUILD                                                        |   16 
 3 files changed, 288 insertions(+), 5 deletions(-)

Added: 0001-multi-fix-the-transfer-hash-function.patch
===================================================================
--- 0001-multi-fix-the-transfer-hash-function.patch                             
(rev 0)
+++ 0001-multi-fix-the-transfer-hash-function.patch     2019-06-16 14:20:03 UTC 
(rev 356201)
@@ -0,0 +1,30 @@
+From 6cc18c59a77bccdd04f65a9abcc9a2b2f88d368d Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <dan...@haxx.se>
+Date: Thu, 13 Jun 2019 17:07:59 +0200
+Subject: [PATCH] multi: fix the transfer hash function
+
+Follow-up from 8b987cc7eb
+
+Reported-by: Tom van der Woerdt
+Fixes #4018
+Closes #4024
+---
+ lib/multi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/multi.c b/lib/multi.c
+index 34a74b8fb..abd8ae563 100644
+--- a/lib/multi.c
++++ b/lib/multi.c
+@@ -214,7 +214,7 @@ static struct Curl_sh_entry *sh_getentry(struct curl_hash 
*sh,
+ #define TRHASH_SIZE 13
+ static size_t trhash(void *key, size_t key_length, size_t slots_num)
+ {
+-  size_t keyval = (size_t)key; /* this is a data pointer */
++  size_t keyval = (size_t)*(struct Curl_easy **)key;
+   (void) key_length;
+ 
+   return (keyval % slots_num);
+-- 
+2.22.0
+

Added: 0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch
===================================================================
--- 0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch             
                (rev 0)
+++ 0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch     
2019-06-16 14:20:03 UTC (rev 356201)
@@ -0,0 +1,247 @@
+From 8b987cc7eb8bd58eaf7c184e0db7103a236704bd Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <dan...@haxx.se>
+Date: Tue, 11 Jun 2019 23:50:26 +0200
+Subject: [PATCH] multi: fix the transfer hashes in the socket hash entries
+
+- The transfer hashes weren't using the correct keys so removing entries
+  failed.
+
+- Simplified the iteration logic over transfers sharing the same socket and
+  they now simply are set to expire and thus get handled in the "regular"
+  timer loop instead.
+
+Reported-by: Tom van der Woerdt
+Fixes #4012
+Closes #4014
+---
+ lib/hash.h  |  4 +--
+ lib/multi.c | 79 ++++++++++++++---------------------------------------
+ 2 files changed, 22 insertions(+), 61 deletions(-)
+
+diff --git a/lib/hash.h b/lib/hash.h
+index 90a25d1ca..558d0f47c 100644
+--- a/lib/hash.h
++++ b/lib/hash.h
+@@ -7,7 +7,7 @@
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2017, Daniel Stenberg, <dan...@haxx.se>, et al.
++ * Copyright (C) 1998 - 2019, Daniel Stenberg, <dan...@haxx.se>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+@@ -80,7 +80,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t 
key_len);
+ void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
+ void Curl_hash_apply(struct curl_hash *h, void *user,
+                      void (*cb)(void *user, void *ptr));
+-int Curl_hash_count(struct curl_hash *h);
++#define Curl_hash_count(h) ((h)->size)
+ void Curl_hash_destroy(struct curl_hash *h);
+ void Curl_hash_clean(struct curl_hash *h);
+ void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+diff --git a/lib/multi.c b/lib/multi.c
+index 33f0d9fd1..34a74b8fb 100644
+--- a/lib/multi.c
++++ b/lib/multi.c
+@@ -194,9 +194,6 @@ struct Curl_sh_entry {
+   unsigned int users; /* number of transfers using this */
+   unsigned int readers; /* this many transfers want to read */
+   unsigned int writers; /* this many transfers want to write */
+-  unsigned int blocked:1; /* if TRUE, blocked from being removed */
+-  unsigned int removed:1; /* if TRUE, this entry is "removed" but prevented
+-                             from it by "blocked" being set! */
+ };
+ /* bits for 'action' having no bits means this socket is not expecting any
+    action */
+@@ -205,16 +202,11 @@ struct Curl_sh_entry {
+ 
+ /* look up a given socket in the socket hash, skip invalid sockets */
+ static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
+-                                         curl_socket_t s,
+-                                         bool also_hidden)
++                                         curl_socket_t s)
+ {
+   if(s != CURL_SOCKET_BAD) {
+     /* only look for proper sockets */
+-    struct Curl_sh_entry *entry =
+-      Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+-    if(entry && entry->removed && !also_hidden)
+-      return NULL;
+-    return entry;
++    return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+   }
+   return NULL;
+ }
+@@ -233,7 +225,7 @@ static size_t trhash_compare(void *k1, size_t k1_len, void 
*k2, size_t k2_len)
+   (void)k1_len;
+   (void)k2_len;
+ 
+-  return k1 == k2;
++  return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2;
+ }
+ 
+ static void trhash_dtor(void *nada)
+@@ -246,13 +238,11 @@ static void trhash_dtor(void *nada)
+ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+                                          curl_socket_t s)
+ {
+-  struct Curl_sh_entry *there = sh_getentry(sh, s, TRUE);
++  struct Curl_sh_entry *there = sh_getentry(sh, s);
+   struct Curl_sh_entry *check;
+ 
+   if(there) {
+     /* it is present, return fine */
+-    if(there->removed)
+-      there->removed = FALSE; /* clear the removed bit */
+     return there;
+   }
+ 
+@@ -281,17 +271,11 @@ static struct Curl_sh_entry *sh_addentry(struct 
curl_hash *sh,
+ static void sh_delentry(struct Curl_sh_entry *entry,
+                         struct curl_hash *sh, curl_socket_t s)
+ {
+-  if(entry->blocked) {
+-    entry->removed = TRUE; /* pretend */
+-    return;
+-  }
+-  else {
+-    Curl_hash_destroy(&entry->transfers);
++  Curl_hash_destroy(&entry->transfers);
+ 
+-    /* We remove the hash entry. This will end up in a call to
+-       sh_freeentry(). */
+-    Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+-  }
++  /* We remove the hash entry. This will end up in a call to
++     sh_freeentry(). */
++  Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+ }
+ 
+ /*
+@@ -2266,7 +2250,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
+     s = socks[i];
+ 
+     /* get it from the hash */
+-    entry = sh_getentry(&multi->sockhash, s, FALSE);
++    entry = sh_getentry(&multi->sockhash, s);
+ 
+     if(curraction & GETSOCK_READSOCK(i))
+       action |= CURL_POLL_IN;
+@@ -2312,7 +2296,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
+         entry->writers++;
+ 
+       /* add 'data' to the transfer hash on this socket! */
+-      if(!Curl_hash_add(&entry->transfers, (char *)data, /* hash key */
++      if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
+                         sizeof(struct Curl_easy *), data))
+         return CURLM_OUT_OF_MEMORY;
+     }
+@@ -2350,7 +2334,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
+     if(stillused)
+       continue;
+ 
+-    entry = sh_getentry(&multi->sockhash, s, FALSE);
++    entry = sh_getentry(&multi->sockhash, s);
+     /* if this is NULL here, the socket has been closed and notified so
+        already by Curl_multi_closed() */
+     if(entry) {
+@@ -2370,8 +2354,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
+       }
+       else {
+         /* still users, but remove this handle as a user of this socket */
+-        Curl_hash_delete(&entry->transfers, (char *)data,
+-                         sizeof(struct Curl_easy *));
++        if(Curl_hash_delete(&entry->transfers, (char *)&data,
++                            sizeof(struct Curl_easy *))) {
++          DEBUGASSERT(NULL);
++        }
+       }
+     }
+   } /* for loop over numsocks */
+@@ -2406,7 +2392,7 @@ void Curl_multi_closed(struct Curl_easy *data, 
curl_socket_t s)
+     if(multi) {
+       /* this is set if this connection is part of a handle that is added to
+          a multi handle, and only then this is necessary */
+-      struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s, FALSE);
++      struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+ 
+       if(entry) {
+         if(multi->socket_cb)
+@@ -2506,7 +2492,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
+     return result;
+   }
+   if(s != CURL_SOCKET_TIMEOUT) {
+-    struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s, FALSE);
++    struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+ 
+     if(!entry)
+       /* Unmatched socket, we can't act on it but we ignore this fact.  In
+@@ -2518,19 +2504,12 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
+     else {
+       struct curl_hash_iterator iter;
+       struct curl_hash_element *he;
+-      SIGPIPE_VARIABLE(pipe_st);
+-
+-      /* block this sockhash entry from being removed in a sub function called
+-         from here */
+-      entry->blocked = TRUE;
+-      DEBUGASSERT(!entry->removed);
+ 
+       /* the socket can be shared by many transfers, iterate */
+       Curl_hash_start_iterate(&entry->transfers, &iter);
+       for(he = Curl_hash_next_element(&iter); he;
+           he = Curl_hash_next_element(&iter)) {
+         data = (struct Curl_easy *)he->ptr;
+-
+         DEBUGASSERT(data);
+         DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
+ 
+@@ -2538,25 +2517,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
+           /* set socket event bitmask if they're not locked */
+           data->conn->cselect_bits = ev_bitmask;
+ 
+-        sigpipe_ignore(data, &pipe_st);
+-        result = multi_runsingle(multi, now, data);
+-        sigpipe_restore(&pipe_st);
+-
+-        if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
+-          /* clear the bitmask only if not locked */
+-          data->conn->cselect_bits = 0;
+-
+-        if(CURLM_OK >= result) {
+-          /* get the socket(s) and check if the state has been changed since
+-             last */
+-          result = singlesocket(multi, data);
+-          if(result)
+-            return result;
+-        }
+-      }
+-      if(entry->removed) {
+-        entry->blocked = FALSE; /* unblock */
+-        sh_delentry(entry, &multi->sockhash, s); /* delete for real */
++        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+       }
+ 
+       /* Now we fall-through and do the timer-based stuff, since we don't want
+@@ -3005,7 +2966,7 @@ CURLMcode curl_multi_assign(struct Curl_multi *multi, 
curl_socket_t s,
+   if(multi->in_callback)
+     return CURLM_RECURSIVE_API_CALL;
+ 
+-  there = sh_getentry(&multi->sockhash, s, FALSE);
++  there = sh_getentry(&multi->sockhash, s);
+ 
+   if(!there)
+     return CURLM_BAD_SOCKET;
+@@ -3094,7 +3055,7 @@ void Curl_multi_dump(struct Curl_multi *multi)
+               statename[data->mstate], data->numsocks);
+       for(i = 0; i < data->numsocks; i++) {
+         curl_socket_t s = data->sockets[i];
+-        struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s, FALSE);
++        struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+ 
+         fprintf(stderr, "%d ", (int)s);
+         if(!entry) {
+-- 
+2.22.0
+

Modified: PKGBUILD
===================================================================
--- PKGBUILD    2019-06-16 08:48:19 UTC (rev 356200)
+++ PKGBUILD    2019-06-16 14:20:03 UTC (rev 356201)
@@ -6,7 +6,7 @@
 
 pkgname=curl
 pkgver=7.65.1
-pkgrel=2
+pkgrel=3
 pkgdesc="An URL retrieval utility and library"
 arch=('x86_64')
 url="https://curl.haxx.se";
@@ -15,15 +15,23 @@
          'libidn2' 'libidn2.so')
 provides=('libcurl.so')
 source=("https://curl.haxx.se/download/$pkgname-$pkgver.tar.gz"{,.asc}
-        '0001-multi-make-sure-data-can-present-in-several-sockhash.patch')
+        '0001-multi-make-sure-data-can-present-in-several-sockhash.patch'
+        '0001-multi-fix-the-transfer-hash-function.patch'
+        '0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch')
 
sha512sums=('0a4b81d115f579df8301859f7d06d00bd9820cbf2fb6b63c6a49418aa174ab32bcbc8942f032f2ea924d208f147de8a30f02f6b922f627d3d9d4afc60df8a39f'
             'SKIP'
-            
'90e0646352baa3b948fc18578eae9f0c878abfa3aec20f19697e8974e669592866a2d778c387d6f693cbcb9aa10cb965a7c7619c7915f4031aa1514a808b9fd3')
+            
'90e0646352baa3b948fc18578eae9f0c878abfa3aec20f19697e8974e669592866a2d778c387d6f693cbcb9aa10cb965a7c7619c7915f4031aa1514a808b9fd3'
+            
'140f733410cb3d6d006faf113ba91bbdef5adc127ac7df5b5e415c24fed4ff68ec84ad9750d7f8d209c4a2f656f64b23171d76ebb5f6c6ded19fcd4588157c8f'
+            
'52466a96916d42fef5a4719795d8498b530c026a7e6154e137ae6c399a8cb77da0ce89e314e214ff756057a9966c8f4bebeaa4f54b887d64a3d9d60ffe96acf3')
 validpgpkeys=('27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2') # Daniel Stenberg
 
 build() {
   cd "$pkgname-$pkgver"
 
+  patch -Np1 < 
../0001-multi-make-sure-data-can-present-in-several-sockhash.patch
+  patch -Np1 < 
../0001-multi-fix-the-transfer-hashes-in-the-socket-hash-ent.patch
+  patch -Np1 < ../0001-multi-fix-the-transfer-hash-function.patch
+
   ./configure \
       --prefix=/usr \
       --mandir=/usr/share/man \
@@ -38,8 +46,6 @@
       --with-random=/dev/urandom \
       --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt
 
-  patch -Np1 < 
../0001-multi-make-sure-data-can-present-in-several-sockhash.patch
-
   make
 }
 

Reply via email to