Package: libsdl-ttf2.0-0 Version: 2.0.9-1 Severity: normal Also tested on source libsdl-ttf2.0 2.0.9-1 built with debug information.
Fixed in SDL_ttf (pre 2.0.10) changeset 144 0f803b00e43b http://hg.libsdl.org/SDL_ttf/rev/0f803b00e43b When the underline style is set the TTF_RenderUNICODE_xxx functions can write past the end of the buffer of the returned SDL surface. The happens in the line write for loop at the end of each function. Attached are a program demonstrating the problem and a patch fixing it. The patch is based on the fix applied to SDL_ttf 2.0.10. To apply the patch, from the SDL-ttf root directory: patch <sdl-ttf2.0-2.0.9-underline_bug.patch -- System Information: Debian Release: squeeze/sid APT prefers testing-proposed-updates APT policy: (500, 'testing-proposed-updates'), (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core) Locale: LANG=en_CA.utf8, LC_CTYPE=en_CA.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libsdl-ttf2.0-0 depends on: ii libc6 2.11.2-2 Embedded GNU C Library: Shared lib ii libfreetype6 2.4.2-1 FreeType 2 font engine, shared lib ii libsdl1.2debian 1.2.14-6 Simple DirectMedia Layer ii zlib1g 1:1.2.3.4.dfsg-3 compression library - runtime libsdl-ttf2.0-0 recommends no packages. libsdl-ttf2.0-0 suggests no packages.
/* Demonstrates libsdl-ttf2.0 2.0.9-1 memory corruption in TTF_RenderUNICODE_Solid * * underline [<font file> [<text message>]] * * Prints the last line and one line past, as hex byte values, * of a rendered underlined text message. * * This actual trigger the following error for me: * *** glibc detected *** ./underline: free(): invalid next size (normal): 0x084b0670 *** * * To build: * gcc -g underline.c -lSDL_ttf -lSDL -o underline * * There are no copyright claims on this program. */ #include <stdio.h> #include <SDL/SDL_ttf.h> static int init(void); static void quit(void); static void print_line(SDL_Surface *surf, int line); int main(int argc, char *argv[]) { TTF_Font *font; const char *filename; const char *msg; FILE *test; int style; SDL_Surface *surf; SDL_Color foreg = {250, 240, 230, 0}; if (argc > 1) { filename = argv[1]; } else { filename = "freesansbold.ttf"; } if (argc > 2) { msg = argv[2]; } else { msg = "Fonty"; } /*check if it is a valid file, else SDL_ttf segfaults*/ test = fopen(filename, "rb"); if(!test) { printf("Unable to open font file '%.1024s'\n", filename); return 1; } fclose(test); if (init() == -1) { printf("%s\n", SDL_GetError()); return 1; } font = TTF_OpenFont(filename, 80); if (!font) { printf("%s\n", TTF_GetError()); quit(); return 1; } style = TTF_GetFontStyle(font); TTF_SetFontStyle(font, style | TTF_STYLE_UNDERLINE); surf = TTF_RenderText_Solid(font, msg, foreg); if (surf == NULL) { TTF_CloseFont(font); printf("%s\n", TTF_GetError()); quit(); return 1; } print_line(surf, surf->h - 1); print_line(surf, surf->h); SDL_FreeSurface(surf); TTF_CloseFont(font); quit(); return 0; } int init(void) { return TTF_Init(); } void quit(void) { TTF_Quit(); } void print_line(SDL_Surface *surf, int line) { unsigned char *lptr = (unsigned char *)surf->pixels + (surf->pitch * line); unsigned char *lendptr = lptr + surf->w; printf("["); while (lptr < lendptr) { printf(" %.2x ", (unsigned)*lptr); ++lptr; } printf("]\n"); }
--- /usr/local/src/sdl-ttf2.0-2.0.9/SDL_ttf.c 2007-07-14 23:18:29.000000000 -0700 +++ SDL_ttf.c 2010-08-29 12:01:40.000000000 -0700 @@ -1204,7 +1204,7 @@ row = (textbuf->h-1) - font->underline_height; } dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch; - for ( row=font->underline_height; row>0; --row ) { + for ( row=font->underline_height; row>0 && dst < dst_check; --row ) { /* 1 because 0 is the bg color */ memset( dst, 1, textbuf->w ); dst += textbuf->pitch; @@ -1465,7 +1465,7 @@ row = (textbuf->h-1) - font->underline_height; } dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch; - for ( row=font->underline_height; row>0; --row ) { + for ( row=font->underline_height; row>0 && dst < dst_check; --row ) { memset( dst, NUM_GRAYS - 1, textbuf->w ); dst += textbuf->pitch; } @@ -1721,7 +1721,7 @@ } dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4; pixel |= 0xFF000000; /* Amask */ - for ( row=font->underline_height; row>0; --row ) { + for ( row=font->underline_height; row>0 && dst < dst_check; --row ) { for ( col=0; col < textbuf->w; ++col ) { dst[col] = pixel; }