[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Git][xorg-team/xserver/xorg-server][upstream-unstable] 9 commits: dix: Fix use after free in input device shutdown



Title: GitLab

Julien Cristau pushed to branch upstream-unstable at X Strike Force / xserver / xorg-server

Commits:

  • 8b75ec34
    by Povilas Kanapickas at 2024-01-22T15:14:21+10:00
    dix: Fix use after free in input device shutdown
    
    This fixes access to freed heap memory via dev->master. E.g. when
    running BarrierNotify.ReceivesNotifyEvents/7 test from
    xorg-integration-tests:
    
    ==24736==ERROR: AddressSanitizer: heap-use-after-free on address
    0x619000065020 at pc 0x55c450e2b9cf bp 0x7fffc532fd20 sp 0x7fffc532fd10
    READ of size 4 at 0x619000065020 thread T0
        #0 0x55c450e2b9ce in GetMaster ../../../dix/devices.c:2722
        #1 0x55c450e9d035 in IsFloating ../../../dix/events.c:346
        #2 0x55c4513209c6 in GetDeviceUse ../../../Xi/xiquerydevice.c:525
    ../../../Xi/xichangehierarchy.c:95
        #4 0x55c450e3455c in RemoveDevice ../../../dix/devices.c:1204
    ../../../hw/xfree86/common/xf86Xinput.c:1142
        #6 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
        #7 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
        #8 0x55c450e837ef in dix_main ../../../dix/main.c:302
        #9 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
    (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
        #11 0x55c450d0113d in _start (/usr/lib/xorg/Xorg+0x117713d)
    
    0x619000065020 is located 160 bytes inside of 912-byte region
    [0x619000064f80,0x619000065310)
    freed by thread T0 here:
    (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
        #1 0x55c450e19f1c in CloseDevice ../../../dix/devices.c:1014
        #2 0x55c450e343a4 in RemoveDevice ../../../dix/devices.c:1186
    ../../../hw/xfree86/common/xf86Xinput.c:1142
        #4 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
        #5 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
        #6 0x55c450e837ef in dix_main ../../../dix/main.c:302
        #7 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
    (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
    
    previously allocated by thread T0 here:
    (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10ddc6)
        #1 0x55c450e1c57b in AddInputDevice ../../../dix/devices.c:259
        #2 0x55c450e34840 in AllocDevicePair ../../../dix/devices.c:2755
        #3 0x55c45130318f in add_master ../../../Xi/xichangehierarchy.c:152
    ../../../Xi/xichangehierarchy.c:465
        #5 0x55c4512cb9f5 in ProcIDispatch ../../../Xi/extinit.c:390
        #6 0x55c450e6a92b in Dispatch ../../../dix/dispatch.c:551
        #7 0x55c450e834b7 in dix_main ../../../dix/main.c:272
        #8 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
    (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
    
    The problem is caused by dev->master being not reset when disabling the
    device, which then causes dangling pointer when the master device itself
    is being deleted when exiting whole server.
    
    Note that RecalculateMasterButtons() requires dev->master to be still
    valid, so we can reset it only at the end of function.
    
    Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
    (cherry picked from commit 1801fe0ac3926882d47d7e1ad6c0518a2cdffd41)
    
  • f653d9a0
    by Yusuf Khan at 2024-02-19T10:12:03+00:00
    hw/xfree86: fix NULL pointer refrence to mode name
    
    Potentially, the pointer to the mode name could be unset, this can
    occur with the xf86-video-nv DDX, in that case there isnt much we can do
    except check if the next mode is any better.
    
    Signed-off-by: Yusuf Khan <yusisamerican@gmail.com>
    ---
    (cherry picked from db3aa4e03b180244e8b4b02272c49f1e0c48b463)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1309>
    
  • 8a46a463
    by Matthieu Herrb at 2024-02-23T00:01:10+00:00
    Initialize Mode->name in xf86CVTMode()
    
    This was overlooked when converting the function to use libxcvt.
    Bring back name initialization from old code.
    
    This was causing a segfault in xf86LookupMode() if modes where
    name is NULL are present the modePool list.
    
    Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
    ---
    (cherry picked from ed11c4d443ad2e82512df64358d38008e0ee7693)
    
    Reported-by: "Sergiy" <Black_N@ukr.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1319>
    
  • 5d7272f0
    by Peter Hutterer at 2024-03-23T14:42:15-07:00
    Allow disabling byte-swapped clients
    
    The X server swapping code is a huge attack surface, much of this code
    is untested and prone to security issues. The use-case of byte-swapped
    clients is very niche, so allow users to disable this if they don't
    need it, using either a config option or commandline flag.
    
    For Xorg, this adds the ServerFlag "AllowByteSwappedClients" "off".
    For all DDX, this adds the commandline options +byteswappedclients and
    -byteswappedclients to enable or disable, respectively.
    
    Fixes #1201
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    ---
    (cherry picked from commit 412777664a20dd3561b936c02c96571a756fe9b2)
    (cherry picked from commit af5cd5acc9012e527ee869f8e98bf6c2e9a02ca4)
    Backport to server-21.1-branch modified to keep byte-swapping enabled
    by default but easy to disable by users or admins (or even by distros
    shipping an xorg.conf.d fragment in their packages).
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1440>
    
  • 5ca3a951
    by Alan Coopersmith at 2024-03-27T19:39:19+00:00
    Xext: SProcSyncCreateFence needs to swap drawable id too
    
    Otherwise it causes the server to return BadDrawable giving a
    byte-swapped resource id instead of the real id the client sent.
    
    Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
    Fixes: 397dfd9f8 ("Create/Destroy/Trigger/Reset/Query Fence Sync objs")
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    ---
    (cherry picked from commit e6573baa7d99a77f44229b9a96a41bbda57e2387)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1438>
    
  • 8a7cd0e3
    by Alan Coopersmith at 2024-04-03T19:35:30+03:00
    Xi: ProcXIGetSelectedEvents needs to use unswapped length to send reply
    
    CVE-2024-31080
    
    Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
    Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.")
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
    (cherry picked from commit 96798fc1967491c80a4d0c8d9e0a80586cb2152b)
    
  • cea92ca7
    by Alan Coopersmith at 2024-04-03T19:35:39+03:00
    Xi: ProcXIPassiveGrabDevice needs to use unswapped length to send reply
    
    CVE-2024-31081
    
    Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.")
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
    (cherry picked from commit 3e77295f888c67fc7645db5d0c00926a29ffecee)
    
  • 0e34d8eb
    by Alan Coopersmith at 2024-04-03T19:35:46+03:00
    Xquartz: ProcAppleDRICreatePixmap needs to use unswapped length to send reply
    
    CVE-2024-31082
    
    Fixes: 14205ade0 ("XQuartz: appledri: Fix byte swapping in replies")
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
    (cherry picked from commit 6c684d035c06fd41c727f0ef0744517580864cef)
    
  • 11731564
    by Peter Hutterer at 2024-04-03T19:37:08+03:00
    render: fix refcounting of glyphs during ProcRenderAddGlyphs
    
    Previously, AllocateGlyph would return a new glyph with refcount=0 and a
    re-used glyph would end up not changing the refcount at all. The
    resulting glyph_new array would thus have multiple entries pointing to
    the same non-refcounted glyphs.
    
    AddGlyph may free a glyph, resulting in a UAF when the same glyph
    pointer is then later used.
    
    Fix this by returning a refcount of 1 for a new glyph and always
    incrementing the refcount for a re-used glyph, followed by dropping that
    refcount back down again when we're done with it.
    
    CVE-2024-31083, ZDI-CAN-22880
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
    (cherry picked from commit bdca6c3d1f5057eeb31609b1280fc93237b00c77)
    

16 changed files:

Changes:

  • Xext/sync.c
    ... ... @@ -2318,6 +2318,7 @@ SProcSyncCreateFence(ClientPtr client)
    2318 2318
         REQUEST(xSyncCreateFenceReq);
    
    2319 2319
         swaps(&stuff->length);
    
    2320 2320
         REQUEST_SIZE_MATCH(xSyncCreateFenceReq);
    
    2321
    +    swapl(&stuff->d);
    
    2321 2322
         swapl(&stuff->fid);
    
    2322 2323
     
    
    2323 2324
         return ProcSyncCreateFence(client);
    

  • Xi/xipassivegrab.c
    ... ... @@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
    93 93
         GrabParameters param;
    
    94 94
         void *tmp;
    
    95 95
         int mask_len;
    
    96
    +    uint32_t length;
    
    96 97
     
    
    97 98
         REQUEST(xXIPassiveGrabDeviceReq);
    
    98 99
         REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
    
    ... ... @@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
    247 248
             }
    
    248 249
         }
    
    249 250
     
    
    251
    +    /* save the value before SRepXIPassiveGrabDevice swaps it */
    
    252
    +    length = rep.length;
    
    250 253
         WriteReplyToClient(client, sizeof(rep), &rep);
    
    251 254
         if (rep.num_modifiers)
    
    252
    -        WriteToClient(client, rep.length * 4, modifiers_failed);
    
    255
    +        WriteToClient(client, length * 4, modifiers_failed);
    
    253 256
     
    
    254 257
      out:
    
    255 258
         free(modifiers_failed);
    

  • Xi/xiselectev.c
    ... ... @@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
    349 349
         InputClientsPtr others = NULL;
    
    350 350
         xXIEventMask *evmask = NULL;
    
    351 351
         DeviceIntPtr dev;
    
    352
    +    uint32_t length;
    
    352 353
     
    
    353 354
         REQUEST(xXIGetSelectedEventsReq);
    
    354 355
         REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
    
    ... ... @@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client)
    418 419
             }
    
    419 420
         }
    
    420 421
     
    
    422
    +    /* save the value before SRepXIGetSelectedEvents swaps it */
    
    423
    +    length = reply.length;
    
    421 424
         WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
    
    422 425
     
    
    423 426
         if (reply.num_masks)
    
    424
    -        WriteToClient(client, reply.length * 4, buffer);
    
    427
    +        WriteToClient(client, length * 4, buffer);
    
    425 428
     
    
    426 429
         free(buffer);
    
    427 430
         return Success;
    

  • dix/devices.c
    ... ... @@ -536,6 +536,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
    536 536
         }
    
    537 537
     
    
    538 538
         RecalculateMasterButtons(dev);
    
    539
    +    dev->master = NULL;
    
    539 540
     
    
    540 541
         return TRUE;
    
    541 542
     }
    

  • dix/dispatch.c
    ... ... @@ -3780,9 +3780,11 @@ ProcEstablishConnection(ClientPtr client)
    3780 3780
         auth_proto = (char *) prefix + sz_xConnClientPrefix;
    
    3781 3781
         auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
    
    3782 3782
     
    
    3783
    -    if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
    
    3784
    -	pad_to_int32(prefix->nbytesAuthProto) +
    
    3785
    -	pad_to_int32(prefix->nbytesAuthString))
    
    3783
    +    if (client->swapped && !AllowByteSwappedClients) {
    
    3784
    +        reason = "Prohibited client endianess, see the Xserver man page ";
    
    3785
    +    } else if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
    
    3786
    +               pad_to_int32(prefix->nbytesAuthProto) +
    
    3787
    +               pad_to_int32(prefix->nbytesAuthString))
    
    3786 3788
             reason = "Bad length";
    
    3787 3789
         else if ((prefix->majorVersion != X_PROTOCOL) ||
    
    3788 3790
             (prefix->minorVersion != X_PROTOCOL_REVISION))
    

  • hw/xfree86/common/xf86Config.c
    ... ... @@ -646,6 +646,7 @@ typedef enum {
    646 646
         FLAG_MAX_CLIENTS,
    
    647 647
         FLAG_IGLX,
    
    648 648
         FLAG_DEBUG,
    
    649
    +    FLAG_ALLOW_BYTE_SWAPPED_CLIENTS,
    
    649 650
     } FlagValues;
    
    650 651
     
    
    651 652
     /**
    
    ... ... @@ -705,6 +706,8 @@ static OptionInfoRec FlagOptions[] = {
    705 706
          {0}, FALSE},
    
    706 707
         {FLAG_DEBUG, "Debug", OPTV_STRING,
    
    707 708
          {0}, FALSE},
    
    709
    +    {FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, "AllowByteSwappedClients", OPTV_BOOLEAN,
    
    710
    +     {0}, FALSE},
    
    708 711
         {-1, NULL, OPTV_NONE,
    
    709 712
          {0}, FALSE},
    
    710 713
     };
    
    ... ... @@ -746,6 +749,14 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
    746 749
             xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
    
    747 750
         }
    
    748 751
     
    
    752
    +    xf86GetOptValBool(FlagOptions, FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, &AllowByteSwappedClients);
    
    753
    +    if (AllowByteSwappedClients) {
    
    754
    +        xf86Msg(X_CONFIG, "Allowing byte-swapped clients\n");
    
    755
    +    }
    
    756
    +    else {
    
    757
    +        xf86Msg(X_CONFIG, "Prohibiting byte-swapped clients\n");
    
    758
    +    }
    
    759
    +
    
    749 760
         if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
    
    750 761
             xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
    
    751 762
                               &xf86Info.autoAddDevices);
    

  • hw/xfree86/common/xf86Mode.c
    ... ... @@ -507,6 +507,8 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
    507 507
                 /* scan through the modes in the sort order above */
    
    508 508
                 if ((p->type & type) != type)
    
    509 509
                     continue;
    
    510
    +            if (p->name == NULL)
    
    511
    +                continue;
    
    510 512
     
    
    511 513
                 if (strcmp(p->name, modep->name) == 0) {
    
    512 514
     
    

  • hw/xfree86/man/xorg.conf.man
    ... ... @@ -677,6 +677,9 @@ Possible values are
    677 677
     or
    
    678 678
     .BR sync .
    
    679 679
     Unset by default.
    
    680
    +.TP 7
    
    681
    +.BI "Option \*qAllowByteSwappedClients\*q  \*q" boolean \*q
    
    682
    +Allow clients with a different byte-order than the server. Enabled by default.
    
    680 683
     .SH "MODULE SECTION"
    
    681 684
     The
    
    682 685
     .B Module
    

  • hw/xfree86/modes/xf86Modes.c
    ... ... @@ -803,10 +803,14 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
    803 803
     {
    
    804 804
         struct libxcvt_mode_info *libxcvt_mode_info;
    
    805 805
         DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
    
    806
    +    char *tmp;
    
    806 807
     
    
    807 808
         libxcvt_mode_info =
    
    808 809
             libxcvt_gen_mode_info(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
    
    809 810
     
    
    811
    +    XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
    
    812
    +    Mode->name = tmp;
    
    813
    +    
    
    810 814
         Mode->VDisplay   = libxcvt_mode_info->vdisplay;
    
    811 815
         Mode->HDisplay   = libxcvt_mode_info->hdisplay;
    
    812 816
         Mode->Clock      = libxcvt_mode_info->dot_clock;
    

  • hw/xquartz/xpr/appledri.c
    ... ... @@ -272,6 +272,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
    272 272
         xAppleDRICreatePixmapReply rep;
    
    273 273
         int width, height, pitch, bpp;
    
    274 274
         void *ptr;
    
    275
    +    CARD32 stringLength;
    
    275 276
     
    
    276 277
         REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
    
    277 278
     
    
    ... ... @@ -307,6 +308,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
    307 308
         if (sizeof(rep) != sz_xAppleDRICreatePixmapReply)
    
    308 309
             ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
    
    309 310
     
    
    311
    +    stringLength = rep.stringLength;  /* save unswapped value */
    
    310 312
         if (client->swapped) {
    
    311 313
             swaps(&rep.sequenceNumber);
    
    312 314
             swapl(&rep.length);
    
    ... ... @@ -319,7 +321,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
    319 321
         }
    
    320 322
     
    
    321 323
         WriteToClient(client, sizeof(rep), &rep);
    
    322
    -    WriteToClient(client, rep.stringLength, path);
    
    324
    +    WriteToClient(client, stringLength, path);
    
    323 325
     
    
    324 326
         return Success;
    
    325 327
     }
    

  • include/opaque.h
    ... ... @@ -74,4 +74,6 @@ extern _X_EXPORT Bool bgNoneRoot;
    74 74
     extern _X_EXPORT Bool CoreDump;
    
    75 75
     extern _X_EXPORT Bool NoListenAll;
    
    76 76
     
    
    77
    +extern _X_EXPORT Bool AllowByteSwappedClients;
    
    78
    +
    
    77 79
     #endif                          /* OPAQUE_H */

  • man/Xserver.man
    ... ... @@ -114,6 +114,13 @@ pattern. This is the default unless -retro or -wr is specified.
    114 114
     .B \-bs
    
    115 115
     disables backing store support on all screens.
    
    116 116
     .TP 8
    
    117
    +.B \+byteswappedclients
    
    118
    +Allow connections from clients with an endianess different to that of the server.
    
    119
    +This is the default unless \fB\-byteswappedclients\fP is specified.
    
    120
    +.TP 8
    
    121
    +.B \-byteswappedclients
    
    122
    +Prohibit connections from clients with an endianess different to that of the server.
    
    123
    +.TP 8
    
    117 124
     .B \-c
    
    118 125
     turns off key-click.
    
    119 126
     .TP 8
    

  • os/utils.c
    ... ... @@ -189,6 +189,8 @@ Bool CoreDump;
    189 189
     
    
    190 190
     Bool enableIndirectGLX = FALSE;
    
    191 191
     
    
    192
    +Bool AllowByteSwappedClients = TRUE;
    
    193
    +
    
    192 194
     #ifdef PANORAMIX
    
    193 195
     Bool PanoramiXExtensionDisabledHack = FALSE;
    
    194 196
     #endif
    
    ... ... @@ -523,6 +525,8 @@ UseMsg(void)
    523 525
         ErrorF("-br                    create root window with black background\n");
    
    524 526
         ErrorF("+bs                    enable any backing store support\n");
    
    525 527
         ErrorF("-bs                    disable any backing store support\n");
    
    528
    +    ErrorF("+byteswappedclients    Allow clients with endianess different to that of the server\n");
    
    529
    +    ErrorF("-byteswappedclients    Prohibit clients with endianess different to that of the server\n");
    
    526 530
         ErrorF("-c                     turns off key-click\n");
    
    527 531
         ErrorF("c #                    key-click volume (0-100)\n");
    
    528 532
         ErrorF("-cc int                default color visual class\n");
    
    ... ... @@ -719,6 +723,11 @@ ProcessCommandLine(int argc, char *argv[])
    719 723
                 else
    
    720 724
                     UseMsg();
    
    721 725
             }
    
    726
    +        else if (strcmp(argv[i], "-byteswappedclients") == 0) {
    
    727
    +            AllowByteSwappedClients = FALSE;
    
    728
    +        } else if (strcmp(argv[i], "+byteswappedclients") == 0) {
    
    729
    +            AllowByteSwappedClients = TRUE;
    
    730
    +        }
    
    722 731
             else if (strcmp(argv[i], "-br") == 0);  /* default */
    
    723 732
             else if (strcmp(argv[i], "+bs") == 0)
    
    724 733
                 enableBackingStore = TRUE;
    

  • render/glyph.c
    ... ... @@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph)
    245 245
         }
    
    246 246
     }
    
    247 247
     
    
    248
    -static void
    
    248
    +void
    
    249 249
     FreeGlyph(GlyphPtr glyph, int format)
    
    250 250
     {
    
    251 251
         CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
    
    252
    +    BUG_RETURN(glyph->refcnt == 0);
    
    252 253
         if (--glyph->refcnt == 0) {
    
    253 254
             GlyphRefPtr gr;
    
    254 255
             int i;
    
    ... ... @@ -354,7 +355,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth)
    354 355
         glyph = (GlyphPtr) malloc(size);
    
    355 356
         if (!glyph)
    
    356 357
             return 0;
    
    357
    -    glyph->refcnt = 0;
    
    358
    +    glyph->refcnt = 1;
    
    358 359
         glyph->size = size + sizeof(xGlyphInfo);
    
    359 360
         glyph->info = *gi;
    
    360 361
         dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);
    

  • render/glyphstr.h
    ... ... @@ -109,6 +109,8 @@ extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id);
    109 109
     
    
    110 110
     extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format);
    
    111 111
     
    
    112
    +extern void FreeGlyph(GlyphPtr glyph, int format);
    
    113
    +
    
    112 114
     extern Bool
    
    113 115
      ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change);
    
    114 116
     
    

  • render/render.c
    ... ... @@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client)
    1076 1076
     
    
    1077 1077
             if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
    
    1078 1078
                 glyph_new->found = TRUE;
    
    1079
    +            ++glyph_new->glyph->refcnt;
    
    1079 1080
             }
    
    1080 1081
             else {
    
    1081 1082
                 GlyphPtr glyph;
    
    ... ... @@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client)
    1168 1169
             err = BadAlloc;
    
    1169 1170
             goto bail;
    
    1170 1171
         }
    
    1171
    -    for (i = 0; i < nglyphs; i++)
    
    1172
    +    for (i = 0; i < nglyphs; i++) {
    
    1172 1173
             AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
    
    1174
    +        FreeGlyph(glyphs[i].glyph, glyphSet->fdepth);
    
    1175
    +    }
    
    1173 1176
     
    
    1174 1177
         if (glyphsBase != glyphsLocal)
    
    1175 1178
             free(glyphsBase);
    
    ... ... @@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client)
    1179 1182
             FreePicture((void *) pSrc, 0);
    
    1180 1183
         if (pSrcPix)
    
    1181 1184
             FreeScratchPixmapHeader(pSrcPix);
    
    1182
    -    for (i = 0; i < nglyphs; i++)
    
    1183
    -        if (glyphs[i].glyph && !glyphs[i].found)
    
    1184
    -            free(glyphs[i].glyph);
    
    1185
    +    for (i = 0; i < nglyphs; i++) {
    
    1186
    +        if (glyphs[i].glyph) {
    
    1187
    +            --glyphs[i].glyph->refcnt;
    
    1188
    +            if (!glyphs[i].found)
    
    1189
    +                free(glyphs[i].glyph);
    
    1190
    +        }
    
    1191
    +    }
    
    1185 1192
         if (glyphsBase != glyphsLocal)
    
    1186 1193
             free(glyphsBase);
    
    1187 1194
         return err;
    


  • Reply to: