Javascript code fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser using document.title

UNCONFIRMED
Unassigned

Status

()

Firefox
Security
--
critical
UNCONFIRMED
8 years ago
4 years ago

People

(Reporter: Jim Bauwens, Unassigned)

Tracking

({crash, testcase})

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [sg:dos] DUPEME)

Attachments

(1 attachment)

(Reporter)

Description

8 years ago
User-Agent:       Mozilla/5.0 (X11; Linux i686; rv:2.0b8pre) Gecko/20101026 Firefox/4.0b8pre
Build Identifier: Mozilla/5.0 (X11; Linux i686; rv:2.0b8pre) Gecko/20101026 Firefox/4.0b8pre

I created a javascript code that constantly duplicates the title (document.title += document.title; in a loop).
This fills the memory of the computer very fast.
The code works in EVERY browser, every OS, but each have different results.
The only browser that handles it good is chromium (or google chrome), were the tab 'snaps' when the memory reaches 100%.
On every mobile device on which I tried this script the browser crashed (iOS and Android). If a computer does not have swap (virtual mem), firefox crashes.
IE9 on windows 7 takes the system down (it forces you to reboot).




Reproducible: Always

Steps to Reproduce:
Code :

<html>
	<head>
		<title>&nbsp;</title>
		<script>
		
		function ohoh(){
			while (true){
				document.title += document.title;
			}
			
		}
		
		</script>
	</head>
	<body onmouseover="ohoh();" onload="ohoh()">
	</body>
</html>
Actual Results:  
The memory and the swap of the computer climbs to 100%
For the (real) memory is only takes a few seconds to jump to 100%
Then its starts filling swap, and that takes a few minutes.
During this process the computer is very slow.

Expected Results:  
The browser(s) should limit the amount of characters possible in a title, and/or limit the amount of memory that a website can use.
(Reporter)

Comment 1

8 years ago
Created attachment 486311 [details]
Testcase, this script fills the mem of your computer (if you click on this link the script will auto-start and you will have to force quit firefox (if you can))
(Reporter)

Updated

8 years ago
Summary: Javascript code to fill memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser → Javascript code to fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser
(Reporter)

Updated

8 years ago
Summary: Javascript code to fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser → Javascript code fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser
(Reporter)

Comment 2

8 years ago
NOTE : When you click on the test case, the script will start running, and you will have to force quit firefox (if you can).
(Reporter)

Updated

8 years ago
Attachment #486311 - Attachment description: Testcase, this script fills the mem of your computer → Testcase, this script fills the mem of your computer (if you click on this link the script will auto-start and you will have to force quit firefox (if you can))
Fairly sure we have a generic "web pages can fill up your memory" bug to dupe this against. This is a denial of service attack.

Reasonable limits on DOM nodes would be a bad idea, but there will always be other ways to exhaust memory.
Group: core-security
Keywords: crash, testcase
Whiteboard: [sg:dos] DUPEME
(Reporter)

Comment 4

8 years ago
Maybe you can look at the way Chrome handles this.
Here the page snaps, and doesn't take the whole browser down.
I think that each tab has its own process.

Comment 5

8 years ago
Comfirming x86 winXP
the browser should check to see if the tab is using, like, more than 98% or whatever of the memory of the system and display a warning, like the unresponsive script dialog.

Comment 6

8 years ago
Known issue. It's due to the while loop. 
This does the trick too:

<script>
   while (1){}
</script>

And done so for years.
(Reporter)

Comment 7

8 years ago
No, this is another issue.
With to code you gave it only consumes cpu power, but with my code the memory of the computer fills up, and makes the whole os unresponsive.

Comment 8

8 years ago
They amount to the same result, because it's obvious why. In both cases the loop is true. No matter what you put inside it. Try a document.write, or any other textrun that depends on memory and it will fill memory as well. Can't see how this could be fixed. Tough, I know Opera handles similar (DoS) processes a bit better especially on newly opened tabs.

Comment 9

8 years ago
Possibly there should exist a CPU minotoring thread (such as a watchdog) that can make sure that if this monitor becomes very slow to respond (say, above 5 seconds to handle the rethrown event), then the most expensive thread will be forced to slow down progressively to make sure that it will at least allow other threads and proces to take control and maintain the responsiveness of the GUI under reasonnable limits (5 seconds to handle GUI requests from a watchdog seems a reasonnable limit for users).

