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;
|
|