bugThe FreeType Project - Bugs: bug #52008, freetype ft_module_get_service()...

 
 

bug #52008: freetype ft_module_get_service() memory corruption

Submitted by:  Ziqiang Gu <ziqiang_gu>
Submitted on:  Wed 13 Sep 2017 09:44:42 AM UTC  
 
Severity: 3 - NormalItem Group: Crash
Status: InvalidPrivacy: Public
Assigned to: Werner LEMBERG <wl>Open/Closed: Closed
Planned Release: None

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Tue 19 Sep 2017 04:33:28 AM UTC, comment #15:

Once again, Ziqiang: Please give a link to an existing function in a library (written in C, not C++) of approximately the same functional level that works as you think it should work.

Everything else you say on this topic is futile since we don't have a common base to communicate due to my lack of understanding.

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Tue 19 Sep 2017 03:12:50 AM UTC, comment #14:

In my opinion, if a component provides service for others, it should guarantee that the service is stable.

Is it possible that the API receive other things than a pointer, but implement the same function? For example, a value which you can check.

Ziqiang Gu <ziqiang_gu>
Mon 18 Sep 2017 05:24:57 PM UTC, comment #13:

Ziqiang, I really don't understand you. As mentioned earlier, please give an example of what you think should be done.

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Mon 18 Sep 2017 01:50:43 PM UTC, comment #12:

fscanf requires valid pointers to work too... Your perception of software security is wrong.

Alexei Podtelezhnikov <podtelez>
Project Member
Mon 18 Sep 2017 12:33:28 PM UTC, comment #11:

GOD, u compare this interface with free()! Just close this issue if you don't want to pay attention to the crash, I just give you a feedback, it depends on you.

Ziqiang Gu <ziqiang_gu>
Mon 18 Sep 2017 07:22:45 AM UTC, comment #10:

User input? What are you talking about? A normal user never sees `FT_Load_Glyph' directly!

Compare this to the standard C `free' function – if you pass an invalid pointer, this function causes a crash. Where's the difference to `FT_Load_Glyph'? `free' is also an `exported API'.

I think we are miscommunicating. Please give me an example of another library that is approximately on the same level as FreeType, and which does what you expect.

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Mon 18 Sep 2017 06:58:53 AM UTC, comment #9:

I've never heard that a program MUST crash. As you know, from a security view, all the data that user input is not trustable.

I think if you want to use a pointer in an exported API, it should be based on a premise that you can judge the validity of the pointer, or you can make sure the caller will transfer a valid pointer, otherwise the use of pointer should be encapsulated inside the program, so that it is under your control.

Of course, I'm not familiar with FT's code, so I can't give you an advice on how to avoid the crash :)

Ziqiang Gu <ziqiang_gu>
Mon 18 Sep 2017 04:44:52 AM UTC, comment #8:

Well, if you provide fake pointers, FreeType must crash, right? How shall this be avoided? AFAIK, there is no possibility to check whether an arbitrary pointer points to correctly allocated memory. In other words, a segmentation fault is unavoidable.

It's not clear what your example demonstrates, or what you are really after. Please elaborate.

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Mon 18 Sep 2017 04:14:47 AM UTC, comment #7:

I can reproduce this issue on 2.8.1 you have just released without poppler.

POC code:

#include &lt;freetype2/ft2build.h&gt;
#include &lt;freetype2/freetype/freetype.h&gt;

int main()
{

FT_FaceRec face = {
.num_faces = 1,
.face_index = 0,
.face_flags = 2577,
.style_flags = 2,
.num_glyphs = 563,
.family_name = 0x5555559f29e0,
.style_name = 0x5555559a80ee,
.num_fixed_sizes = 0,
.available_sizes = 0x0,
.num_charmaps = 2,
.charmaps = 0x5555559f3a20,
.generic = {.data = 0x0, .finalizer = 0x0},
.bbox = {.xMin = -173, .yMin = -307, .xMax = 1097, .yMax = 979},
.units_per_EM = 1000,
.ascender = 979,
.descender = -307,
.height = 1286,
.max_advance_width = 1183,
.max_advance_height = 1286,
.underline_position = -155,
.underline_thickness = 69,
.glyph = 0x5555559cb6b0,
.size = 0x5555559c77f0,
.charmap = 0x5555559ef220,
.driver = 0x555555995940,
.memory = 0x5555559963d0,
.stream = 0x5555559a7f40,
.sizes_list = {.head = 0x5555559c7f30, .tail = 0x5555559c76e0},
.autohint = {.data = 0x0, .finalizer = 0x0},
.extensions = 0x0,
.internal = 0x5555559a7e00
};
FT_Load_Glyph (&amp;face, 78, 0xa);
}

Compile the poc file and run, you'll find the crash:

