[Bug 149537] New: Race condition in kmail attachment handling re OO.org quickstarter, gimp-remote etc and `kioexec --tempfiles'

Craig Ringer craig at postnewspapers.com.au
Tue Sep 4 11:51:18 BST 2007

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
           Summary: Race condition in kmail attachment handling re OO.org
                    quickstarter, gimp-remote etc and `kioexec --tempfiles'
           Product: kmail
           Version: 1.9.5
          Platform: Debian stable
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
        AssignedTo: kdepim-bugs kde org
        ReportedBy: craig postnewspapers com au

Version:           1.9.5 (using KDE KDE 3.5.5)
Installed from:    Debian stable Packages
Compiler:          gcc 4.1.2 
OS:                Linux

KMail should not use the --tempfiles argument when using kioexec to launch applications that may have single-instance-per-user behaviour, like GIMP (with gimp-remote) or OpenOffice, as this introduces a race where the real helper process must open the file before the single-instance-per-user launcher/wrapper finishes terminating and kioexec unlink()s the file.

This issue is easily reproduced, at least on my system and one of the user's thin clients:
1) Send yourself a message with a file in a format that'll spawn a single instance per user helper (like an .odt for example)
2) For the purposes of this test, make sure that the program in question is not already running.
3) Open the attachment, and not that everything works correctly.
4) Quit the helper program (in this case OO.o).
5) Open the attachment. Again, note that everything works correctly.
6) This time, don't quit OO.o . Instead, just close the document but leave the program running with an empty window.
7) Return the focus to KMail and open the attachment again. Either: [Fails to open file] OR [File opens successfully] depending on race outcome.
8) Repeat step 7 and observe the unpredictable outcome.

I would not be surprised if this was easier to reproduce on dual core / multiprocessor systems. I've found that OO.o rarely opens the file before kioexec can delete it, but it does so sometimes. I've not yet managed to get the GIMP (controlled by gimp-remote as per the defaults) to "win" the race at all. In fact, the GIMP can't even open the file correctly even if it's not already open. Unlike ooqstart, which directly exec()s the real OO.o if it's not already running, gimp-remote forks and exec()s gimp in the fork while the original terminates. On my Debian system the only way to open an image in the GIMP from kmail is to change the default handler for "Graphics/GIMP Image Editor" in "Open With" from "gimp-remote-2.2 %U" to "gimp-2.2 %U" .

Here's a walk through the race. If the user has OpenOffice.org open (either already in use elsewhere or launched by kmail to open another attachment) and attempts to open an .odt file emailed to them in KMail, kmail will fork or spawn a helper and call (strace output):

execve("/usr/bin/kioexec", ["kioexec", "--tempfiles", "ooffice -calc %U", "file:///tmp/kde-craig/!.xls_%5B8"...], [/* 33 vars */]) = 0

The odd filename !.xls is because I initially thought this was an issue with failing to escape shell metacharacters like `(' and '!'. Please ignore it. In any case, kioexec will exec /usr/bin/ooffice:

execve("/usr/bin/ooffice", ["ooffice", "-calc", "/tmp/kde-craig/!.xls_[8qpkhb].xl"...], [/* 33 vars */]) = 0

which succeeds, causing /usr/bin/ooffice to exec ooqstart:

execve("/usr/lib/openoffice/program/ooqstart", ["/usr/lib/openoffice/program/ooqs"..., "/tmp/kde-craig/!.xls_[8qpkhb].xl"...], [/* 34 vars */]) = 0

which notices that oo.o is already running. ooqstart then writes a message to the control socket:

write(3, "/tmp/kde-craig/!.xls_[8qpkhb].xl"..., 35) = 35

and terminates, having told the real OO.o process to open the file. Therein lying the problem, because kioexec will helpfully delete the tempfile now that the helper program has "terminated", and may do so before OO.o responds to the open request on its control socket.

More information about the Kdepim-bugs mailing list