CVE-2019-7637.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # HG changeset patch
  2. # User Petr Písař <ppisar@redhat.com>
  3. # Date 1552788984 25200
  4. # Sat Mar 16 19:16:24 2019 -0700
  5. # Branch SDL-1.2
  6. # Node ID 9b0e5c555c0f5ce6d2c3c19da6cc2c7fb5048bf2
  7. # Parent 4646533663ae1d80c2cc6b2d6dbfb37c62491c1e
  8. CVE-2019-7637: Fix in integer overflow in SDL_CalculatePitch
  9. If a too large width is passed to SDL_SetVideoMode() the width travels
  10. to SDL_CalculatePitch() where the width (e.g. 65535) is multiplied by
  11. BytesPerPixel (e.g. 4) and the result is stored into Uint16 pitch
  12. variable. During this arithmetics an integer overflow can happen (e.g.
  13. the value is clamped as 65532). As a result SDL_Surface with a pitch
  14. smaller than width * BytesPerPixel is created, too small pixel buffer
  15. is allocated and when the SDL_Surface is processed in SDL_FillRect()
  16. a buffer overflow occurs.
  17. This can be reproduced with "./graywin -width 21312312313123213213213"
  18. command.
  19. This patch fixes is by using a very careful arithmetics in
  20. SDL_CalculatePitch(). If an overflow is detected, an error is reported
  21. back as a special 0 value. We assume that 0-width surfaces do not
  22. occur in the wild. Since SDL_CalculatePitch() is a private function,
  23. we can change the semantics.
  24. CVE-2019-7637
  25. https://bugzilla.libsdl.org/show_bug.cgi?id=4497
  26. Signed-off-by: Petr Písař <ppisar@redhat.com>
  27. CVE: CVE-2019-7637
  28. Upstream-Status: Backport
  29. Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
  30. diff -r 4646533663ae -r 9b0e5c555c0f src/video/SDL_pixels.c
  31. --- a/src/video/SDL_pixels.c Sat Mar 16 18:35:33 2019 -0700
  32. +++ b/src/video/SDL_pixels.c Sat Mar 16 19:16:24 2019 -0700
  33. @@ -286,26 +286,53 @@
  34. }
  35. }
  36. /*
  37. - * Calculate the pad-aligned scanline width of a surface
  38. + * Calculate the pad-aligned scanline width of a surface. Return 0 in case of
  39. + * an error.
  40. */
  41. Uint16 SDL_CalculatePitch(SDL_Surface *surface)
  42. {
  43. - Uint16 pitch;
  44. + unsigned int pitch = 0;
  45. /* Surface should be 4-byte aligned for speed */
  46. - pitch = surface->w*surface->format->BytesPerPixel;
  47. + /* The code tries to prevent from an Uint16 overflow. */;
  48. + for (Uint8 byte = surface->format->BytesPerPixel; byte; byte--) {
  49. + pitch += (unsigned int)surface->w;
  50. + if (pitch < surface->w) {
  51. + SDL_SetError("A scanline is too wide");
  52. + return(0);
  53. + }
  54. + }
  55. switch (surface->format->BitsPerPixel) {
  56. case 1:
  57. - pitch = (pitch+7)/8;
  58. + if (pitch % 8) {
  59. + pitch = pitch / 8 + 1;
  60. + } else {
  61. + pitch = pitch / 8;
  62. + }
  63. break;
  64. case 4:
  65. - pitch = (pitch+1)/2;
  66. + if (pitch % 2) {
  67. + pitch = pitch / 2 + 1;
  68. + } else {
  69. + pitch = pitch / 2;
  70. + }
  71. break;
  72. default:
  73. break;
  74. }
  75. - pitch = (pitch + 3) & ~3; /* 4-byte aligning */
  76. - return(pitch);
  77. + /* 4-byte aligning */
  78. + if (pitch & 3) {
  79. + if (pitch + 3 < pitch) {
  80. + SDL_SetError("A scanline is too wide");
  81. + return(0);
  82. + }
  83. + pitch = (pitch + 3) & ~3;
  84. + }
  85. + if (pitch > 0xFFFF) {
  86. + SDL_SetError("A scanline is too wide");
  87. + return(0);
  88. + }
  89. + return((Uint16)pitch);
  90. }
  91. /*
  92. * Match an RGB value to a particular palette index
  93. diff -r 4646533663ae -r 9b0e5c555c0f src/video/gapi/SDL_gapivideo.c
  94. --- a/src/video/gapi/SDL_gapivideo.c Sat Mar 16 18:35:33 2019 -0700
  95. +++ b/src/video/gapi/SDL_gapivideo.c Sat Mar 16 19:16:24 2019 -0700
  96. @@ -733,6 +733,9 @@
  97. video->w = gapi->w = width;
  98. video->h = gapi->h = height;
  99. video->pitch = SDL_CalculatePitch(video);
  100. + if (!current->pitch) {
  101. + return(NULL);
  102. + }
  103. /* Small fix for WinCE/Win32 - when activating window
  104. SDL_VideoSurface is equal to zero, so activating code
  105. diff -r 4646533663ae -r 9b0e5c555c0f src/video/nanox/SDL_nxvideo.c
  106. --- a/src/video/nanox/SDL_nxvideo.c Sat Mar 16 18:35:33 2019 -0700
  107. +++ b/src/video/nanox/SDL_nxvideo.c Sat Mar 16 19:16:24 2019 -0700
  108. @@ -378,6 +378,10 @@
  109. current -> w = width ;
  110. current -> h = height ;
  111. current -> pitch = SDL_CalculatePitch (current) ;
  112. + if (!current->pitch) {
  113. + current = NULL;
  114. + goto done;
  115. + }
  116. NX_ResizeImage (this, current, flags) ;
  117. }
  118. diff -r 4646533663ae -r 9b0e5c555c0f src/video/ps2gs/SDL_gsvideo.c
  119. --- a/src/video/ps2gs/SDL_gsvideo.c Sat Mar 16 18:35:33 2019 -0700
  120. +++ b/src/video/ps2gs/SDL_gsvideo.c Sat Mar 16 19:16:24 2019 -0700
  121. @@ -479,6 +479,9 @@
  122. current->w = width;
  123. current->h = height;
  124. current->pitch = SDL_CalculatePitch(current);
  125. + if (!current->pitch) {
  126. + return(NULL);
  127. + }
  128. /* Memory map the DMA area for block memory transfer */
  129. if ( ! mapped_mem ) {
  130. diff -r 4646533663ae -r 9b0e5c555c0f src/video/ps3/SDL_ps3video.c
  131. --- a/src/video/ps3/SDL_ps3video.c Sat Mar 16 18:35:33 2019 -0700
  132. +++ b/src/video/ps3/SDL_ps3video.c Sat Mar 16 19:16:24 2019 -0700
  133. @@ -339,6 +339,9 @@
  134. current->w = width;
  135. current->h = height;
  136. current->pitch = SDL_CalculatePitch(current);
  137. + if (!current->pitch) {
  138. + return(NULL);
  139. + }
  140. /* Alloc aligned mem for current->pixels */
  141. s_pixels = memalign(16, current->h * current->pitch);
  142. diff -r 4646533663ae -r 9b0e5c555c0f src/video/windib/SDL_dibvideo.c
  143. --- a/src/video/windib/SDL_dibvideo.c Sat Mar 16 18:35:33 2019 -0700
  144. +++ b/src/video/windib/SDL_dibvideo.c Sat Mar 16 19:16:24 2019 -0700
  145. @@ -675,6 +675,9 @@
  146. video->w = width;
  147. video->h = height;
  148. video->pitch = SDL_CalculatePitch(video);
  149. + if (!current->pitch) {
  150. + return(NULL);
  151. + }
  152. /* Small fix for WinCE/Win32 - when activating window
  153. SDL_VideoSurface is equal to zero, so activating code
  154. diff -r 4646533663ae -r 9b0e5c555c0f src/video/windx5/SDL_dx5video.c
  155. --- a/src/video/windx5/SDL_dx5video.c Sat Mar 16 18:35:33 2019 -0700
  156. +++ b/src/video/windx5/SDL_dx5video.c Sat Mar 16 19:16:24 2019 -0700
  157. @@ -1127,6 +1127,9 @@
  158. video->w = width;
  159. video->h = height;
  160. video->pitch = SDL_CalculatePitch(video);
  161. + if (!current->pitch) {
  162. + return(NULL);
  163. + }
  164. #ifndef NO_CHANGEDISPLAYSETTINGS
  165. /* Set fullscreen mode if appropriate.
  166. diff -r 4646533663ae -r 9b0e5c555c0f src/video/x11/SDL_x11video.c
  167. --- a/src/video/x11/SDL_x11video.c Sat Mar 16 18:35:33 2019 -0700
  168. +++ b/src/video/x11/SDL_x11video.c Sat Mar 16 19:16:24 2019 -0700
  169. @@ -1225,6 +1225,10 @@
  170. current->w = width;
  171. current->h = height;
  172. current->pitch = SDL_CalculatePitch(current);
  173. + if (!current->pitch) {
  174. + current = NULL;
  175. + goto done;
  176. + }
  177. if (X11_ResizeImage(this, current, flags) < 0) {
  178. current = NULL;
  179. goto done;