Google patches second Chrome zero-day in two weeks(zdnet.com)
zdnet.com
Google patches second Chrome zero-day in two weeks
https://www.zdnet.com/article/google-patches-second-chrome-zero-day-in-two-weeks/
6 comments
An option to do this would be interesting and useful, especially for security-minded organizations. I personally wouldn't enable it myself.
CVE-2020-16009 and CVE-2020-15999 are described are "heap corruption". Are those two¹ bugs possible only in memory unsafe programming languages (in other words, they don't happen with safe programming languages and practices)?
¹=edit: clarified I was referring to the specific bugs
¹=edit: clarified I was referring to the specific bugs
Diane wrote an analysis of how many bugs would have been avoided had the Servo style system been in Gecko all along:
https://hacks.mozilla.org/2019/02/rewriting-a-browser-compon...
"There’s a significant overlap between memory vulnerabilities and severe security problems. Of the 34 critical/high bugs, 32 were memory-related."
Rust doesn't fix everything, and this result won't hold for code that is itself security logic (ie, crypto implementation) as logic errors are also very bad. But fixing memory safety does address almost all the high and critical severity issues.
Microsoft published similar research: https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-s...
Keep in mind that the Gecko style system has had two decades of work before the Rust code came along, and was written by some excellent programmers. It was extensively fuzzed for years. And still, Rust has enormous potential to solve these security issues.
Only time will tell if the next decade with Rust will pan out as the data seem to predict, but I am quite hopeful.
"There’s a significant overlap between memory vulnerabilities and severe security problems. Of the 34 critical/high bugs, 32 were memory-related."
Rust doesn't fix everything, and this result won't hold for code that is itself security logic (ie, crypto implementation) as logic errors are also very bad. But fixing memory safety does address almost all the high and critical severity issues.
Microsoft published similar research: https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-s...
Keep in mind that the Gecko style system has had two decades of work before the Rust code came along, and was written by some excellent programmers. It was extensively fuzzed for years. And still, Rust has enormous potential to solve these security issues.
Only time will tell if the next decade with Rust will pan out as the data seem to predict, but I am quite hopeful.
One question I have, since the JVM, Flash VM, and also Javascript VM seems to have occasional security issues - how confident are we that rustc bugs wont undermine the security of correctly written rust programs?
Confident, not because rustc is written better but because your comment confuses two types of bugs.
The bugs you're talking about in JVM, flash, and javascript implementations are bugs that allow malicious code to confuse the language implementation and break out of the programming language defined sandbox. Rust eliminates this class of bugs by not trying to sandbox anything in the first place :P.
If you did try and modify rustc to create that type of sandbox, you would fail, rustc is filled with the sort of bugs that allow malicious code to trick the compiler (largely as a result of using llvm as the backend).
However the bugs that would undermine the security of correctly written code are a different sort of bug. These are bugs where the compiler takes well defined non-exploitable code and miscompiles it to produce a program that when fed malicious input is exploitable. These bugs are much rarer, because the input to the compiler is not malicious so the compiler is much more likely (almost always) to be on the happy/correct path.
The bugs you're talking about in JVM, flash, and javascript implementations are bugs that allow malicious code to confuse the language implementation and break out of the programming language defined sandbox. Rust eliminates this class of bugs by not trying to sandbox anything in the first place :P.
If you did try and modify rustc to create that type of sandbox, you would fail, rustc is filled with the sort of bugs that allow malicious code to trick the compiler (largely as a result of using llvm as the backend).
However the bugs that would undermine the security of correctly written code are a different sort of bug. These are bugs where the compiler takes well defined non-exploitable code and miscompiles it to produce a program that when fed malicious input is exploitable. These bugs are much rarer, because the input to the compiler is not malicious so the compiler is much more likely (almost always) to be on the happy/correct path.
CVE-2020-15999 was described as:
"A vulnerability exists in the function `Load_SBit_Png`, which processes PNG images embedded into fonts. This function:
1) Obtains the image width and height from the header as 32-bit integers.
2) Truncates the obtained values to 16 bit and stores them in a `TT_SBit_Metrics` structure.
3) Uses the truncated values to calculate the bitmap size.
4) Allocates the backing store of that size.
5) Passes `png_struct` and the backing store to a libpng function.
The issue is that libpng uses the original 32-bit values, which are saved in `png_struct`. Therefore, if the original width and/or height are greater than 65535, the allocated buffer won't be able to fit the bitmap."
This one could only happen in an memory unsafe programming language. Having bounds checks on the destination buffer would have avoided the problem.
"A vulnerability exists in the function `Load_SBit_Png`, which processes PNG images embedded into fonts. This function:
1) Obtains the image width and height from the header as 32-bit integers.
2) Truncates the obtained values to 16 bit and stores them in a `TT_SBit_Metrics` structure.
3) Uses the truncated values to calculate the bitmap size.
4) Allocates the backing store of that size.
5) Passes `png_struct` and the backing store to a libpng function.
The issue is that libpng uses the original 32-bit values, which are saved in `png_struct`. Therefore, if the original width and/or height are greater than 65535, the allocated buffer won't be able to fit the bitmap."
This one could only happen in an memory unsafe programming language. Having bounds checks on the destination buffer would have avoided the problem.
As Hoare would put it in 1981,
"The first principle was security: The principle that every syntactically incorrect program should be rejected by the compiler and that every syntactically correct program should give a result or an error message that was predictable and comprehensible in terms of the source language program itself. Thus no core dumps should ever be necessary. It was logically impossible for any source language program to cause the computer to run wild, either at compile time or at run time. A consequence of this principle is that every occurrence of every subscript of every subscripted variable was on every occasion checked at run time against both the upper and the lower declared bounds of the array. Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to--they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary pre- cautions would have long been against the law."
https://www.cs.fsu.edu/~engelen/courses/COP4610/hoare.pdf
I guess in IT one needs a couple of decades to be proven right.
"The first principle was security: The principle that every syntactically incorrect program should be rejected by the compiler and that every syntactically correct program should give a result or an error message that was predictable and comprehensible in terms of the source language program itself. Thus no core dumps should ever be necessary. It was logically impossible for any source language program to cause the computer to run wild, either at compile time or at run time. A consequence of this principle is that every occurrence of every subscript of every subscripted variable was on every occasion checked at run time against both the upper and the lower declared bounds of the array. Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to--they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary pre- cautions would have long been against the law."
https://www.cs.fsu.edu/~engelen/courses/COP4610/hoare.pdf
I guess in IT one needs a couple of decades to be proven right.
FreeType is an endless shitshow of security vulnerabilities going back 25 years now. There's really no excuse in 2020 for writing libraries to decode file formats in unsafe languages. Yes, there are performance-sensitive aspects to image decoding, but opening the file and reading two integers is not one of those.
As if this was available 25 years ago. IMHO the real issue is embedded pngs in _fonts_, but YMMV.
Feel free to start rewriting libpng and freetype in rust. See you in 25 years?
Feel free to start rewriting libpng and freetype in rust. See you in 25 years?
Looks like this work is already well under way, maybe even already done: https://docs.rs/png/0.16.7/png/ and https://docs.rs/ttf-parser/0.8.2/ttf_parser/ .
System programming languages with bounds checking enabled go back to 1961.
We are stuck with C due to the synergy effects of having a free beer OS with source code available.
We are stuck with C due to the synergy effects of having a free beer OS with source code available.
It's incorrect to believe that C was the right choice even in 1996. At that time it was already obviously the wrong choice.
It was the only choice that met the performance constraints at the time.
And the common sense at the time did not put too much focus on memory safety.
And the common sense at the time did not put too much focus on memory safety.
I was meeting the performance constraints of doing software in MS-DOS with Turbo Pascal.
I wasn't; back then there were a LOT of things, especially in graphics and linear algebra, that required dropping to embedded ASM to accomplish in a performant way. I think Turbo- and Object Pascal were great languages, but let's not pretend they were anywhere near the speed of C.
The point of my remark here is we aren't talking about rendering text along a path or whatever. We're talking about opening a file and parsing a binary format, which is in most use cases not at all performance-sensitive.
C machine code quality was just as slow as anything else on 16 bit computers, lets not pretend otherwise.
Modula-2 and Pascal compilers had the necessary switches to make the languages just as unsafe as C, and anything related to ultimate performance out of 8086 and 68000 required Assembly anyway.
Modula-2 and Pascal compilers had the necessary switches to make the languages just as unsafe as C, and anything related to ultimate performance out of 8086 and 68000 required Assembly anyway.
FreeType was initially written in Pascal.
> IMHO the real issue is embedded pngs in _fonts_, but YMMV.
Png is a pretty simple format that everyone already implements. Would you rather use something ad-hoc?
Png is a pretty simple format that everyone already implements. Would you rather use something ad-hoc?
I would bet that most libraries chrome uses for file format parsing would not lose any performance at all if rewritten in rust.
You don't even have to drop the remaining zero-days if you apply enough performance hacks using unsafe.
I believe your comment under appreciated the utility of having all unsafe functionality clearly marked as such, with the additional scrutiny that such a label would bring. Instead of having to look through the entire codebase for memory issues, only small set of areas would need to be validated.
The problem is you’d have to rewrite them.
It was not originally meant to be fed malicious inputs from the web all day though. I think the majority of the responsibility rests on people plugging it into web browsers.
I don't think that's really true. Downloading and installing fonts was one of the very first popular activities online. At the time FreeType was written it was easily seen that untrusted inputs would be the norm.
Sure but you can hardly place the same onus of security rigor on the shoulders of a 90's OS/2 software hobbyist enabling people to explicitly download font files once in a blue moon from sources they explicitly choose, vs a big corporation in the 00's employing world class product security staff deciding to stick that in their source tree without even a shrug, where the downloading and applying the fonts happens behind the users back with 0 interaction.
I believe WebKit integrated FreeType2 years before Chrome project even started.
Why do you call it like that? I mean, does it compare bad enough to other font libraries that you feel justified in summarizing it as "an endless shitshow"?
The issue is in the bindings, which necessarily call libpng in an unsafe way. But if you use known-good bindings it should be prevented. Or if you use a native memory safe library for that matter.
> Having bounds checks on the destination buffer would have avoided the problem.
Since the access to the buffer happens inside libpng, this means libpng should have bounds checks compiled in according to your argument. (Hoping that the compiler can elide them by seeing through the library interface is but wishful thinking.)
Would you rather have a slower version of libpng that defends against screwups of the calling code, or a faster version that assumes the calling code is sane? Not an obvious choice to me.
Since the access to the buffer happens inside libpng, this means libpng should have bounds checks compiled in according to your argument. (Hoping that the compiler can elide them by seeing through the library interface is but wishful thinking.)
Would you rather have a slower version of libpng that defends against screwups of the calling code, or a faster version that assumes the calling code is sane? Not an obvious choice to me.
Would you rather have a belt that limits movements that defends against crashes, or freedom of movements that assumes a car crash never happens? Not an obvious choice to me.
> Are those two¹ bugs possible only in memory unsafe programming languages
CVE-2020-16009 is a bug in V8 (Chrome's implementation of JavaScript).
You could write a JavaScript implementation in Rust. However, to achieve acceptable performance, you would almost certainly need to use a lot of "unsafe" code. A performant JavaScript implementation has to be able to generate raw machine code, after all, and then execute it. And the garbage collector probably isn't going to manage memory in a way that the Rust compiler can verify for correctness.
So no, "use a memory-safe language" isn't a simple answer to this kind of bug. Using Rust could reduce the attack surface somewhat but certainly would not completely prevent bugs.
CVE-2020-16009 is a bug in V8 (Chrome's implementation of JavaScript).
You could write a JavaScript implementation in Rust. However, to achieve acceptable performance, you would almost certainly need to use a lot of "unsafe" code. A performant JavaScript implementation has to be able to generate raw machine code, after all, and then execute it. And the garbage collector probably isn't going to manage memory in a way that the Rust compiler can verify for correctness.
So no, "use a memory-safe language" isn't a simple answer to this kind of bug. Using Rust could reduce the attack surface somewhat but certainly would not completely prevent bugs.
It's hard to make sweeping claims without knowing what this exact bug looked like (and the associated chromium issue isn't public yet, I believe). Generally speaking, memory-safe programming languages (Java, Safe Rust, Python...) shouldn't have any heap corruption bugs (modulo bugs in their implementation, of course). Memory-safe generally means that memory corruption of all kinds are impossible. But Heap Corruption is a very broad category.
[deleted]
Can anyone explain what a zero-day vulnerability is? What's the difference between zero-day and non-zero-day vulnerabilities? I'm not getting much out of wikipedia.
A zero day vulnerability is one the manufacturer doesn’t know about or has had zero days of notice on (“zero days to fix”). An n-day vulnerability means the manufacturer has had that much time to deal with it before it goes public.
I believe this is the correct usage of the term, but it seems that articles now use it to mean any vulnerability of any kind regardless of disclosure/patch turnaround, which can add a lot of confusion when reading.
Wow, Chrome's security seems more and more like IE.. the number of bugs is just astonishing.
>On October 20, Google also released a security update for Chrome to patch CVE-2020-15999, a zero-day in Chrome's FreeType font rendering library.
>As Google revealed last week on Friday, this Chrome zero-day was utilized together with a Windows zero-day (CVE-2020-17087).
I thought Chrome only used DirectWrite font rendering on Windows, and only used dynamically linked system FreeType on Linux-like platforms. https://bugs.chromium.org/p/chromium/issues/detail?id=670480 shows that some people were discussing using FreeType on Windows, but it doesn't seem to have resulted in any actions.
>As Google revealed last week on Friday, this Chrome zero-day was utilized together with a Windows zero-day (CVE-2020-17087).
I thought Chrome only used DirectWrite font rendering on Windows, and only used dynamically linked system FreeType on Linux-like platforms. https://bugs.chromium.org/p/chromium/issues/detail?id=670480 shows that some people were discussing using FreeType on Windows, but it doesn't seem to have resulted in any actions.
I'm not sure what's better, keeping data in tabs but at risk, or involuntarily losing data to protect users.