Bug 127247 - [PATCH] Double-free in Xlibs
[PATCH] Double-free in Xlibs
Status: CLOSED NEXTRELEASE
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: XFree86 (Show other bugs)
3.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Søren Sandmann Pedersen
David Lawrence
:
: 65265 (view as bug list)
Depends On:
Blocks: 123574
  Show dependency treegraph
 
Reported: 2004-07-05 05:37 EDT by Bastien Nocera
Modified: 2014-06-18 05:07 EDT (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-09-21 01:15:24 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
XFree86-4.3.0-omgeneric-double-free.patch (477 bytes, patch)
2004-07-05 05:38 EDT, Bastien Nocera
no flags Details | Diff

  None (edit)
Description Bastien Nocera 2004-07-05 05:37:43 EDT
From UBS:
---8<---
 In the Xlib code for the function parse_fontdata (in
xc/libs/X11/omGeneric.c),
error handling code which deals with failure of the get_rotate_fontname
method does not correctly clean up its memory allocation. This causes
later
code in one of its callers (parse_vw) to attempt the memory cleanup again,
resulting in a double-call to free() with the same memory address.
This then
corrupts the malloc data structures causing a segmentation fault shortly
there after (or sometimes a hang in malloc_consolidate).

In parse_fontdata, the snippet of code in question is:

 case C_VROTATE:
      if(is_found == True) {
 char *rotate_name;

 if((rotate_name = get_rotate_fontname(font_data->xlfd_name))
    != NULL) {
     Xfree(font_data->xlfd_name);
     font_data->xlfd_name = rotate_name;

     return True;
 }
 Xfree(font_data->xlfd_name);
 return False;
      }
      break;

In particular the last two lines of the failure scenario:

 Xfree(font_data->xlfd_name);
 return False;


Now parse_vw method which calls parse_fontdata works thus:

ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
    name_list, count, C_VROTATE, NULL);
if(ret == -1) {
   return (-1);
} else if(ret == False) {
   CodeRange code_range;
   int num_cr;
   int sub_num = font_set->substitute_num;

   code_range = vrotate[0].code_range; /* ? */
   num_cr = vrotate[0].num_cr;         /* ? */
   for(i = 0 ; i < vrotate_num ; i++) {
if(vrotate[i].xlfd_name)
   Xfree(vrotate[i].xlfd_name);
   }


Notice in particular the call

if(vrotate[i].xlfd_name)
   Xfree(vrotate[i].xlfd_name);

The member vortate[i].xlfd_name was already just freed when
parse_fontdata failure.

The patch to fix this crash is very simple. In parse_fontdata
simply reset the pointer for xlfd_name to NULL having free'd
it:


 Xfree(font_data->xlfd_name);
                 font_data->xlfd_name = NULL;
 return False;


A short test program to demonstrate the crash is as follows:


#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <mcheck.h>


int main(int argc, char** arbv) {
 Display *dpy;
 XEvent evt;
 char *base_name = "-dt-interface
system-medium-r-normal-m*-*-*-*-*-*-*-*-*";
 char **missing_charset;
 int missing_charsetn;
 char *def_str;
 XFontSet font_set;

 mtrace();
 if (!(dpy = XOpenDisplay(NULL))) {
   fprintf(stderr, "Cannot open display");
   return 0;
 }

 font_set = XCreateFontSet(dpy,
   base_name,
   &missing_charset,
   &missing_charsetn,
   &def_str);
 if (font_set) {
   XFreeFontSet(dpy, font_set);
 }

 XCloseDisplay(dpy);
 muntrace();
}

Which can be compiled & run thus:

  gcc -o test -L/usr/X11R6/lib -lX11 test.c
  export MALLOC_TRACE=test.log
  ./test
  mtrace test.log | head -10


NB, the base_name member will have to be changed to
refer to a font, which is both installed on your X
server, and for which there is no rotated font data
available.

This particular example is reproducable by using
ReflectionX 10.0 on WinXP to connect to a RHEL 3
server using XDMCP protocol & then running the
test program. To the best of my knowledge it is not
reproducable on XFree86 since the particular troublesome
error cleanup code path is not executed.
---8<---
Comment 1 Bastien Nocera 2004-07-05 05:38:44 EDT
Created attachment 101634 [details]
XFree86-4.3.0-omgeneric-double-free.patch

Patch for the above. Probably needs to be applied to all the versions of
XFree86 and derivates like X.org.
Comment 2 Mike A. Harris 2004-07-05 18:11:53 EDT
*** Bug 65265 has been marked as a duplicate of this bug. ***
Comment 3 Mike A. Harris 2004-07-05 18:14:31 EDT
I just spotted bug #65265 which is a duplicate and previously
reported bug for this same problem.  We'll review the patch
for potential inclusion in all currently supported OS products
for future updates (RHEL 2.1, RHEL 3, FC1, FC2).

Thanks Bastien
Comment 5 Søren Sandmann Pedersen 2004-07-07 14:03:38 EDT
I have filed this as 

http://freedesktop.org/bugzilla/show_bug.cgi?id=837

Comment 6 Søren Sandmann Pedersen 2004-07-20 13:52:41 EDT
The bug is now fixed upstream, but I'll leave this bug open to track
whether we want to merge into future updates.
Comment 13 Mike A. Harris 2004-09-21 01:15:24 EDT
Fix confirmed to be present in CVS:

%changelog
* Fri Sep 17 2004 Kristian Høgsberg <krh@redhat.com> 4.3.0-70.EL
- Add patch for xlib double free (#127247).

Note You need to log in before you can comment on or make changes to this bug.