gzq@kali64:~/tmp$ gcc -o testft poc.c /home/gzq/tmp/install/lib/libfreetype.a -I/home/gzq/tmp/install/include/ -I/home/gzq/tmp/install/include/freetype2
gzq@kali64:~/tmp$ file testft
testft: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b53cada172c04793397a7cc03c00671c0716ec91, not stripped
gzq@kali64:~/tmp$ gdb -q ./testft
Reading symbols from ./testft...done.
(gdb) r
Starting program: /home/gzq/tmp/testft

Program received signal SIGSEGV, Segmentation fault.
FT_Load_Glyph (face=0x7fffffffe410, glyph_index=78, load_flags=10) at /home/gzq/program/freetype-2.8.1/src/base/ftobjs.c:645
645 ft_glyphslot_clear( slot );
(gdb) bt
#0 FT_Load_Glyph (face=0x7fffffffe410, glyph_index=78, load_flags=10) at /home/gzq/program/freetype-2.8.1/src/base/ftobjs.c:645
#1 0x0000555555554de0 in main ()
(gdb)

FT_Load_Glyph() is an API you provide to others, the input is not trustable.

Ziqiang Gu <ziqiang_gu>
Fri 15 Sep 2017 04:53:41 AM UTC, comment #6:

Ziqiang, I have no time to test your specific setup – what I want to know is whether you can reproduce the issue with the current versions of the git repositories! I'm not responsible for poppler, and I'm going to make a new FreeType release this weekend.

Have you already contacted the poppler developers?

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Fri 15 Sep 2017 01:11:56 AM UTC, comment #5:

Poppler just fixed an infinite loop bug yesterday. I believe you can reproduce this issue with poppler's stable release 0.59.0.

