Merge branch 'PHP-5.6' into PHP-7.0

* PHP-5.6:
  Fix #73549: Use after free when stream is passed to imagepng
This commit is contained in:
Stanislav Malyshev 2016-11-27 14:53:27 -08:00
commit 1cb58ead70
2 changed files with 39 additions and 1 deletions

View File

@ -57,6 +57,16 @@ static int _php_image_stream_putbuf(struct gdIOCtx *ctx, const void* buf, int l)
} /* }}} */ } /* }}} */
static void _php_image_stream_ctxfree(struct gdIOCtx *ctx) /* {{{ */ static void _php_image_stream_ctxfree(struct gdIOCtx *ctx) /* {{{ */
{
if(ctx->data) {
ctx->data = NULL;
}
if(ctx) {
efree(ctx);
}
} /* }}} */
static void _php_image_stream_ctxfreeandclose(struct gdIOCtx *ctx) /* {{{ */
{ {
if(ctx->data) { if(ctx->data) {
@ -82,6 +92,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
gdIOCtx *ctx = NULL; gdIOCtx *ctx = NULL;
zval *to_zval = NULL; zval *to_zval = NULL;
php_stream *stream; php_stream *stream;
int close_stream = 1;
/* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp(). /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
* The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
@ -120,6 +131,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
if (stream == NULL) { if (stream == NULL) {
RETURN_FALSE; RETURN_FALSE;
} }
close_stream = 0;
} else if (Z_TYPE_P(to_zval) == IS_STRING) { } else if (Z_TYPE_P(to_zval) == IS_STRING) {
if (CHECK_ZVAL_NULL_PATH(to_zval)) { if (CHECK_ZVAL_NULL_PATH(to_zval)) {
php_error_docref(NULL, E_WARNING, "Invalid 2nd parameter, filename must not contain null bytes"); php_error_docref(NULL, E_WARNING, "Invalid 2nd parameter, filename must not contain null bytes");
@ -156,7 +168,11 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
ctx = emalloc(sizeof(gdIOCtx)); ctx = emalloc(sizeof(gdIOCtx));
ctx->putC = _php_image_stream_putc; ctx->putC = _php_image_stream_putc;
ctx->putBuf = _php_image_stream_putbuf; ctx->putBuf = _php_image_stream_putbuf;
ctx->gd_free = _php_image_stream_ctxfree; if (close_stream) {
ctx->gd_free = _php_image_stream_ctxfreeandclose;
} else {
ctx->gd_free = _php_image_stream_ctxfree;
}
ctx->data = (void *)stream; ctx->data = (void *)stream;
} }

View File

@ -0,0 +1,22 @@
--TEST--
Bug #73549 (Use after free when stream is passed to imagepng)
--SKIPIF--
<?php
if (!extension_loaded('gd')) die('skip gd extension not available');
?>
--FILE--
<?php
$stream = fopen(__DIR__ . DIRECTORY_SEPARATOR . 'bug73549.png', 'w');
$im = imagecreatetruecolor(8, 8);
var_dump(imagepng($im, $stream));
var_dump($stream);
?>
===DONE===
--EXPECTF--
bool(true)
resource(%d) of type (stream)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73549.png');
?>