diff options
author | jdolecek <jdolecek@pkgsrc.org> | 2016-08-19 09:34:46 +0000 |
---|---|---|
committer | jdolecek <jdolecek@pkgsrc.org> | 2016-08-19 09:34:46 +0000 |
commit | 0c59b095e949645d7556b085aa81026114a08eb8 (patch) | |
tree | 19fbcd86ba4b5af1439c3c6405a52f3de30066ea /www | |
parent | d994eedea29966e7358c91b89ec55243fa02f523 (diff) | |
download | pkgsrc-0c59b095e949645d7556b085aa81026114a08eb8.tar.gz |
add patch for apcu memory allocation failure handling, submitted as
https://bugs.php.net/bug.php?id=72801
Diffstat (limited to 'www')
-rw-r--r-- | www/php-apcu/Makefile | 3 | ||||
-rw-r--r-- | www/php-apcu/distinfo | 3 | ||||
-rw-r--r-- | www/php-apcu/patches/patch-apc_cache.c | 333 |
3 files changed, 337 insertions, 2 deletions
diff --git a/www/php-apcu/Makefile b/www/php-apcu/Makefile index 21666ac09ee..79e12f0c989 100644 --- a/www/php-apcu/Makefile +++ b/www/php-apcu/Makefile @@ -1,7 +1,8 @@ -# $NetBSD: Makefile,v 1.4 2016/08/11 22:54:16 jdolecek Exp $ +# $NetBSD: Makefile,v 1.5 2016/08/19 09:34:46 jdolecek Exp $ MODNAME= apcu PECL_VERSION= 5.1.5 +PKGREVISION= 1 CATEGORIES+= sysutils MAINTAINER= pkgsrc-users@NetBSD.org diff --git a/www/php-apcu/distinfo b/www/php-apcu/distinfo index 5801dcd2627..fca789bb459 100644 --- a/www/php-apcu/distinfo +++ b/www/php-apcu/distinfo @@ -1,8 +1,9 @@ -$NetBSD: distinfo,v 1.3 2016/07/26 09:22:40 jdolecek Exp $ +$NetBSD: distinfo,v 1.4 2016/08/19 09:34:46 jdolecek Exp $ SHA1 (php-apcu/apcu-5.1.5.tgz) = 1fe5f87808fd51f45b1fa2a7f67ae45b0c8336fb RMD160 (php-apcu/apcu-5.1.5.tgz) = b4b9c4ffe34ae5d1f27ae5033fb3ad06444cbf97 SHA512 (php-apcu/apcu-5.1.5.tgz) = ffa3e666f354c8fd2ab163db9c8352066d27a1cd6aebe4d8f374052f14a90dbe752efc27c6e927cbf75fc48b6f673e639b07ceeffc2a68402a778cc6a8b18fbc Size (php-apcu/apcu-5.1.5.tgz) = 109196 bytes SHA1 (patch-.._package.xml) = 2012bc96eaa53679b457b7230fb10634aca2bb6a +SHA1 (patch-apc_cache.c) = c4ff5659b589e345d676831ab5bd9642c5af39a1 SHA1 (patch-config.m4) = 8bbec8aff40c4d19fa46166dae1507316bf6e3bb diff --git a/www/php-apcu/patches/patch-apc_cache.c b/www/php-apcu/patches/patch-apc_cache.c new file mode 100644 index 00000000000..47ef951a51e --- /dev/null +++ b/www/php-apcu/patches/patch-apc_cache.c @@ -0,0 +1,333 @@ +$NetBSD: patch-apc_cache.c,v 1.1 2016/08/19 09:34:46 jdolecek Exp $ + +Fix for SIGSEGvs when memory allocation fails. + +https://bugs.php.net/bug.php?id=72801 + +--- apc_cache.c.orig 2016-06-07 12:41:02.000000000 +0000 ++++ apc_cache.c +@@ -46,7 +46,7 @@ typedef int (*ht_check_copy_fun_t)(Bucke + + #define CHECK(p) { if ((p) == NULL) return NULL; } + +-static APC_HOTSPOT void my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt); ++static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt); + + /* {{{ make_prime */ + static int const primes[] = { +@@ -108,22 +108,24 @@ apc_cache_slot_t* make_slot(apc_cache_t* + /* copy identifier */ + zend_string *copiedKey = apc_pstrcpy(key->str, value->pool); + +- if (copiedKey) { ++ if (copiedKey == NULL) { ++ value->pool->pfree(value->pool, p); ++ return NULL; ++ } + +- /* set slot data */ +- p->key = key[0]; +- p->key.str = copiedKey; +- p->value = value; ++ /* set slot data */ ++ p->key = key[0]; ++ p->key.str = copiedKey; ++ p->value = value; + +- /* set slot relation */ +- p->next = next; ++ /* set slot relation */ ++ p->next = next; + +- /* set slot defaults */ +- p->nhits = 0; +- p->ctime = t; +- p->atime = t; +- p->dtime = 0; +- } ++ /* set slot defaults */ ++ p->nhits = 0; ++ p->ctime = t; ++ p->atime = t; ++ p->dtime = 0; + } + + return p; +@@ -232,8 +234,12 @@ PHP_APCU_API int APC_SERIALIZER_NAME(php + PHP_VAR_SERIALIZE_INIT(var_hash); + php_var_serialize(&strbuf, (zval*) value, &var_hash); + PHP_VAR_SERIALIZE_DESTROY(var_hash); +- if(strbuf.s->val) { ++ ++ if (strbuf.s != NULL) { + *buf = (unsigned char *)estrndup(ZSTR_VAL(strbuf.s), ZSTR_LEN(strbuf.s)); ++ if (*buf == NULL) ++ return 0; ++ + *buf_len = ZSTR_LEN(strbuf.s); + smart_str_free(&strbuf); + return 1; +@@ -269,6 +275,11 @@ PHP_APCU_API apc_cache_t* apc_cache_crea + /* allocate pointer by normal means */ + cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t)); + ++ if (!cache) { ++ apc_error("Unable to allocate memory for cache structures. (Perhaps your memory_limit isn't large enough?). "); ++ return NULL; ++ } ++ + /* calculate cache size for shm allocation */ + cache_size = sizeof(apc_cache_header_t) + nslots*sizeof(apc_cache_slot_t*); + +@@ -495,12 +506,13 @@ static inline apc_cache_entry_t* apc_cac + static inline zend_bool apc_cache_fetch_internal(apc_cache_t* cache, zend_string *key, apc_cache_entry_t *entry, time_t t, zval **dst) { + /* context for copying out */ + apc_context_t ctxt = {0, }; ++ zval *rv; + + /* create unpool context */ + if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0)) { + + /* copy to destination */ +- apc_cache_fetch_zval(&ctxt, *dst, &entry->val); ++ rv = apc_cache_fetch_zval(&ctxt, *dst, &entry->val); + + /* release entry */ + apc_cache_release(cache, entry); +@@ -508,7 +520,7 @@ static inline zend_bool apc_cache_fetch_ + /* destroy context */ + apc_cache_destroy_context(&ctxt ); + +- return 1; ++ return (rv != NULL) ? 1 : 0; + } + + return 0; +@@ -1268,7 +1280,8 @@ static zend_always_inline int apc_array_ + } + } while (0); + +- my_copy_zval(&q->val, data, ctxt); ++ if (my_copy_zval(&q->val, data, ctxt) == NULL) ++ return 0; + + q->h = p->h; + if (packed) { +@@ -1341,7 +1354,11 @@ static APC_HOTSPOT HashTable* my_copy_ha + + if (ctxt->copy == APC_COPY_IN) { + target = (HashTable*) pool->palloc(pool, sizeof(HashTable)); +- } else ALLOC_HASHTABLE(target); ++ } else ++ ALLOC_HASHTABLE(target); ++ ++ if (target == NULL) ++ goto bad; + + GC_REFCOUNT(target) = 1; + GC_TYPE_INFO(target) = IS_ARRAY; +@@ -1366,7 +1383,12 @@ static APC_HOTSPOT HashTable* my_copy_ha + target->nNextFreeElement = source->nNextFreeElement; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); +- } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ } else ++ HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ ++ if (HT_GET_DATA_ADDR(target) == NULL) ++ goto bad; ++ + target->nInternalPointer = source->nInternalPointer; + memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source)); + if (target->nNumOfElements > 0 && +@@ -1385,7 +1407,12 @@ static APC_HOTSPOT HashTable* my_copy_ha + target->nNextFreeElement = source->nNextFreeElement; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); +- } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ } else ++ HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ ++ if (HT_GET_DATA_ADDR(target) == NULL) ++ goto bad; ++ + target->nInternalPointer = source->nInternalPointer; + HT_HASH_RESET_PACKED(target); + +@@ -1409,7 +1436,12 @@ static APC_HOTSPOT HashTable* my_copy_ha + target->nInternalPointer = HT_INVALID_IDX; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); +- } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ } else ++ HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); ++ ++ if (HT_GET_DATA_ADDR(target) == NULL) ++ goto bad; ++ + HT_HASH_RESET(target); + + if (target->u.flags & HASH_FLAG_STATIC_KEYS) { +@@ -1432,6 +1464,18 @@ static APC_HOTSPOT HashTable* my_copy_ha + } + } + return target; ++ ++ bad: ++ /* some kind of memory allocation failure */ ++ if (target) { ++ if (ctxt->copy == APC_COPY_IN) { ++ pool->pfree(pool, target); ++ } else { ++ FREE_HASHTABLE(target); ++ } ++ } ++ ++ return NULL; + } + + static APC_HOTSPOT zend_reference* my_copy_reference(const zend_reference* src, apc_context_t *ctxt) { +@@ -1454,10 +1498,14 @@ static APC_HOTSPOT zend_reference* my_co + dst = emalloc(sizeof(zend_reference)); + } + ++ if (dst == NULL) ++ return NULL; ++ + GC_REFCOUNT(dst) = 1; + GC_TYPE_INFO(dst) = IS_REFERENCE; +- +- my_copy_zval(&dst->val, &src->val, ctxt); ++ ++ if (my_copy_zval(&dst->val, &src->val, ctxt) == NULL) ++ return NULL; + + if (ctxt->copied.nTableSize) { + zend_hash_index_update_ptr(&ctxt->copied, (uintptr_t) src, dst); +@@ -1467,7 +1515,7 @@ static APC_HOTSPOT zend_reference* my_co + } + + /* {{{ my_copy_zval */ +-static APC_HOTSPOT void my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) ++static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) + { + apc_pool* pool = ctxt->pool; + +@@ -1481,8 +1529,9 @@ static APC_HOTSPOT void my_copy_zval(zva + zval *rc = zend_hash_index_find( + &ctxt->copied, (uintptr_t) Z_COUNTED_P(src)); + if (rc) { ++ /* this does not allocate memory, so always succeeds */ + ZVAL_COPY(dst, rc); +- return; ++ return dst; + } + } + } +@@ -1497,12 +1546,14 @@ static APC_HOTSPOT void my_copy_zval(zva + break; + + case IS_REFERENCE: +- Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt); +- break; ++ if ((Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt)) == NULL) ++ return NULL; ++ break; + + case IS_INDIRECT: +- my_copy_zval(dst, Z_INDIRECT_P(src), ctxt); +- break; ++ if (my_copy_zval(dst, Z_INDIRECT_P(src), ctxt) == NULL) ++ return NULL; ++ break; + + case IS_CONSTANT: + case IS_STRING: +@@ -1512,20 +1563,26 @@ static APC_HOTSPOT void my_copy_zval(zva + Z_TYPE_INFO_P(dst) = IS_STRING_EX; + Z_STR_P(dst) = apc_pstrcpy(Z_STR_P(src), pool); + } ++ if (Z_STR_P(dst) == NULL) ++ return NULL; + break; + + case IS_ARRAY: + if(ctxt->serializer == NULL) { +- Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt); ++ if ((Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt)) == NULL) ++ return NULL; + break; + } + + /* break intentionally omitted */ + + case IS_OBJECT: +- if(ctxt->copy == APC_COPY_IN) { ++ if (ctxt->copy == APC_COPY_IN) { + dst = my_serialize_object(dst, src, ctxt); +- } else dst = my_unserialize_object(dst, src, ctxt); ++ } else ++ dst = my_unserialize_object(dst, src, ctxt); ++ if (dst == NULL) ++ return NULL; + break; + + case IS_CALLABLE: +@@ -1540,14 +1597,15 @@ static APC_HOTSPOT void my_copy_zval(zva + if (Z_REFCOUNTED_P(dst) && ctxt->copied.nTableSize) { + zend_hash_index_update(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src), dst); + } ++ ++ return dst; + } + /* }}} */ + + /* {{{ apc_copy_zval */ + PHP_APCU_API zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) + { +- my_copy_zval(dst, src, ctxt); +- return dst; ++ return my_copy_zval(dst, src, ctxt); + } + /* }}} */ + +@@ -1558,13 +1616,14 @@ PHP_APCU_API zval* apc_cache_store_zval( + /* Maintain a list of zvals we've copied to properly handle recursive structures */ + zend_hash_init(&ctxt->copied, 16, NULL, NULL, 0); + dst = apc_copy_zval(dst, src, ctxt); ++ /* remove from copied regardless if allocation failure */ + zend_hash_destroy(&ctxt->copied); + ctxt->copied.nTableSize=0; + } else { + dst = apc_copy_zval(dst, src, ctxt); + } + +- if (EG(exception)) { ++ if (dst == NULL || EG(exception)) { + return NULL; + } + +@@ -1579,11 +1638,13 @@ PHP_APCU_API zval* apc_cache_fetch_zval( + /* Maintain a list of zvals we've copied to properly handle recursive structures */ + zend_hash_init(&ctxt->copied, 16, NULL, NULL, 0); + dst = apc_copy_zval(dst, src, ctxt); ++ /* remove from copied regardless if allocation failure */ + zend_hash_destroy(&ctxt->copied); + ctxt->copied.nTableSize=0; + } else { + dst = apc_copy_zval(dst, src, ctxt); + } ++ + return dst; + } + /* }}} */ +@@ -1602,7 +1663,8 @@ PHP_APCU_API apc_cache_entry_t* apc_cach + /* set key for serializer */ + ctxt->key = key; + +- if(!apc_cache_store_zval(&entry->val, val, ctxt)) { ++ if (!apc_cache_store_zval(&entry->val, val, ctxt)) { ++ pool->pfree(pool, entry); + return NULL; + } + |