Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:89513 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 45019 invoked from network); 1 Dec 2015 16:17:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Dec 2015 16:17:15 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 209.85.223.182 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 209.85.223.182 mail-io0-f182.google.com Received: from [209.85.223.182] ([209.85.223.182:33955] helo=mail-io0-f182.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C5/A0-38618-908CD565 for ; Tue, 01 Dec 2015 11:17:14 -0500 Received: by ioir85 with SMTP id r85so14514821ioi.1 for ; Tue, 01 Dec 2015 08:17:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zend-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=IiSBz5q+jE8uhxJBrYnscK2JThwA9eN7EHlqWhzytoA=; b=Bm3ebUNgLw18NM/t+rQjRV/Puh3E9lRug7doRHAcA4yRTFnz8yJ4iPJkJcIkkKKxZf po8jZ8NRfJDmnJk/ofuEcimF3nGOtwiOK3iOmawsu+C6jC+QLT3ySDeF8unJCoQ4i12N oaKnkXHlq0zP/nyRmwBy6p8XF5lO/ycyP2flySw4UYCt+mUs6Ajr4XLC8DB52oXXxLCZ 9AnDYZyK7wXLn5Q1CnT0J8IQZaPod0b2iOZyLProrYCDNxVUXayWh5ZWPAeOLrdQy8VI qo6KuihS9zf5QaZbvQGBecOVuErByAdGhDok1pO6qY/TusM4mp1j4hwPGBNbEDPUKYGI if9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=IiSBz5q+jE8uhxJBrYnscK2JThwA9eN7EHlqWhzytoA=; b=LxoSsoZ4FlTDwqxJOf9ir4E0HUZw9cX8ulm5n5bDPDJUxfuAb8K2+VMu8OZcHUIudD poL+xauduJwNVTH27FzQZyF1ZskS4FExhVbjEIcZYTBa4q67GqFshafIT/JiBDm5OI2R Wo59ttQqV7jQDrNpF2OtnOUferlyY4z+neMa0E7b7gZpmnY0eHnQDkrLoH42nRenA4i1 sShbfcJy1epRMkzSA3dtBCsQyGR1R0+FI7viNMauKVBNZmTz6kuquirD63unN2UdbjrO 25Ib6KSggo2UrY7ZexIrRi8Z+0rHpPBkXPKciDPYo4+pun9aexJEJ+tSokC8rYu8lA4B +IRA== X-Gm-Message-State: ALoCoQkKgxorea/Goxk/bBpX31b/UjL72CwsIEKWI82FtwV+jmXYbLh7JST9sp8oNsRMkDLIky4/eOneDxyJz3Az10RPB/STkaKaHxCedRUFGgcUTa6LmBDdcy5bh4HpNQXEoJ5x4xKFmfYTQxdpFa4NcWEG4EqD1Vq8AC5WdeI2OZMU6bKCbQ4= MIME-Version: 1.0 X-Received: by 10.107.25.77 with SMTP id 74mr63527668ioz.196.1448986630231; Tue, 01 Dec 2015 08:17:10 -0800 (PST) Received: by 10.50.128.201 with HTTP; Tue, 1 Dec 2015 08:17:10 -0800 (PST) In-Reply-To: References: Date: Tue, 1 Dec 2015 19:17:10 +0300 Message-ID: To: Nikita Popov Cc: PHP internals , Anatol Belski , Remi Collet Content-Type: multipart/alternative; boundary=001a113fd4c06132bd0525d87de1 Subject: Re: [PHP-DEV] HashDos protection From: dmitry@zend.com (Dmitry Stogov) --001a113fd4c06132bd0525d87de1 Content-Type: text/plain; charset=UTF-8 On Tue, Dec 1, 2015 at 3:48 PM, Nikita Popov wrote: > On Tue, Dec 1, 2015 at 10:50 AM, Dmitry Stogov wrote: > >> Hi Nikita, >> >> few notes: >> >> It looks like the patch messes the attempt of catching the problem (few >> lines related to zend_hash_find_bucket changes) with optimization to >> compensate collision check overhead (everything else). I think it's better >> to separate these parts. >> > > The addition of zend_hash_add_or_return() isn't an optimization, it is > required to ensure that the check happens in all relevant cases. The code > previously used a combination of zend_hash_find() and zend_hash_add_new(). > However the whole purpose of the zend_hash_add_new() function is to skip > the part of the insertion operation where the collision count would be done. > > At this point I could either a) also count collisions in zend_hash_find(), > which is imho not a good option as it's enough to count once and not at > every lookup, or b) avoid the combination of zend_hash_find() and > zend_hash_add_new() by introducing a new zend_hash_add_or_return() function > (which does the same as the previous combination but also performs the > collision count). Alternatively I would also simply make > zend_hash_add_new() the same as zend_hash_add(), which is probably not > wanted either. > I got it now. > > >> Introduction of zend_hash_add_or_return() in 7.0.1 is going to make >> forward incompatibility with 7.0.0. However, we may reserve it for internal >> usage removing ZEND_API. >> > > I'm fine with not marking it ZEND_API in 7.0. > > >> I don't think PHP should prevent user from construction of arrays he >> likes, because of internal problems (like in your example). >> >> > $s = 1 << 16; $a = []; >> > for ($i = 0; count($a) < $s; $i += $s) { $a[$i] = 0; } >> >> It makes performance problem, but it doesn't mean we should kill it. >> We have "max_execution_time" to catch them all. >> > >> I think only big arrays coming from external sources should be checked. >> > > There is no way for PHP to know whether or not an array is constructed > from an external source. Yes, of course we can special case json_decode() > and unserialize(), but this would not fix the vulnerability for any array > that is created in PHP code. It's not exactly unusual to create arrays > which are in some way based on user input. > If this is a real problem, we should better provide an API for "safe" array construction from "unsafe" data. Also, if such arrays are constructed from many elements, it may make sense to insert all elements first and then rehash them. This will make O(2*N) complexity, even if all of them have the same hash value. > > Your solution is incomplete, anyway, because of crafting a single list >> with 10000 collisions, attacker will able to use N lists with 1000 >> collisions. >> > > One list with N*1000 collisions and N lists with 1000 collisions each have > very different asymptotic complexity. The former is O(N^2), while the > latter is O(N). The DOS attack is based on having O(N^2) complexity. > You are right of course about O(N) and O(N^2), but today affecting data-locality may make more harm then list length. The fact, that PHP7 is few times faster on your example, is caused by the linear placement of the collisions list. Once we start to work with randomized lists, in addition to complexity, we will also suffer from stalls because of the cache misses. Thanks. Dmitry. Nikita > --001a113fd4c06132bd0525d87de1--