Yes it will still allow the thread to fill up memory, but this is not really the memory filling that is the issue but the huge amount of CPU time taken just to perform here the memory allocations, swaps to disk, zeroing pages of new uncommited memory, and copying data from one page to another, and swapping dirty pages at a very high rate, even though they are very recent. Slowing down things can help recover the situation, and can also allow the monitor to display an alert box about a "frozen" thread tht it should propose to kill in the Javascript VM.

Things would be simpler if the OS was at least implementing resource quotas not just on disk space, but also on swap space per user and per process, because we would at least see "out of memory" exceptions, before the whole system freezes.

But can't we at least simulate "out of memory" exceptions by allowing the watchdoc monitor to control when it will really allow more memory to be allocated to a client thread ? In that case the fix needs some interface between the watchdog (or a debugger) and the VM to control memory resource exhaustions. The watchdog could implement a resource arbitrator by checking that each thread (or authorized processes) that it controls cannot exhaust all resources wanted by other threads so much that one of them will cause CPU time starvation to all others (and notably to those that are not blocked waiting for I/O completion, but ready to run).

Ideally, the watchdog should be running in its own minimal process (just like the "idle" process of the underlying OS). Note that many OSes are now also implementing their own watchdog process (but for securing low level I/O requests and recover from possible timeouts, giving a chance for the upper layer client to get informed that something is getting too slow). This is true in Windows as well of Linux. The system performance monitors are also providing an interface for using its service.

The OS will make sure that there will always be enough CPU time and ressources available to the watchdog service itself and handler callbacks in client processes. This allows any aplication to register with this watchdog and allow them to pace down their resource usage enough to allow a user to control the GUI and possibly abort manually a too long UI request (such as here, refreshing a page, or cancelling a page load and coming back in the browser history, or close the tab, or, if the user is experienced, suspend a tab just to allow him to investigate what's happening in the background by starting and attaching some external debugger).

Updated

7 years ago
Summary: Javascript code fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser → Javascript code fills memory and virtual memory to 100%, slows down the computer, and potentially crashes the browser using document.title

Comment 10

7 years ago
You changed te bug description, limiting it to "document.title". If the issue is just in document.title, there's no reason for this title to exceed a reasonnable limit for what is intended to be a single-line label; In addition, this title is used to create the system caption of the window, and this may be anissue there, as it could eat too much GDI ressources on Windows, and anyway it will be truncated (even if, though the Javascript interface, it is exposed to a longer value).
I'm however not sure that this bug is limited to "doucment.title" (which is just used there as a convenience without having to create a new property).
My tests when assigning a custom property or standard "data-*" of any HTML element shows the same bug: the fast exponentially growing usage of memory is effectively a problem, as it does not seem that the GUI freeze is caused by the GUI but effectively inthe VM allocator (whose garbage collector is heavily stressed trying to recompact many objects or constantly swapping them out only to make place to fit the copied strings in memory, and performing this copy. Then above some limit, the VM is permanently occupied trying to swap out the strings and reloading parts of memory from disk, but if this was the case, we would see long I/O requests in queue. But here this is the CPU that is constantly overwhelmed (this effectively means that the garbage collection is constantly relaunched, and is constantly freeing autoreleasable objects that need to be reconstructed).
Once again, the only stable solution is to fix some CPU sage quota in each tab, and to make sure that all tabs won't use more than about 85% of CPU time for more than about 10 seconds, and then slow these processes/threads by idling them to avoid CPU time starvation in the global system (there should also remain time to allow the "Cancel loading/stop script" button or the "history back" button to work and reply in a reasonnable time, preferably always in at most 1 second. Here again, a watchdog process (or thread in the main GUI browser process) can measure the response time to a delayed event (when a javascript starts running, setup a wakeup event to the watchdog every about 5 seconds, and detect the late time it takes to handle the event; then the watchdog can slow down the CPU-hungry processes/threads, for example by reducing its priority, or pausing it until the watchdog wakeup delay becomes acceptable). The user should always have the control and should be able to launch any other external tool (such as a debugger), or have the possibility to suspend a long-running javascript...
(Reporter)

Comment 11

7 years ago
Its nice to see that someone is still busy with this :)

I can't say much more, because browser programming is not what I do :)

Thanks!

Comment 12

6 years ago
Someone mentioned before to handle this using the same method that Google Chrome uses. When you open the link using Google Chrome it simply takes you to an error page saying that something went wrong while viewing the page. In order to do this you could do as verdy_p mentioned and create a CPU or memory monitor. If the monitor noticed a spike of whatever within n amount of time then it takes you to an error page saying that the page was unable to load.
You need to log in before you can comment on or make changes to this bug.