------------------------------------------------------------ revno: 13670 revision-id: squid3@treenet.co.nz-20141203114128-i9f1ou00f6q97k09 parent: squid3@treenet.co.nz-20141203113859-p9jwbfc1oueaj3ft fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4131 author: Alex Rousskov , Amos Jeffries committer: Amos Jeffries branch nick: 3.5 timestamp: Wed 2014-12-03 03:41:28 -0800 message: Bug 4131: SIGSEGV at store.cc:962 content_length > store_maxobjsize ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20141203114128-i9f1ou00f6q97k09 # target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 # testament_sha1: 22f0ba0d4f9eaf99107e937964a7b0921029f389 # timestamp: 2014-12-03 11:45:02 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 # base_revision_id: squid3@treenet.co.nz-20141203113859-\ # p9jwbfc1oueaj3ft # # Begin patch === modified file 'src/Store.h' --- src/Store.h 2014-09-13 13:59:43 +0000 +++ src/Store.h 2014-12-03 11:41:28 +0000 @@ -225,6 +225,8 @@ void transientsAbandonmentCheck(); private: + bool checkTooBig() const; + static MemAllocator *pool; unsigned short lock_count; /* Assume < 65536! */ === modified file 'src/store.cc' --- src/store.cc 2014-09-22 19:06:19 +0000 +++ src/store.cc 2014-12-03 11:41:28 +0000 @@ -892,6 +892,7 @@ int private_key; int too_many_open_files; int too_many_open_fds; + int missing_parts; } no; struct { @@ -927,6 +928,18 @@ return 0; } +bool +StoreEntry::checkTooBig() const +{ + if (mem_obj->endOffset() > store_maxobjsize) + return true; + + if (getReply()->content_length < 0) + return false; + + return (getReply()->content_length > store_maxobjsize); +} + // TODO: move "too many open..." checks outside -- we are called too early/late bool StoreEntry::checkCachable() @@ -958,9 +971,12 @@ debugs(20, 3, "StoreEntry::checkCachable: NO: negative cached"); ++store_check_cachable_hist.no.negative_cached; return 0; /* avoid release call below */ - } else if ((getReply()->content_length > 0 && - getReply()->content_length > store_maxobjsize) || - mem_obj->endOffset() > store_maxobjsize) { + } else if (!mem_obj || !getReply()) { + // XXX: In bug 4131, we forgetHit() without mem_obj, so we need + // this segfault protection, but how can we get such a HIT? + debugs(20, 2, "StoreEntry::checkCachable: NO: missing parts: " << *this); + ++store_check_cachable_hist.no.missing_parts; + } else if (checkTooBig()) { debugs(20, 2, "StoreEntry::checkCachable: NO: too big"); ++store_check_cachable_hist.no.too_big; } else if (checkTooSmall()) { @@ -1008,6 +1024,8 @@ store_check_cachable_hist.no.wrong_content_length); storeAppendPrintf(sentry, "no.negative_cached\t%d\n", store_check_cachable_hist.no.negative_cached); + storeAppendPrintf(sentry, "no.missing_parts\t%d\n", + store_check_cachable_hist.no.missing_parts); storeAppendPrintf(sentry, "no.too_big\t%d\n", store_check_cachable_hist.no.too_big); storeAppendPrintf(sentry, "no.too_small\t%d\n",