Skip to content

Commit

Permalink
Fix heap-buffer-overflow in Image#wet_floor with ImageMagick 7
Browse files Browse the repository at this point in the history
The AddressSanitizer indicates heap-buffer-overflow at https://github.com/rmagick/rmagick/blob/655f48ff2fdc980be63bf656f2f5bef393c8d182/ext/RMagick/rmimage.c#L16057

```
$ CFLAGS='-O0 -g -fsanitize=address -fno-omit-frame-pointer' rake
...
==52655==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61d00082bc00 at pc 0x00011ae6566d bp 0x7ffee11df090 sp 0x7ffee11df088
READ of size 4 at 0x61d00082bc00 thread T0
    #0 0x11ae6566c in Image_wet_floor rmimage.c:16057
    #1 0x10f25bdf9 in call_cfunc_m1 vm_insnhelper.c:2336
    #2 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #3 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #4 0x10f219e74 in vm_call_method_each_type vm_insnhelper.c:2925
    #5 0x10f219649 in vm_call_method vm_insnhelper.c:3028
    #6 0x10f1bf95c in vm_call_general vm_insnhelper.c:3076
    #7 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    #8 0x10f1cdf3f in vm_exec_core insns.def:801
    #9 0x10f20a734 in rb_vm_exec vm.c:1920
    #10 0x10f2660c6 in invoke_block vm.c:1044
    #11 0x10f26559c in invoke_block_from_c_bh vm.c:1134
    #12 0x10f1fe93e in vm_yield_with_cref vm.c:1171
    #13 0x10f1ff972 in yield_under vm_eval.c:1877
    #14 0x10f201fc9 in rb_obj_instance_exec_internal vm_eval.c:2023
    #15 0x10f25bdf9 in call_cfunc_m1 vm_insnhelper.c:2336
    #16 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #17 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #18 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    #19 0x10f1cda91 in vm_exec_core insns.def:782
    #20 0x10f20a880 in rb_vm_exec vm.c:1929
    #21 0x10f2660c6 in invoke_block vm.c:1044
    #22 0x10f26559c in invoke_block_from_c_bh vm.c:1134
    #23 0x10f2650c0 in vm_yield vm.c:1179
    #24 0x10f1f86a4 in rb_yield_0 vm_eval.c:1227
    #25 0x10f1f8604 in rb_yield_1 vm_eval.c:1233
    #26 0x10f1f86e3 in rb_yield vm_eval.c:1243
    #27 0x10ea232c1 in rb_ary_collect array.c:3065
    #28 0x10f25be28 in call_cfunc_0 vm_insnhelper.c:2343
    #29 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #30 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #31 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    #32 0x10f1cda91 in vm_exec_core insns.def:782
    #33 0x10f20a734 in rb_vm_exec vm.c:1920
    #34 0x10f2660c6 in invoke_block vm.c:1044
    #35 0x10f26559c in invoke_block_from_c_bh vm.c:1134
    #36 0x10f2650c0 in vm_yield vm.c:1179
    #37 0x10f1f86a4 in rb_yield_0 vm_eval.c:1227
    #38 0x10f1f8604 in rb_yield_1 vm_eval.c:1233
    #39 0x10f1f86e3 in rb_yield vm_eval.c:1243
    #40 0x10ea232c1 in rb_ary_collect array.c:3065
    #41 0x10f25be28 in call_cfunc_0 vm_insnhelper.c:2343
    #42 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #43 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #44 0x10f219e74 in vm_call_method_each_type vm_insnhelper.c:2925
    #45 0x10f219649 in vm_call_method vm_insnhelper.c:3028
    #46 0x10f1bf95c in vm_call_general vm_insnhelper.c:3076
    rmagick#47 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    rmagick#48 0x10f1cda91 in vm_exec_core insns.def:782
    rmagick#49 0x10f20a880 in rb_vm_exec vm.c:1929
    rmagick#50 0x10f20efcf in rb_iseq_eval_main vm.c:2179
    rmagick#51 0x10ebcd82b in rb_ec_exec_node eval.c:277
    rmagick#52 0x10ebcd2ae in ruby_run_node eval.c:335
    rmagick#53 0x10ea0bd13 in main main.c:50
    rmagick#54 0x7fff67ac57fc in start (libdyld.dylib:x86_64+0x1a7fc)

0x61d00082bc00 is located 0 bytes to the right of 1920-byte region [0x61d00082b480,0x61d00082bc00)
allocated by thread T0 here:
    #0 0x10f85b107 in wrap_posix_memalign (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x62107)
    #1 0x11ae8d87c in rm_aligned_malloc rmmain.c:147
    #2 0x11b0dfa06 in AcquireAlignedMemory (libMagickCore-7.Q16HDRI.7.dylib:x86_64+0x10ea06)
    #3 0x11aff6a38 in OpenPixelCache (libMagickCore-7.Q16HDRI.7.dylib:x86_64+0x25a38)
    #4 0x11aff8c5d in GetImagePixelCache (libMagickCore-7.Q16HDRI.7.dylib:x86_64+0x27c5d)
    #5 0x11affb381 in SyncImagePixelCache (libMagickCore-7.Q16HDRI.7.dylib:x86_64+0x2a381)
    #6 0x11b001601 in SetImageAlphaChannel (libMagickCore-7.Q16HDRI.7.dylib:x86_64+0x30601)
    #7 0x11ae653b2 in Image_wet_floor rmimage.c:16013
    #8 0x10f25bdf9 in call_cfunc_m1 vm_insnhelper.c:2336
    #9 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #10 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #11 0x10f219e74 in vm_call_method_each_type vm_insnhelper.c:2925
    #12 0x10f219649 in vm_call_method vm_insnhelper.c:3028
    #13 0x10f1bf95c in vm_call_general vm_insnhelper.c:3076
    #14 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    #15 0x10f1cdf3f in vm_exec_core insns.def:801
    #16 0x10f20a734 in rb_vm_exec vm.c:1920
    #17 0x10f2660c6 in invoke_block vm.c:1044
    #18 0x10f26559c in invoke_block_from_c_bh vm.c:1134
    #19 0x10f1fe93e in vm_yield_with_cref vm.c:1171
    #20 0x10f1ff972 in yield_under vm_eval.c:1877
    #21 0x10f201fc9 in rb_obj_instance_exec_internal vm_eval.c:2023
    #22 0x10f25bdf9 in call_cfunc_m1 vm_insnhelper.c:2336
    #23 0x10f23aaa9 in vm_call_cfunc_with_frame vm_insnhelper.c:2514
    #24 0x10f21bf8b in vm_call_cfunc vm_insnhelper.c:2539
    #25 0x10f247393 in vm_sendish vm_insnhelper.c:4023
    #26 0x10f1cda91 in vm_exec_core insns.def:782
    #27 0x10f20a880 in rb_vm_exec vm.c:1929
    #28 0x10f2660c6 in invoke_block vm.c:1044
    #29 0x10f26559c in invoke_block_from_c_bh vm.c:1134

SUMMARY: AddressSanitizer: heap-buffer-overflow rmimage.c:16057 in Image_wet_floor
Shadow bytes around the buggy address:
  0x1c3a00105730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c3a00105740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c3a00105750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c3a00105760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c3a00105770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1c3a00105780:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c3a00105790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c3a001057a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c3a001057b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c3a001057c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c3a001057d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==52655==ABORTING
```

The address of variable `p` and `q` will be moved in https://github.com/rmagick/rmagick/blob/655f48ff2fdc980be63bf656f2f5bef393c8d182/ext/RMagick/rmimage.c#L16062-L16063

The overflow will be occurred with storing to moved address + index `x`.
  • Loading branch information
Watson1978 committed Dec 29, 2019
1 parent 655f48f commit e5c3677
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion ext/RMagick/rmimage.c
Expand Up @@ -16054,14 +16054,15 @@ Image_wet_floor(int argc, VALUE *argv, VALUE self)

for (x = 0; x < (long) image->columns; x++)
{
q[x] = p[x];
// Never make a pixel *less* transparent than it already is.
#if defined(IMAGEMAGICK_7)
*q = *p;
SetPixelAlpha(reflection, min(GetPixelAlpha(image, q), QuantumRange - (Quantum)opacity), q);

p += GetPixelChannels(reflection);
q += GetPixelChannels(reflection);
#else
q[x] = p[x];
q[x].opacity = max(q[x].opacity, (Quantum)opacity);
#endif
}
Expand Down

0 comments on commit e5c3677

Please sign in to comment.