Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Mon, Sep 28, 2015 at 5:40 AM, Anne van Kesteren wrote: > On Sun, Sep 27, 2015 at 6:14 PM, Allen Wirfs-Brock > wrote: > > Actually, that's not completely correct. Within ES2015, the only way > > explicitly allocate a large, dense area of memory is by creating a large > > ArrayBuffer instance. All attempts to create such instances eventually > > perform the actions specified by CreateDataBlock [1]. CreateDataBlock > > explicitly says that a RangeError exception is thrown if it is > impossible to > > allocated the requested memory. > > > > I would expect and future ES features that exposed similar allocation > > capabilities to follow that same pattern. > > > > [1]: http://ecma-international.org/ecma-262/6.0/#sec-createbytedatablock > > Thank you Allen. It would then make the most sense to rethrow that > exception for these methods (and ImageData constructor). I > filed https://github.com/whatwg/html/issues/197 to track this. If > anyone is interested in working on this let me know. It should be a > relatively straightforward refactoring of the existing descriptions of > these features. > > Okay. That settles it for me, future sophistication not withstanding. To give more context on the Canvas/ArrayBuffer specific cases: These APIs allow apps to request arbitrarily large contiguous memory buffers, so they are frequent sites of allocation failure errors. Often when an allocation failure happens in these API's the system is not critically low on memory, and the rest of the application/browser may very well be able to continue to function normally. For a long time in Blink, we've been mitigating OOM crashes by allowing canvases to silently fail when their backing stores fail to allocate. These failures have been implemented in a way that is transparent to the javascript code. The only side effect is that the canvas contents remain blank (I know, it's a big side effect). This strategy has avoided the confusion issue that Mark explained. The only observable effect form the app's perspective are when doing canvas readbacks, the results come back blank. Whether or not this is an acceptable user experience depends on the nature of the application and whether or not the canvas is central to the app, but it is almost always a better user experience than a crash. The additional problem we have with the ImageData creation APIs, is that failing silently is a lot trickier because the APIs must return a valid ImageData object of the correct size. Failure to do so would not be spec compliant, could result in a confused state, and would likely result in some hard to foresee exception being thrown later down the road. What Rik was suggesting about returning a fake ImageData object would be consistent with the silent failure/best effort approach we've been using so far, but it has performance implications that we can't ignore: We would have to add a conditional branch (or a function pointer indirection) to the UInt8ClampedArray element accessor to differentiate the fake vs real behaviors. This is the stuff of inner loops for image processing algorithms. Throwing a RangeError exception in these cases does seem like the lesser evil, not to mention that it is what the spec now calls for (thanks Allen).
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Sun, Sep 27, 2015 at 6:14 PM, Allen Wirfs-Brock wrote: > Actually, that's not completely correct. Within ES2015, the only way > explicitly allocate a large, dense area of memory is by creating a large > ArrayBuffer instance. All attempts to create such instances eventually > perform the actions specified by CreateDataBlock [1]. CreateDataBlock > explicitly says that a RangeError exception is thrown if it is impossible to > allocated the requested memory. > > I would expect and future ES features that exposed similar allocation > capabilities to follow that same pattern. > > [1]: http://ecma-international.org/ecma-262/6.0/#sec-createbytedatablock Thank you Allen. It would then make the most sense to rethrow that exception for these methods (and ImageData constructor). I filed https://github.com/whatwg/html/issues/197 to track this. If anyone is interested in working on this let me know. It should be a relatively straightforward refactoring of the existing descriptions of these features. -- https://annevankesteren.nl/
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Sep 26, 2015, at 7:34 AM, Anne van Kesteren wrote: > On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: >> Currently there is no spec'ed behavior for handling out-of memory issues >> for the specific case of attempting to allocate a large buffer through >> image data APIs. > > Actually, there is no specified behavior for out-of-memory behavior, > period. This is a problem that starts with the ECMAScript standard and > everything that builds upon it. Actually, that's not completely correct. Within ES2015, the only way explicitly allocate a large, dense area of memory is by creating a large ArrayBuffer instance. All attempts to create such instances eventually perform the actions specified by CreateDataBlock [1]. CreateDataBlock explicitly says that a RangeError exception is thrown if it is impossible to allocated the requested memory. I would expect and future ES features that exposed similar allocation capabilities to follow that same pattern. Allen [1]: http://ecma-international.org/ecma-262/6.0/#sec-createbytedatablock > > I have seen Mark Miller discuss some of the issues surrounding this > and perhaps even the necessity to eventually define it, but so far > this has not happened. Not sure if the full story is documented > somewhere. Mark? > > https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 > indicates there may be security issues with throwing out-of-memory > exceptions. > > > -- > https://annevankesteren.nl/ >
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
Since my post is about the more general OOM issue, I have shifted the discussion to es-discuss https://mail.mozilla.org/pipermail/es-discuss/2015-September/044267.html Please continue discussion of the non-browser-specific issue there. On Sun, Sep 27, 2015 at 8:33 AM, Mark S. Miller wrote: > I should make it clear that my post is not concerned about OOM for image > data -- the original subject of this thread -- but rather about the more > general OOM question that Anne asks about. > > > On Sat, Sep 26, 2015 at 9:15 PM, Rik Cabanier wrote: > >> On Fri, Sep 25, 2015 at 7:51 AM, Boris Zbarsky wrote: >> >> > On 9/25/15 10:48 AM, Justin Novosad wrote: >> > >> >> I am sharing this here in case there would be interest in standardizing >> >> this behavior. >> >> >> > >> > I personally think it's a good idea (and throwing an exception is how >> > Gecko handles, or at least aims to handle, this situation). >> >> >> In the past, we discussed that error conditions such as this shouldn't >> throw exceptions. Most of the time, this type of error is just temporal >> and >> is resolved in the next frame. Rare exceptions are almost never caught by >> the author so the application crashes. >> >> Maybe for out of memory conditions, we could return a fake imagedata >> object >> with nothing but transparent white. In addition an 'isValid' property >> could >> signal if you have a real imagedata object. >> > > > > -- > Cheers, > --MarkM > -- Cheers, --MarkM
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Sun, Sep 27, 2015 at 8:30 AM, Mark S. Miller wrote: > On Sat, Sep 26, 2015 at 7:34 AM, Anne van Kesteren > wrote: > >> On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: >> > Currently there is no spec'ed behavior for handling out-of memory issues >> > for the specific case of attempting to allocate a large buffer through >> > image data APIs. >> >> Actually, there is no specified behavior for out-of-memory behavior, >> period. This is a problem that starts with the ECMAScript standard and >> everything that builds upon it. >> >> I have seen Mark Miller discuss some of the issues surrounding this >> and perhaps even the necessity to eventually define it, but so far >> this has not happened. Not sure if the full story is documented >> somewhere. Mark? >> >> >> https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 >> indicates there may be security issues with throwing out-of-memory >> exceptions. > > > Well, the full story is never documented ;). However, that post and the > links from there: > > http://www.eros-os.org/pipermail/e-lang/2007-January/011817.html > https://github.com/google/caja/issues/460 > > are a good start. The security issue is serious and needs to be fixed. It > cannot practically be fixed by libraries without additional help by the > platform. The problem is that > > * In a language that implicitly allocates everywhere, like JavaScript, > Java, and many other oo languages, it is impossible to prevent a code from > causing OOM > * If OOM is thrown (see the first link for Java/Joe-E issues), and the > language has try/finally, it is impossible to prevent the OOM being masked. > * In such languages, it is impossible to program defensively against > the pervasive possibility of OOM -- if execution simply resumes in that > context as if nothing bad happened. > > In Joe-E we took the painful step of outlawing the Java try/finally from > the Joe-E subset of Java for this reason. There was no other reason to > outlaw try/finally as there's nothing else inherently unsafe about it. We > really tried to find another solution but under our constraints -- no > rewriting of the Java nor change to the JVM -- we could not. > > By preventing Joe-E code from catching VirtualMachineErrors and from doing > a try/finally, the Joe-E code was preemptively terminated immediately on > occurrence of a VirtualMachineError. Only the spawner of the Joe-E > computation could react to this termination of the computation it spawned. > > This mirrors one of the many thing that Erlang gets right. When a program > is confused, that program is the last one you want to ask to recover from > the confusion, since it is already impaired by its own confusion. If you > don't know what is still true, you are unlikely to engage in repair actions > correctly. Better to preemptively terminate some large unit containing the > confusion and recover by > * restarting from earlier known good state, or > * if this is not yet feasible, propagating the termination to a yet > larger granularity of computation. > > This is the "fail stop" philosophy of "Death Before Confusion". The > contrasting philosophy appropriate for some computation is "best efforts". > Some JavaScript code is best served by one and some by the other. Security > enforcing code must maintain its own integrity at the price of termination > (and restart from some coarser grain). Web pages using JavaScript only to > spice up the user experience are often best served by best efforts. Erlang > itself is an interesting case study, as its original motivating problem -- > telephone switches -- places a higher priority on uptime than on integrity. > Nevertheless, both Erlang and the Tandem non-stop architecture found that > uptime in the large is best served by fail-stop in the small combined with > coarser-grain recovery logic. > > Because JavaScript comes from such a long legacy of de facto best efforts > architecture, I think a direct du jure shift to fail-stop is unlikely. > Instead, what we need is a trap-handling mechanism (Erlang "supervisor". > KeyKOS "keeper"), where different policies can be expressed by user-defined > trap handlers. When multiple policies co-exist, > Sorry for incomplete sentence. Should be When multiple policies co-exist, the platform obeys the more severe policies. > For concreteness, I'll make here a first sketch: > > On OOM, the platform first scans the stack to enumerate all realms > represented by in-progress stack frames as of that moment. (In progress > meaning that the stack frame still would have been there even if that > platform had implemented proper-tail-call.) It gathers the trap handlers > associated with each of those realms. Each trap handler is a pair of a > string and an optional function. > > The string indicates the choice of trap handling strategy, where these > strategies are ordered by severity. Among the gathered strategies, the most > sev
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
I should make it clear that my post is not concerned about OOM for image data -- the original subject of this thread -- but rather about the more general OOM question that Anne asks about. On Sat, Sep 26, 2015 at 9:15 PM, Rik Cabanier wrote: > On Fri, Sep 25, 2015 at 7:51 AM, Boris Zbarsky wrote: > > > On 9/25/15 10:48 AM, Justin Novosad wrote: > > > >> I am sharing this here in case there would be interest in standardizing > >> this behavior. > >> > > > > I personally think it's a good idea (and throwing an exception is how > > Gecko handles, or at least aims to handle, this situation). > > > In the past, we discussed that error conditions such as this shouldn't > throw exceptions. Most of the time, this type of error is just temporal and > is resolved in the next frame. Rare exceptions are almost never caught by > the author so the application crashes. > > Maybe for out of memory conditions, we could return a fake imagedata object > with nothing but transparent white. In addition an 'isValid' property could > signal if you have a real imagedata object. > -- Cheers, --MarkM
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Sat, Sep 26, 2015 at 3:33 PM, Niels Keurentjes < niels.keurent...@omines.com> wrote: > > > https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 > > indicates there may be security issues with throwing out-of-memory > exceptions. > > That's hardly worth considering. The technique described there for > fingerprinting Please read beyond the title. The important issue is not fingerprinting or information leakage. It is loss of integrity. > is interesting from a theorist's perspective, but exposing no data that > cannot already be more reliably extracted from navigator.userAgent with a > simple regex. > > An out-of-memory in a sandbox is just exposing information about the > sandbox, and worth nothing therefore if the sandbox version itself isn’t > already compromised, at which point the user is generally screwed anyway if > he didn't patch in time. Being able to detect a vulnerability is not a > prerequisite for exploiting it. > > Niels > > -Original Message- > From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Anne > van Kesteren > Sent: zaterdag 26 september 2015 16:35 > To: Justin Novosad > Cc: WHAT Working Group ; Mark Miller > > Subject: Re: [whatwg] Handling out of memory issues with > getImageData/createImageData > > On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: > > Currently there is no spec'ed behavior for handling out-of memory issues > > for the specific case of attempting to allocate a large buffer through > > image data APIs. > > Actually, there is no specified behavior for out-of-memory behavior, > period. This is a problem that starts with the ECMAScript standard and > everything that builds upon it. > > I have seen Mark Miller discuss some of the issues surrounding this > and perhaps even the necessity to eventually define it, but so far > this has not happened. Not sure if the full story is documented > somewhere. Mark? > > > https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 > indicates there may be security issues with throwing out-of-memory > exceptions. > > > -- > https://annevankesteren.nl/ > -- Cheers, --MarkM
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Sat, Sep 26, 2015 at 7:34 AM, Anne van Kesteren wrote: > On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: > > Currently there is no spec'ed behavior for handling out-of memory issues > > for the specific case of attempting to allocate a large buffer through > > image data APIs. > > Actually, there is no specified behavior for out-of-memory behavior, > period. This is a problem that starts with the ECMAScript standard and > everything that builds upon it. > > I have seen Mark Miller discuss some of the issues surrounding this > and perhaps even the necessity to eventually define it, but so far > this has not happened. Not sure if the full story is documented > somewhere. Mark? > > > https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 > indicates there may be security issues with throwing out-of-memory > exceptions. Well, the full story is never documented ;). However, that post and the links from there: http://www.eros-os.org/pipermail/e-lang/2007-January/011817.html https://github.com/google/caja/issues/460 are a good start. The security issue is serious and needs to be fixed. It cannot practically be fixed by libraries without additional help by the platform. The problem is that * In a language that implicitly allocates everywhere, like JavaScript, Java, and many other oo languages, it is impossible to prevent a code from causing OOM * If OOM is thrown (see the first link for Java/Joe-E issues), and the language has try/finally, it is impossible to prevent the OOM being masked. * In such languages, it is impossible to program defensively against the pervasive possibility of OOM -- if execution simply resumes in that context as if nothing bad happened. In Joe-E we took the painful step of outlawing the Java try/finally from the Joe-E subset of Java for this reason. There was no other reason to outlaw try/finally as there's nothing else inherently unsafe about it. We really tried to find another solution but under our constraints -- no rewriting of the Java nor change to the JVM -- we could not. By preventing Joe-E code from catching VirtualMachineErrors and from doing a try/finally, the Joe-E code was preemptively terminated immediately on occurrence of a VirtualMachineError. Only the spawner of the Joe-E computation could react to this termination of the computation it spawned. This mirrors one of the many thing that Erlang gets right. When a program is confused, that program is the last one you want to ask to recover from the confusion, since it is already impaired by its own confusion. If you don't know what is still true, you are unlikely to engage in repair actions correctly. Better to preemptively terminate some large unit containing the confusion and recover by * restarting from earlier known good state, or * if this is not yet feasible, propagating the termination to a yet larger granularity of computation. This is the "fail stop" philosophy of "Death Before Confusion". The contrasting philosophy appropriate for some computation is "best efforts". Some JavaScript code is best served by one and some by the other. Security enforcing code must maintain its own integrity at the price of termination (and restart from some coarser grain). Web pages using JavaScript only to spice up the user experience are often best served by best efforts. Erlang itself is an interesting case study, as its original motivating problem -- telephone switches -- places a higher priority on uptime than on integrity. Nevertheless, both Erlang and the Tandem non-stop architecture found that uptime in the large is best served by fail-stop in the small combined with coarser-grain recovery logic. Because JavaScript comes from such a long legacy of de facto best efforts architecture, I think a direct du jure shift to fail-stop is unlikely. Instead, what we need is a trap-handling mechanism (Erlang "supervisor". KeyKOS "keeper"), where different policies can be expressed by user-defined trap handlers. When multiple policies co-exist, For concreteness, I'll make here a first sketch: On OOM, the platform first scans the stack to enumerate all realms represented by in-progress stack frames as of that moment. (In progress meaning that the stack frame still would have been there even if that platform had implemented proper-tail-call.) It gathers the trap handlers associated with each of those realms. Each trap handler is a pair of a string and an optional function. The string indicates the choice of trap handling strategy, where these strategies are ordered by severity. Among the gathered strategies, the most severe win and the rest are discarded. From least to most severe, they are "THROW" "ABORT_JOB" "REFRESH" "ABORT_EVENT_LOOP" Except for "THROW", all the rest cause the current turn/job to first be preemptively terminated without running catch or finally blocks. If during any one trap handling strategy we run out of reserve memory, then
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Fri, Sep 25, 2015 at 7:51 AM, Boris Zbarsky wrote: > On 9/25/15 10:48 AM, Justin Novosad wrote: > >> I am sharing this here in case there would be interest in standardizing >> this behavior. >> > > I personally think it's a good idea (and throwing an exception is how > Gecko handles, or at least aims to handle, this situation). In the past, we discussed that error conditions such as this shouldn't throw exceptions. Most of the time, this type of error is just temporal and is resolved in the next frame. Rare exceptions are almost never caught by the author so the application crashes. Maybe for out of memory conditions, we could return a fake imagedata object with nothing but transparent white. In addition an 'isValid' property could signal if you have a real imagedata object.
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
> https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 > indicates there may be security issues with throwing out-of-memory exceptions. That's hardly worth considering. The technique described there for fingerprinting is interesting from a theorist's perspective, but exposing no data that cannot already be more reliably extracted from navigator.userAgent with a simple regex. An out-of-memory in a sandbox is just exposing information about the sandbox, and worth nothing therefore if the sandbox version itself isn’t already compromised, at which point the user is generally screwed anyway if he didn't patch in time. Being able to detect a vulnerability is not a prerequisite for exploiting it. Niels -Original Message- From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Anne van Kesteren Sent: zaterdag 26 september 2015 16:35 To: Justin Novosad Cc: WHAT Working Group ; Mark Miller Subject: Re: [whatwg] Handling out of memory issues with getImageData/createImageData On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: > Currently there is no spec'ed behavior for handling out-of memory issues > for the specific case of attempting to allocate a large buffer through > image data APIs. Actually, there is no specified behavior for out-of-memory behavior, period. This is a problem that starts with the ECMAScript standard and everything that builds upon it. I have seen Mark Miller discuss some of the issues surrounding this and perhaps even the necessity to eventually define it, but so far this has not happened. Not sure if the full story is documented somewhere. Mark? https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 indicates there may be security issues with throwing out-of-memory exceptions. -- https://annevankesteren.nl/
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On Fri, Sep 25, 2015 at 4:48 PM, Justin Novosad wrote: > Currently there is no spec'ed behavior for handling out-of memory issues > for the specific case of attempting to allocate a large buffer through > image data APIs. Actually, there is no specified behavior for out-of-memory behavior, period. This is a problem that starts with the ECMAScript standard and everything that builds upon it. I have seen Mark Miller discuss some of the issues surrounding this and perhaps even the necessity to eventually define it, but so far this has not happened. Not sure if the full story is documented somewhere. Mark? https://esdiscuss.org/topic/using-max-stack-limit-to-determine-current-js-engine-and-revision#content-7 indicates there may be security issues with throwing out-of-memory exceptions. -- https://annevankesteren.nl/
Re: [whatwg] Handling out of memory issues with getImageData/createImageData
On 9/25/15 10:48 AM, Justin Novosad wrote: I am sharing this here in case there would be interest in standardizing this behavior. I personally think it's a good idea (and throwing an exception is how Gecko handles, or at least aims to handle, this situation). -Boris