Bug 82290 - EPS rendering using GS may cause pipe writing deadlock
Summary: EPS rendering using GS may cause pipe writing deadlock
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: filters and storage (show other bugs)
Version:
(earliest affected)
4.2.5.2 release
Hardware: All Linux (All)
: medium major
Assignee: Hiroto Kagotani
URL:
Whiteboard: target:4.4.0
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-07 11:27 UTC by Hiroto Kagotani
Modified: 2015-04-01 16:27 UTC (History)
0 users

See Also:
Crash report or crash signature:


Attachments
EPS file that causes a deadlock (119.51 KB, image/x-eps)
2014-08-07 11:28 UTC, Hiroto Kagotani
Details
ODP file that causes a deadlock (38.24 KB, application/vnd.oasis.opendocument.presentation)
2014-08-07 11:29 UTC, Hiroto Kagotani
Details
Patch to 4.2.5.2 (1.60 KB, patch)
2014-08-07 11:31 UTC, Hiroto Kagotani
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Hiroto Kagotani 2014-08-07 11:27:14 UTC
If I have pstoedit, there is no problem with handling EPS files.  Without pstoedit, EPS is rendered as BMP using GS in RenderAsBMPThroughHelper().  The input/output to/from GS are transferred using pipes.

RenderAsBMPThroughHelper() first writes the EPS file content to a pipe pIn, then closes the pipe, and then reads BMP result from another pipe pOut.  With this sequence, GS may start to produce the BMP result as soon as it reads a "showpage" operator from stdin, and this causes a deadlock between LO writing to a pipe and GS writing to another pipe.

On FreeBSD, this situation frequently happens because write(2) >= 8KB to pipes always blocks until the whole pipe buffer content is consumed by read(2).

On Linux, this situation rarely happens because write(2) to pipes returns immediately if the size is less than the buffer size.  However, large EPS using a "showpage" operator and including a large bogus trailer can cause this deadlock.  Attached EPS and ODP are example files that cause the deadlock.

How-to-repeat:
Make sure pstoedit is NOT installed and GS is properly installed.
On FreeBSD (9.3R or 10.0R) or Linux (Fedora 20), open the attached ODP file, or insert the attached EPS file to any LO document.

Fix:
There are several solutions to fix this deadlock.
1. Do not use pipes for both direction.  Like in RenderAsEMF(), use a temporary file for BMP result.
2. Do not use blocking write(2)/read(2).  Make them non-blocking, and use select(2) to choose the next operation.
3. Perform write(2) and read(2) concurrently.  Create a new thread and perform write(2) in it.

Attached patch is for the 3rd solution.
Comment 1 Hiroto Kagotani 2014-08-07 11:28:47 UTC
Created attachment 104219 [details]
EPS file that causes a deadlock
Comment 2 Hiroto Kagotani 2014-08-07 11:29:29 UTC
Created attachment 104220 [details]
ODP file that causes a deadlock
Comment 3 Hiroto Kagotani 2014-08-07 11:31:34 UTC
Created attachment 104221 [details]
Patch to 4.2.5.2
Comment 4 Jan Holesovsky 2014-08-08 08:58:25 UTC
Hirato: Thank you for the patch!  I have pushed it to the gerrit, our code review system:

https://gerrit.libreoffice.org/10825

and added a note there - we should definitely destroy the thread too when the work is finished.

Would be ideal if you can submit your further patches directly via gerrit, in bugzilla they can be overlooked by mistake; but not in gerrit :-)  How to get set up with gerrit (if you haven't done it yet):

https://wiki.documentfoundation.org/Development/gerrit

Thank you again! :-)
Comment 5 Hiroto Kagotani 2014-08-19 07:29:59 UTC
Thank you, Jan.

I followed the instruction and "git push"ed, then new gerrit code review was created at

https://gerrit.libreoffice.org/#/c/11014/

I don't know how to add my patch to your code review at

https://gerrit.libreoffice.org/#/c/10825/


Thanks.
Comment 6 Commit Notification 2014-08-25 09:38:18 UTC
Hiroto Kagotani committed a patch related to this issue.
It has been pushed to "master":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=48500bdd0571b11f56161579b576e37883f4c81d

fdo#82290: avoid pipe deadlock by executing write(2) in a new thread



The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds
Affected users are encouraged to test the fix and report feedback.