-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integer overflow in StringBytes::Encode hex leads to a crash or an infinite loop #46836
Comments
Want to send a pull request? For background, that code was written at a time when node / V8 didn't support buffers larger than 1 or 2 GB. Subsequent refactors then switched some things to |
The required change would be changing "i" and "k" to |
Switching to |
Fixes: #46836 PR-URL: #48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: #46836 PR-URL: #48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: #46836 PR-URL: #48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: #46836 PR-URL: #48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: #46836 PR-URL: #48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: nodejs#46836 PR-URL: nodejs#48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Fixes: nodejs#46836 PR-URL: nodejs#48033 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Stephen Belanger <[email protected]>
Version
No response
Platform
No response
Subsystem
No response
What steps will reproduce the bug?
Run the following code (node buf_test_1.js):
It will most likely crash (with an access violation exit code on Windows or with a segmentation fault on Linux) and won’t reach the last line of code.
Now run the following code (node buf_test_2.js):
This code will run infinitely in a loop and will never end.
These issues also manifest when running untrusted code in a sandboxed vm, which is the more likely scenario for exploitation:
Even though a timeout is defined, the code executes forever.
How often does it reproduce? Is there a required condition?
Stable reproduction
What is the expected behavior?
Console shows "Never gets executed"
What do you see instead?
The code executes forever (infinite loop)
Additional information
Note - This was first reported as a security issue, but rejected since the main attack scenario is when using the
vm
moduleSummary:
Due to a type mismatch between variables in the string_bytes module, an integer overflow occurs, which can cause a crash or an infinite loop.
Description:
The code in string_bytes.cc encodes and decodes different types of string encodings. In the StringBytes::Encode function, there is a case that takes care of “hex” encoding:
The “dlen” variable created in this code is of type “size_t”. It is passed to the StringBytes::hex_encode function, which looks like this:
Also here the type of “dlen” is “size_t”, but the types of the variables “i” and “k” are “uint32_t”. In 64-bit operating systems, “size_t” is equivalent to a 64-bit unsigned integer. In a case that “dlen” is more than 32 bits long (for example 0x100000000), the variable “k” will be increased until it reaches the maximum value for an unsigned 32-bit integer (0xfffffffe since “k” increases by 2 in each iteration), and will the wrap around to 0. The expression “k < dlen” in the “for” statement will always be true, meaning that the loop runs infinitely. Since the array “src” is being read in the index “i” (which increases by 1 in every iteration, hence not wrapping around at the same time as “k”), at some point it will try reading from a memory address that doesn’t belong to “src”, and will eventually crash.
The variable “dlen” is equal to “src”’s length times 2. For example, if “src”’s length is 0x80000000, “dlen” will be equal to 0x100000000, causing a crash at some point after the variable “i” passes 0x80000000.
An infinite loop without crashing exists in the case that src’s length is 0x100000000, meaning “dlen” is 0x200000000. In this case both “i” and “k” keep wrapping forever, and the code never finishes running.
These code flows are not likely to appear organically, but in cases where there is use of the “vm” module to run untrusted code in a sandbox, these situations could be real and easily cause crashes or infinite loops. “vm”’s timeout option does not work in this case. Reaching this vulnerable code is possible by using the Buffer object, which is enabled by default in both “vm” and “vm2” modules without the need to use any external modules.
The text was updated successfully, but these errors were encountered: