On Sat, Jan 06, 2007 at 17:10:18 -0800, missileboat wrote: > Ok, so, aside from having to Force Quit apps affected by a malicious > PDF, what else will this cause?
Read the advisory carefully. The next step after memory corruption is often execution of arbitrary code.
So far, it seems like it is just an infinite loop of CGPDFReaderGetPageDictionary(). mdimport automatically kills itself after spending too much time on it. Safari just sits there eating CPU. For the latter it's just a classic denial of service attack.
It also seems mdimport runs in the current user's context.
No need to worry about Acrobat Reader, since the issue has already been fixed in version 8. That, and I venture to say that most mac users don't use Adobe Acrobat reader to read PDFs. It's just too dang slow and not fat.
I don't think this one is exploitable (even in theory) in the CGPDFReaderGetPageDictionary() case. One method is to put some kinda of static var in there that counts the number of times CGPDFDictionaryGetCount() is called with the same object and the same key (type). If you then return 0 from is_page_tree_node(), then the PDF reader will correctly log: "Some pages of this PDF are corrupt and will be ignored." Then all is well with the world.
I don't see any memory corruption in the CGPDFDocument case. Or any exploitation condition on Mac OS X. Sadly, I don't have Adobe Reader 7.x or lower installed to see how it handles it.
The advisory seems to only state that Linux implementations crash.
Ack, at 1/6/07, Matt Beaumont said:
>On Sat, Jan 06, 2007 at 17:10:18 -0800, missileboat wrote: >>Ok, so, aside from having to Force Quit apps affected by a malicious >>PDF, what else will this cause?
>Read the advisory carefully. The next step after memory corruption is >often execution of arbitrary code.
--
Sincerely, Rosyna Keller Technical Support/Carbon troll/Always needs a hug
Unsanity: Unsane Tools for Insanely Great People
It's either this, or imagining Phil Schiller in a thong.
> So far, it seems like it is just an infinite loop of > CGPDFReaderGetPageDictionary(). mdimport automatically kills itself > after spending too much time on it. Safari just sits there eating > CPU. For the latter it's just a classic denial of service attack.
> It also seems mdimport runs in the current user's context.
> No need to worry about Acrobat Reader, since the issue has already > been fixed in version 8. That, and I venture to say that most mac > users don't use Adobe Acrobat reader to read PDFs. It's just too > dang slow and not fat.
> I don't think this one is exploitable (even in theory) in the > CGPDFReaderGetPageDictionary() case. One method is to put some > kinda of static var in there that counts the number of times > CGPDFDictionaryGetCount() is called with the same object and the > same key (type). If you then return 0 from is_page_tree_node(), > then the PDF reader will correctly log: "Some pages of this PDF are > corrupt and will be ignored." Then all is well with the world.
In this particular case, the page node is self-referential -- from my reproduction: 7 0 obj << /Type /Pages /MediaBox [0 0 612 792] /Count 1 /Kids [ 7 0 R ] >> endobj
I've briefly played around with other potential error conditions, and haven't been able to trigger any other bugs in CG's PDF handler -- not that my search was exhaustive.
On Jan 7, 2:17 am, Matt Beaumont <m...@cs.ucla.edu> wrote:
> On Sat, Jan 06, 2007 at 17:10:18 -0800, missileboat wrote: > > Ok, so, aside from having to Force Quit apps affected by a malicious > > PDF, what else will this cause?Read the advisory carefully. The next step after memory corruption is > often execution of arbitrary code.
> -Matt
not often, rarely.
this is not a MOAB, this is a MOB.
there are thousands of bugs like this.
the next one will be:
when i modify the code of application X it crashes !
> In this particular case, the page node is self-referential -- from > my reproduction: > 7 0 obj > << /Type /Pages /MediaBox [0 0 612 792] /Count 1 /Kids [ 7 0 R ] >> > endobj
Attached is a patch against trunk that implements PDF loop detection. I kept banging on this one late into the night just because the Proof- of-Concept DoS is such a pain in the neck -- *everything* renders PDFs, from Safari to Mail.app.
The bug itself is in the CGPDFReaderGetPageDictionary() function -- it doesn't implement any loop detection, such that a self-referential PDF page node object can refer back to itself infinitely. The fix works by maintaining a per-thread key for the length of the CGPDFReaderGetPageDictionary() call. A counter is assigned to the key upon entry to CGPDFReaderGetPageDictionary(), and the key is cleared upon exit from CGPDFReaderGetPageDictionary().
pdf_xref_resolve() is called within the loop, and I use our guard_pdf_xref_resolve() to acquire a reference to the pthread key and increment the counter. When the counter hits MAX_LOOP (500000), guard_pdf_xref_resolve() returns NULL, which the caller (CGPDFReaderGetPageDictionary ) then handles correctly, breaking out of the loop.
I'd appreciate a code review, and more sets of eyes on CGPDFReaderGetPageDictionary and pdf_xref_resolve, to make sure I didn't bungle anything. You can find my proof-of-concept PDF here: http://landonf.bikemonkey.org/static/moab-tests/autopdf.html
> pdf_xref_resolve() is called within the loop, and I use our > guard_pdf_xref_resolve() to acquire a reference to the pthread key > and increment the counter. When the counter hits MAX_LOOP (500000), > guard_pdf_xref_resolve() returns NULL, which the caller > (CGPDFReaderGetPageDictionary ) then handles correctly, breaking > out of the loop.
I should also note that the guard_pdf_xref_resolve() function skips all loop detection if the pthread key is not set (ie, it is called outside of CGPDFReaderGetPageDictionary())