My enviroment is as follow:
gzq@ubuntu:~/install/poppler-dev/bin$ ldd pdftoppm
linux-vdso.so.1 =&gt; (0x00007ffdd8eb4000)
libjpeg.so.8 =&gt; /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f4c7c5a7000)
libpng16.so.16 =&gt; /usr/lib/x86_64-linux-gnu/libpng16.so.16 (0x00007f4c7c375000)
libz.so.1 =&gt; /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4c7c15b000)
libopenjpeg.so.5 =&gt; /usr/lib/x86_64-linux-gnu/libopenjpeg.so.5 (0x00007f4c7bf38000)
libfontconfig.so.1 =&gt; /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f4c7bcf5000)
libfreetype.so.6 =&gt; /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f4c7ba46000)
libpthread.so.0 =&gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4c7b828000)
libstdc++.so.6 =&gt; /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4c7b4a0000)
libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4c7b197000)
libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4c7af80000)
libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4c7abb9000)
/lib64/ld-linux-x86-64.so.2 (0x00005593bbeca000)
libexpat.so.1 =&gt; /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f4c7a98d000)
gzq@ubuntu:~/install/poppler-dev/bin$ cat /etc/*lease
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.10
DISTRIB_CODENAME=yakkety
DISTRIB_DESCRIPTION=&quot;Ubuntu 16.10&quot;
NAME=&quot;Ubuntu Kylin&quot;
VERSION=&quot;16.10 (Yakkety Yak)&quot;
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME=&quot;Ubuntu Kylin 16.10&quot;
VERSION_ID=&quot;16.10&quot;
HOME_URL=&quot;http://www.ubuntu.com/&quot;
SUPPORT_URL=&quot;http://help.ubuntu.com/&quot;
BUG_REPORT_URL=&quot;http://bugs.launchpad.net/ubuntu/&quot;
PRIVACY_POLICY_URL=&quot;http://www.ubuntu.com/legal/terms-and-policies/privacy-policy&quot;
VERSION_CODENAME=yakkety
UBUNTU_CODENAME=yakkety

Ziqiang Gu <ziqiang_gu>
Thu 14 Sep 2017 01:40:20 PM UTC, comment #4:

Fedora 25 comes with poppler-0.45.0, FreeType is git HEAD. I do not know how to extract fonts from this PDF file, but it appear that it contains one Type 1 and one Type 3 font. It would be cleaner to get the segfault using our tools. On the surface it looks like the Type 1 or unsupported Type 3 face is not properly loaded by poppler indeed.

Alexei Podtelezhnikov <podtelez>
Project Member
Thu 14 Sep 2017 09:33:36 AM UTC, comment #3:

Thanks for the report. However, what you have completely missed is to report the used versions of the programs!

Compiling the git repositories of poppler and FreeType (both with a simple call to `./configure && make', not using any configuration options), I get neither a crash nor a memory corruption – I'm checking with valgrind on a 64bit GNU/Linux box. Attached is the resulting image.

In other words, it seems that the issue has been fixed already; please confirm.

(file #41801)

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
Thu 14 Sep 2017 02:43:31 AM UTC, comment #2:

Yes, the result various, but it all seems to crash from FT_Load_Glyph (). I'm not sure whether it is a freetype's issue or one of poppler's.

Ziqiang Gu <ziqiang_gu>
Thu 14 Sep 2017 01:41:28 AM UTC, comment #1:

My backtrace is different:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff56ac751 in T1_Load_Glyph (t1glyph=0x5555557af460,
t1size=0x5555557d4fe0, glyph_index=78, load_flags=10)
at /home/apodtele/freetype2/src/type1/t1gload.c:331
331 error = decoder_funcs->init( &decoder,
(gdb) bt
#0 0x00007ffff56ac751 in T1_Load_Glyph (t1glyph=0x5555557af460,
t1size=0x5555557d4fe0, glyph_index=78, load_flags=10)
at /home/apodtele/freetype2/src/type1/t1gload.c:331
#1 0x00007ffff5691fae in FT_Load_Glyph (face=0x5555557eb890, glyph_index=78,
load_flags=<optimized out>)
at /home/apodtele/freetype2/src/base/ftobjs.c:766
#2 0x00007ffff7b0978c in SplashFTFont::getGlyphAdvance(int) ()
from /lib64/libpoppler.so.62
#3 0x00007ffff7a0204d in SplashOutputDev::doUpdateFont(GfxState*) ()
from /lib64/libpoppler.so.62
#4 0x00007ffff7a026ab in SplashOutputDev::drawChar(GfxState, double, double, double, double, double, double, unsigned int, int, unsigned int, int) ()
from /lib64/libpoppler.so.62

Alexei Podtelezhnikov <podtelez>
Project Member
Wed 13 Sep 2017 09:44:42 AM UTC, original submission:

A memory corruption vulnerability was found in freetype ft_module_get_service() which may lead to potential attack.

we can reproduce this vulnerability when we use pdftoppm to process malicious PDF files:

gzq@ubuntu:~/tmp/install/bin$ pdftoppm -q ./mal.pdf
Segmentation fault
gzq@ubuntu:~/tmp/install/bin$ gdb -q ./pdftoppm
Reading symbols from ./pdftoppm...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6068da6 in ft_service_list_lookup () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#0 0x00007ffff6068da6 in ft_service_list_lookup () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#1 0x00007ffff606a553 in ft_module_get_service () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#2 0x00007ffff60d2bec in ?? () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#3 0x00007ffff608627e in ?? () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#4 0x00007ffff606d450 in FT_Load_Glyph () from /usr/lib/x86_64-linux-gnu/libfreetype.so.6
#5 0x00007ffff7af31e0 in SplashFTFont::getGlyphAdvance (this=0x5555557d16b0, c=109) at SplashFTFont.cc:374
#6 0x00007ffff798455e in SplashOutputDev::doUpdateFont (this=0x5555557a0180, state=0x5555630ef400) at SplashOutputDev.cc:2295
#7 0x00007ffff7985057 in SplashOutputDev::drawChar (this=0x5555557a0180, state=0x5555630ef400, x=50, y=700, dx=17.327999999999999, dy=0, originX=0, originY=0, code=72, nBytes=1, u=0x5555557a6720, uLen=1) at SplashOutputDev.cc:2460
#8 0x00007ffff79f4b6c in Gfx::doShowText (this=0x5555557a62c0, s=0x5555630e6560) at Gfx.cc:4009
#9 0x00007ffff79f326f in Gfx::opShowText (this=0x5555557a62c0, args=0x7fffff800300, numArgs=1) at Gfx.cc:3756
#10 0x00007ffff79e21f0 in Gfx::execOp (this=0x5555557a62c0, cmd=0x7fffff8002e0, args=0x7fffff800300, numArgs=1) at Gfx.cc:880
#11 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=false) at Gfx.cc:744
#12 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffff800700, topLevel=false) at Gfx.cc:706
#13 0x00007ffff79f454b in Gfx::doShowText (this=0x5555557a62c0, s=0x5555630dc670) at Gfx.cc:3961
#14 0x00007ffff79f326f in Gfx::opShowText (this=0x5555557a62c0, args=0x7fffff8008a0, numArgs=1) at Gfx.cc:3756
#15 0x00007ffff79e21f0 in Gfx::execOp (this=0x5555557a62c0, cmd=0x7fffff800880, args=0x7fffff8008a0, numArgs=1) at Gfx.cc:880
#16 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=false) at Gfx.cc:744
#17 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffff800ca0, topLevel=false) at Gfx.cc:706
#18 0x00007ffff79f454b in Gfx::doShowText (this=0x5555557a62c0, s=0x5555630d2df0) at Gfx.cc:3961
#19 0x00007ffff79f326f in Gfx::opShowText (this=0x5555557a62c0, args=0x7fffff800e40, numArgs=1) at Gfx.cc:3756
#20 0x00007ffff79e21f0 in Gfx::execOp (this=0x5555557a62c0, cmd=0x7fffff800e20, args=0x7fffff800e40, numArgs=1) at Gfx.cc:880
#21 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=false) at Gfx.cc:744
#22 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffff801240, topLevel=false) at Gfx.cc:706
..........
..........
..........
#29096 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=false) at Gfx.cc:744
#29097 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffffffd7a0, topLevel=false) at Gfx.cc:706
#29098 0x00007ffff79f454b in Gfx::doShowText (this=0x5555557a62c0, s=0x5555557d1680) at Gfx.cc:3961
#29099 0x00007ffff79f326f in Gfx::opShowText (this=0x5555557a62c0, args=0x7fffffffd940, numArgs=1) at Gfx.cc:3756
#29100 0x00007ffff79e21f0 in Gfx::execOp (this=0x5555557a62c0, cmd=0x7fffffffd920, args=0x7fffffffd940, numArgs=1) at Gfx.cc:880
#29101 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=false) at Gfx.cc:744
#29102 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffffffdd40, topLevel=false) at Gfx.cc:706
#29103 0x00007ffff79f454b in Gfx::doShowText (this=0x5555557a62c0, s=0x5555557af710) at Gfx.cc:3961
#29104 0x00007ffff79f326f in Gfx::opShowText (this=0x5555557a62c0, args=0x7fffffffdee0, numArgs=1) at Gfx.cc:3756
#29105 0x00007ffff79e21f0 in Gfx::execOp (this=0x5555557a62c0, cmd=0x7fffffffdec0, args=0x7fffffffdee0, numArgs=1) at Gfx.cc:880
#29106 0x00007ffff79e1a88 in Gfx::go (this=0x5555557a62c0, topLevel=true) at Gfx.cc:744
#29107 0x00007ffff79e180c in Gfx::display (this=0x5555557a62c0, obj=0x7fffffffe230, topLevel=true) at Gfx.cc:706
#29108 0x00007ffff7a4a1a5 in Page::displaySlice (this=0x5555557a6080, out=0x5555557a0180, hDPI=150, vDPI=150, rotate=0, useMediaBox=true, crop=false, sliceX=0, sliceY=0, sliceW=1240, sliceH=1755, printing=false, abortCheckCbk=0x0, abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at Page.cc:560
#29109 0x00007ffff7a4e2c5 in PDFDoc::displayPageSlice (this=0x55555579ee70, out=0x5555557a0180, page=1, hDPI=150, vDPI=150, rotate=0, useMediaBox=true, crop=false, printing=false, sliceX=0, sliceY=0, sliceW=1240, sliceH=1755, abortCheckCbk=0x0, abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at PDFDoc.cc:522
#29110 0x0000555555556836 in savePageSlice (doc=0x55555579ee70, splashOut=0x5555557a0180, pg=1, x=0, y=0, w=1240, h=1755, pg_w=1239.5833333333335, pg_h=1754.1666666666667, ppmFile=0x0) at pdftoppm.cc:282
#29111 0x0000555555557764 in main (argc=2, argv=0x7fffffffe5b8) at pdftoppm.cc:600

A file has been attached to reproduce the issue.

Ziqiang Gu <ziqiang_gu>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

Attached Files
file #41792:  mal-freetype-crash-ft_service_list_lookup.pdf added by ziqiang_gu (5KiB - application/pdf - POC file of the vulnerability)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by wl (Updated the item)
  • -unavailable- added by podtelez (Posted a comment)
  • -unavailable- added by ziqiang_gu (Submitted the item)
  • -unavailable- added by ziqiang_gu
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 9 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Mon 18 Sep 2017 01:50:43 PM UTCpodtelezStatusWorks For Me=>Invalid
      PrivacyPrivate=>Public
      Open/ClosedOpen=>Closed
    Thu 14 Sep 2017 09:33:36 AM UTCwlAttached File-=>Added mal-freetype-crash-ft_service_list_lookup.png, #41801
      StatusNone=>Works For Me
      Assigned toNone=>wl
    Thu 14 Sep 2017 01:41:28 AM UTCpodtelezPrivacyPublic=>Private
    Wed 13 Sep 2017 09:44:42 AM UTCziqiang_guAttached File-=>Added mal-freetype-crash-ft_service_list_lookup.pdf, #41792
      Carbon-Copy-=>Added -unavailable-

    Back to the top


    Powered by Savane 3.1-cleanup1