mono / libgdiplus

C-based implementation of the GDI+ API
http://www.mono-project.com/
MIT License
329 stars 171 forks source link

Fix stack buffer overflows in GdipCreateRegionRgnData #679

Closed hughbe closed 10 months ago

hughbe commented 3 years ago

Can get some odd bugs if size < header.size

E.g.

=================================================================
==53395==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffeef9cf984 at pc 0x0001003349dd bp 0x7ffeef9cd670 sp 0x7ffeef9cd668
READ of size 1 at 0x7ffeef9cf984 thread T0
    #0 0x1003349dc in gdip_crc32 general.c:815
    #1 0x100403f44 in GdipCreateRegionRgnData region.c:687
    #2 0x100238b3c in main testregion.c:9446
    #3 0x7fff20336630 in start+0x0 (libdyld.dylib:x86_64+0x15630)

Address 0x7ffeef9cf984 is located in stack of thread T0 at offset 8612 in frame
    #0 0x10023648f in main testregion.c:9436

  This frame has 189 object(s):
    [32, 40) 'path.i1773' (line 8683)
    [64, 72) 'region.i1774' (line 8684)
    [96, 112) 'infiniteRect.i1775' (line 8685)
    [128, 144) 'emptyRect.i1776' (line 8686)
    [160, 176) 'rect.i1777' (line 8687)
    [192, 200) 'path.i1550' (line 8472)
    [224, 232) 'region.i1551' (line 8473)
    [256, 272) 'infiniteRect.i1552' (line 8474)
    [288, 304) 'emptyRect.i1553' (line 8475)
    [320, 336) 'rect.i1554' (line 8476)
    [352, 360) 'infiniteRegion.i' (line 4320)
    [384, 392) 'emptyRegion.i' (line 4321)
    [416, 424) 'rectRegion.i' (line 4322)
    [448, 456) 'pathRegion.i' (line 4323)
    [480, 496) 'rect1.i1493' (line 4330)
    [512, 528) 'rect2.i1494' (line 4331)
    [544, 552) 'region.i1495' (line 4339)
    [576, 584) 'region9.i' (line 4342)
    [608, 616) 'region12.i' (line 4345)
    [640, 648) 'region15.i' (line 4348)
    [672, 680) 'region18.i' (line 4351)
    [704, 712) 'region22.i' (line 4354)
    [736, 744) 'region26.i' (line 4357)
    [768, 776) 'region30.i' (line 4360)
    [800, 808) 'region34.i' (line 4363)
    [832, 840) 'region37.i' (line 4366)
    [864, 872) 'region40.i' (line 4369)
    [896, 904) 'region43.i' (line 4372)
    [928, 936) 'region46.i' (line 4375)
    [960, 968) 'region49.i' (line 4378)
    [992, 1000) 'region52.i' (line 4381)
    [1024, 1032) 'region55.i' (line 4384)
    [1056, 1064) 'path.i1386' (line 3882)
    [1088, 1096) 'region.i1387' (line 3883)
    [1120, 1128) 'matrix.i1388' (line 3884)
    [1152, 1184) 'scans.i1389' (line 3885)
    [1216, 1220) 'count.i1390' (line 3886)
    [1232, 1248) 'rect.i1391' (line 3891)
    [1264, 1280) 'lessThanPointFiveRect.i1392' (line 3911)
    [1296, 1312) 'pointFiveRect.i1393' (line 3924)
    [1328, 1344) 'greaterThanPointFiveRect.i1394' (line 3937)
    [1360, 1376) 'zeroWidthRect.i1395' (line 3950)
    [1392, 1408) 'zeroHeightRect.i1396' (line 3959)
    [1424, 1440) 'zeroWidthAndHeightRect.i1397' (line 3968)
    [1456, 1472) 'negativeWidthRect.i1398' (line 3977)
    [1488, 1504) 'negativeHeightRect.i1399' (line 3986)
    [1520, 1536) 'negativeWidthAndHeightRect.i1400' (line 3995)
    [1552, 1560) 'path.i1341' (line 3560)
    [1584, 1592) 'region.i1342' (line 3561)
    [1616, 1624) 'matrix.i1343' (line 3562)
    [1648, 1656) 'translateMatrix.i' (line 3563)
    [1680, 1688) 'scaleMatrix.i' (line 3564)
    [1712, 1720) 'translateScaleMatrix.i' (line 3565)
    [1744, 1752) 'complexMatrix.i' (line 3566)
    [1776, 4976) 'scans.i' (line 3567)
    [5104, 5108) 'count.i1344' (line 3568)
    [5120, 5136) 'rect.i1345' (line 3581)
    [5152, 5168) 'lessThanPointFiveRect.i' (line 3641)
    [5184, 5200) 'pointFiveRect.i' (line 3651)
    [5216, 5232) 'greaterThanPointFiveRect.i' (line 3664)
    [5248, 5264) 'zeroWidthRect.i1346' (line 3677)
    [5280, 5296) 'zeroHeightRect.i1347' (line 3686)
    [5312, 5328) 'zeroWidthAndHeightRect.i1348' (line 3695)
    [5344, 5360) 'negativeWidthRect.i1349' (line 3704)
    [5376, 5392) 'negativeHeightRect.i1350' (line 3713)
    [5408, 5424) 'negativeWidthAndHeightRect.i' (line 3722)
    [5440, 5448) 'path.i1288' (line 3500)
    [5472, 5480) 'region.i1289' (line 3501)
    [5504, 5512) 'matrix.i' (line 3502)
    [5536, 5540) 'count.i' (line 3503)
    [5552, 5568) 'rect.i1290' (line 3508)
    [5584, 5592) 'path.i1093' (line 3272)
    [5616, 5624) 'region.i1094' (line 3273)
    [5648, 5652) 'isVisible.i1095' (line 3274)
    [5664, 5680) 'rect.i1096' (line 3277)
    [5696, 5704) 'path.i898' (line 3044)
    [5728, 5736) 'region.i899' (line 3045)
    [5760, 5764) 'isVisible.i900' (line 3046)
    [5776, 5792) 'rect.i901' (line 3049)
    [5808, 5816) 'path.i729' (line 2896)
    [5840, 5848) 'region.i730' (line 2897)
    [5872, 5876) 'isVisible.i731' (line 2898)
    [5888, 5904) 'rect.i732' (line 2901)
    [5920, 5928) 'path.i549' (line 2740)
    [5952, 5960) 'region.i550' (line 2741)
    [5984, 5988) 'isVisible.i' (line 2742)
    [6000, 6016) 'rect.i551' (line 2745)
    [6032, 6040) 'region.i529' (line 2719)
    [6064, 6068) 'isInfinite.i' (line 2720)
    [6080, 6088) 'region.i509' (line 1640)
    [6112, 6116) 'isEmpty.i' (line 1641)
    [6128, 6136) 'region.i497' (line 1619)
    [6160, 6176) 'rect.i498' (line 1620)
    [6192, 6200) 'path.i453' (line 1571)
    [6224, 6232) 'region.i454' (line 1572)
    [6256, 6272) 'rect.i455' (line 1575)
    [6288, 6296) 'path.i428' (line 1523)
    [6320, 6328) 'region.i429' (line 1524)
    [6352, 6368) 'rect.i430' (line 1527)
    [6384, 6392) 'path.i397' (line 1482)
    [6416, 6424) 'region.i398' (line 1483)
    [6448, 6464) 'rect.i399' (line 1486)
    [6480, 6488) 'path.i367' (line 1426)
    [6512, 6520) 'region.i368' (line 1427)
    [6544, 6552) 'clone.i' (line 1428)
    [6576, 6592) 'rect.i369' (line 1431)
    [6608, 6616) 'region.i357' (line 1408)
    [6640, 6644) 'bufferSize.i' (line 1409)
    [6656, 6664) 'region.i288' (line 1281)
    [6688, 6696) 'other.i289' (line 1282)
    [6720, 6728) 'path.i290' (line 1283)
    [6752, 6768) 'rect1.i291' (line 1284)
    [6784, 6792) 'region.i221' (line 1156)
    [6816, 6824) 'other.i222' (line 1157)
    [6848, 6856) 'path.i223' (line 1158)
    [6880, 6896) 'rect1.i224' (line 1159)
    [6912, 6920) 'region.i167' (line 999)
    [6944, 6952) 'other.i' (line 1000)
    [6976, 6984) 'path.i168' (line 1001)
    [7008, 7024) 'rect1.i' (line 1002)
    [7040, 7056) 'rect2.i' (line 1003)
    [7072, 7080) 'region.i118' (line 746)
    [7104, 7112) 'path.i119' (line 747)
    [7136, 8160) 'buffer.i' (line 749)
    [8288, 8292) 'sizeFilled.i' (line 750)
    [8304, 8320) 'infiniteRect.i122' (line 784)
    [8336, 8352) 'emptyRect.i' (line 804)
    [8368, 8384) 'rect.i' (line 824)
    [8400, 8416) 'zeroWidthRect.i' (line 844)
    [8432, 8448) 'zeroHeightRect.i' (line 864)
    [8464, 8480) 'zeroWidthAndHeightRect.i' (line 884)
    [8496, 8512) 'negativeWidthRect.i126' (line 904)
    [8528, 8544) 'negativeHeightRect.i128' (line 924)
    [8560, 8568) 'region.i78' (line 404)
    [8592, 8612) 'infiniteRegionData.i' (line 407) <== Memory access at offset 8612 overflows this variable
    [8656, 8676) 'emptyRegionData.i' (line 441)
    [8720, 8756) 'rectMagicNumber2.i' (line 458)
    [8800, 8816) 'expectedRect.i' (line 471)
    [8832, 8868) 'rectMagicNumber1.i' (line 476)
    [8912, 8932) 'rectEmpty.i' (line 494)
    [8976, 8996) 'rectInfinite.i' (line 508)
    [9040, 9076) 'zeroWidthRectRegionData.i' (line 522)
    [9120, 9156) 'zeroHeightRectRegionData.i' (line 543)
    [9200, 9236) 'zeroWidthAndHeightRectRegionData.i' (line 564)
    [9280, 9316) 'negativeWidthRectRegionData.i' (line 585)
    [9360, 9396) 'negativeHeightRectRegionData.i' (line 606)
    [9440, 9476) 'invalidChecksum.i' (line 687)
    [9520, 9556) 'zeroSize.i' (line 701)
    [9600, 9636) 'smallSize.i' (line 715)
    [9680, 9688) 'path.i' (line 310)
    [9712, 9720) 'region.i41' (line 311)
    [9744, 9784) 'polygonPoints.i' (line 344)
    [9824, 9840) 'emptyCurvePoints.i' (line 366)
    [9856, 9872) 'infiniteCurvePoints.i' (line 380)
    [9888, 9904) 'normalRect.i22' (line 260)
    [9920, 9936) 'negativeWidthRect.i' (line 261)
    [9952, 9968) 'negativeHeightRect.i' (line 262)
    [9984, 10000) 'zeroRect.i' (line 263)
    [10016, 10032) 'infiniteRect.i' (line 264)
    [10048, 10056) 'region.i23' (line 265)
    [10080, 10096) 'normalRect.i' (line 47)
    [10112, 10120) 'region.i13' (line 48)
    [10144, 10160) 'greaterThanInfiniteGreaterThanInfiniteHeightRect.i' (line 58)
    [10176, 10192) 'greaterThanInfiniteInfiniteHeightRect.i' (line 66)
    [10208, 10224) 'greaterThanInfinitePositiveHeightRect.i' (line 74)
    [10240, 10256) 'greaterThanInfiniteZeroHeightRect.i' (line 82)
    [10272, 10288) 'greaterThanInfiniteNegativeHeightRect.i' (line 90)
    [10304, 10320) 'infiniteWidthGreaterThanInfiniteHeightRect.i' (line 98)
    [10336, 10352) 'infiniteWidthInfiniteHeightRect.i' (line 106)
    [10368, 10384) 'infiniteWidthPositiveHeightRect.i' (line 114)
    [10400, 10416) 'infiniteWidthZeroHeightRect.i' (line 122)
    [10432, 10448) 'infiniteWidthNegativeHeightRect.i' (line 130)
    [10464, 10480) 'positiveWidthGreaterThanInfiniteHeightRect.i' (line 138)
    [10496, 10512) 'positiveWidthInfiniteHeightRect.i' (line 146)
    [10528, 10544) 'positiveWidthZeroHeightRect.i' (line 154)
    [10560, 10576) 'positiveWidthNegativeHeightRect.i' (line 162)
    [10592, 10608) 'zeroWidthGreaterThanInfiniteHeightRect.i' (line 170)
    [10624, 10640) 'zeroWidthInfiniteHeightRect.i' (line 178)
    [10656, 10672) 'zeroWidthPositiveHeightRect.i' (line 186)
    [10688, 10704) 'zeroWidthZeroHeightRect.i' (line 194)
    [10720, 10736) 'zeroWidthNegativeHeightRect.i' (line 202)
    [10752, 10768) 'negativeWidthGreaterThanInfiniteHeightRect.i' (line 210)
    [10784, 10800) 'negativeWidthInfiniteHeightRect.i' (line 218)
    [10816, 10832) 'negativeWidthPositiveHeightRect.i' (line 226)
    [10848, 10864) 'negativeWidthZeroHeightRect.i' (line 234)
    [10880, 10896) 'negativeWidthNegativeHeightRect.i' (line 242)
    [10912, 10920) 'region.i' (line 32)
    [10944, 10948) 'gdiplusToken' (line 9437)
    [10960, 10984) 'gdiplusStartupInput' (line 9437)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow general.c:815 in gdip_crc32
Shadow bytes around the buggy address:
  0x1fffddf39ee0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x1fffddf39ef0: f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2
  0x1fffddf39f00: f2 f2 f2 f2 f2 f2 f2 f2 f8 f2 f8 f8 f2 f2 f8 f8
  0x1fffddf39f10: f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f8
  0x1fffddf39f20: f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 00 f2 f2 f2 00 00
=>0x1fffddf39f30:[04]f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8
  0x1fffddf39f40: f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f2 f2 f8 f8 f8 f8
  0x1fffddf39f50: f8 f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8
  0x1fffddf39f60: f8 f2 f2 f2 f2 f2 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2
  0x1fffddf39f70: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8 f8 f2
  0x1fffddf39f80: f2 f2 f2 f2 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8
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
==53395==ABORTING
FAIL testregion (exit status: 134)
hughbe commented 10 months ago

Closing, as libgdiplus is deprecated