From 9097fb54c534175c0bda30ed2d607c981fa64be6 Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Tue, 12 Apr 2016 16:52:34 -0400 Subject: [PATCH] Use pool counter for generating large diffs to prevent DoS. Bug: T130947 Change-Id: If560844664051c04e01b954377b4bdfdb744d13f Signed-off-by: Chad Horohoe --- includes/diff/DifferenceEngine.php | 35 ++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index caef7f162d..8985d511e0 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -842,19 +842,36 @@ class DifferenceEngine extends ContextSource { * @return bool|string */ public function generateTextDiffBody( $otext, $ntext ) { - $time = microtime( true ); + $diff = function() use ( $otext, $ntext ) { + $time = microtime( true ); - $result = $this->textDiff( $otext, $ntext ); + $result = $this->textDiff( $otext, $ntext ); - $time = intval( ( microtime( true ) - $time ) * 1000 ); - $this->getStats()->timing( 'diff_time', $time ); - // Log requests slower than 99th percentile - if ( $time > 100 && $this->mOldPage && $this->mNewPage ) { - wfDebugLog( 'diff', - "$time ms diff: {$this->mOldid} -> {$this->mNewid} {$this->mNewPage}" ); + $time = intval( ( microtime( true ) - $time ) * 1000 ); + $this->getStats()->timing( 'diff_time', $time ); + // Log requests slower than 99th percentile + if ( $time > 100 && $this->mOldPage && $this->mNewPage ) { + wfDebugLog( 'diff', + "$time ms diff: {$this->mOldid} -> {$this->mNewid} {$this->mNewPage}" ); + } + + return $result; + }; + + $error = function( $status ) { + throw new FatalError( $status->getWikiText() ); + }; + + // Use PoolCounter if the diff looks like it can be expensive + if ( strlen( $otext ) + strlen( $ntext ) > 20000 ) { + $work = new PoolCounterWorkViaCallback( 'diff', + md5( $otext ) . md5( $ntext ), + [ 'doWork' => $diff, 'error' => $error ] + ); + return $work->execute(); } - return $result; + return $diff(); } /** -- 2.20.1