fonts can be munged across processes, missing global locks, and errors in XCloseDisplay with unrefd fonts
Submitted by guy goode
Assigned to Xorg Project Team
Link to original bug (#107380)
Description
Created attachment 140815 font unit test, ppms: ref.ppm, bug.ppm
I have been working around various errors in Xft freetype and fontconfig for some time, with some success... but now I need help. The big issue is that even if I add workarounds in my code, other code can apparently munge font data that is then shared by the server. This creates visible errors in rendered glyphs. see attachment test.tgz and inspect ppms/ref.ppm, ppms/bug.ppm
First, the easy stuff.
- The global data in libXft should be locked. It definitely can crash the program. The most frequent errors are segvs and infinite loops because the _XftDisplayInfo list is global, and is modified without locks in _XftDisplayInfoGet for a MRU update when info is accessed. There is more global data than this which should be locked.
nm -a src/.libs/libXft.a | grep " [bBdDcC] ":
0000000000000000 b debug.11726
0000000000000004 b initialized.11725
0000000000000008 C _XftDisplayInfo
0000000000000000 b _XftFtFiles
0000000000000008 C _XftFTlibrary
0000000000000014 b XftAllocCount
0000000000000010 b XftAllocMem
0000000000000004 b XftAllocNotify
0000000000000018 b _XftConfigInitialized
000000000000000c b XftFreeCount
0000000000000008 b XftFreeMem
0000000000000000 b XftFreeNotify
0000000000000000 d XftInUse
0000000000000000 b _XftNameInitialized
0000000000000000 d XftXlfdSlants
0000000000000040 d XftXlfdWeights
Most of this needs a lock.
- Closing a display with unrefd fonts always creates an XError failure. This is because there are events generated by _XftCloseDisplay which attempt to use the transport during XSync(display,1). This can be avoided by closing the fonts with maxunreffonts=0, so that the cleanup is done while the transport is usable. example:
FcPattern *defaults = FcPatternCreate();
FcPatternAddInteger(defaults, "maxunreffonts", 0);
XftDefaultSet(display, defaults);
xftFontClose (display, xft_font);
...
XCloseDisplay(display);
Now, the one that is too hard for me to find or workaround.
- The glyph data can be corrupted by another process. I have written a unit test program (attached) which uses techniques similar to the application code which I use. If I run it by itself, it seems to work. If I run multiple processes of it (2 or 3 usually), it works. If I run even one copy, and bring up ooffice on a big document, and scroll it around (to force a bunch of glyph operations), within a minute or so the bug trap is triggered.
I rate these bugs as serious.
All of them can be produced with the attached unit test.
[root@xray tmp]# ./a.out 1 # unlocked globals
Segmentation fault (core dumped)
[root@xray tmp]# ./a.out 2 # unrefd fonts
X Error of failed request: BadRequest (invalid request code or no such operation)
Major opcode of failed request: 160 ()
Minor opcode of failed request: 0
Serial number of failed request: 83
Current serial number in output stream: 125
[root@xray tmp]# ./a.out # munged glyph
BUG 0x7f81271ce700
This should probably be broken into 3 bugs, but this is a good starting point.
If this is not the place to submit this bug report, please let me know.
Attachment 140815, "font unit test, ppms: ref.ppm, bug.ppm":
test.tgz