Thursday, August 2, 2018

Adventures in vulnerability reporting

Posted by Natalie Silvanovich, Project Zero

At Project Zero, we spend a lot of time reporting security bugs to vendors. Most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time, this is a fairly straightforward process, but we occasionally encounter challenges getting information about vulnerabilities into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hands of vendors. Since it is important to user security that software vendors fix reported vulnerabilities in a timely matter, and vendors need to actually receive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 report for this to happen, we have decided to share some of our experiences. We hope to show that good practices by software vendors can avoid delays in vulnerability reporting.

Effective Vulnerability Reporting Processes
There are several aspects of a bug reporting process that make reporting vulnerabilities easier from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug reporter’s perspective. To start off, it’s important for a bug reporting process to be easy to find and use. We sometimes have difficulty figuring out how to report a vulnerability in a piece of software if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability reporting process is not documented on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 project or vendor’s website, or if outdated material is not removed and instructions for reporting vulnerabilities are inconsistent. This can lead to delays in reporting. Effective vulnerability reporting processes are clearly documented, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 documentation is easy to find.

We also appreciate when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process for reporting a vulnerability is short and straightforward. Occasionally, we report dozens of vulnerabilities in a vendor’s products, and it is helpful when reporting does not require a lot of clicks and reading. Reporting processes that use email or bug trackers are usually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 easiest, though webforms can be easy if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are not excessively long. While Project Zero will always report a vulnerability, even if reporting it is very time consuming, this is not necessarily cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case for ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r bug reporters. Long bug reporting processes can cause bug reporters to report bugs more slowly, spend less time working on a piece of software or even give up on reporting a bug. The easier a bug reporting process is, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more likely it is that someone will go through with it.

It’s also important for bug reporting processes to be well-tested. While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 majority we encounter are, we’ve occasionally had bug reporting email addresses bounce, webforms reject necessary information (like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporter’s name) and security issues go unnoticed in bug trackers for months despite following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 documented process. Vendors with good processes usually test that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir process and any systems it involves works correctly on a regular basis.

Mandatory legal agreements in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporting process are anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r problem that we encounter every so often. If a legal agreement contains language about disclosure or any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r subject we don’t feel comfortable entering an agreement about on behalf of our company, deciding whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r to enter cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 agreement can require a lengthy discussion, delaying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug report. While legal agreements are sometimes necessary for rewards programs and code contributions, good vulnerability reporting processes allow bug reporters to report bugs without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

It is also helpful when vendors confirm that vulnerability reports have been received in a timely manner. Since bug reports can get lost for a number of reasons, including bugs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporting interface and human error, it is a good idea to let reporters know that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir report has been received, even if it won’t be processed right away. This lets cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporter know that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y’ve reported cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug correctly, and don’t need to spend any more time reporting it, and makes it more likely that bug reporters will reach out if a bug report gets lost, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y will be expecting a confirmation.

Finally, even if good practices are followed in creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug reporting process, it is still possible that a bug reporting process has problems, so it is very helpful if vendors provide a way to give feedback on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process. It’s very rare for vendors to intentionally make bug reporting difficult, but unexpected problems happen fairly frequently, so it is good to provide a way bug reporters can reach out for help as a last resort if a reporting a bug fails for any reason.

Examples
One example of a bug we had difficulty reporting due to a vendor not following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 practices described above is CVE-2018-10751.  CVE-2018-10751 is a remote memory corruption vulnerability in OMACP affecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Samsung S7 Edge. The issue can be triggered by sending a single SMS to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target device, and does not require any user interaction. The payload can be sent from an app on an Android device without root access or any special equipment. It is similar to CVE-2016-7990, which is described in detail here.

Samsung’s Vulnerability Reporting Process
CVE-2018-10751 is a serious vulnerability, and I wanted to report it immediately. I started off by reading Samsung Mobile’s Security Reporting page. This page has a button to create a bug report.


Pressing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 button led to a sign-up page. I didn’t have a Samsung account, so I tried to sign up. Unfortunately, it led to this page:


Not speaking Korean, I wasn’t sure what to do here. I eventually went back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous page and tried cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ‘Sign-in’ button.

This brought me to an English sign-up page, which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n brought me to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 account creation page. According to this page, I had to read and agree to some terms. Clicking cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 links led to over twenty separate agreements, most of which had nothing to do with vulnerability reporting.
https://account.samsung.com Accessed February 22, 2018

That’s a lot of text to read and review. Let’s just say I skimmed a bit. Once I clicked ‘Agree’, I was taken to a page where I could enter account information. The page required my birthdate and zip code, which I wasn’t thrilled to have to provide to report a vulnerability, but I wanted to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue reported, so I entered cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. Finally, my account was created! I logged in, hoping to start reporting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug, only to be greeted with more conditions.

https://account.samsung.com Accessed February 22, 2018

These ones were in Korean, and I couldn’t figure out how to change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 language. Eventually, I just selected confirm. Finally, I got to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 form where I could report bugs!


I filled out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability information, and scrolled down, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was one more set of terms to agree to:

These terms included:

- You MUST hold off disclosing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability in reasonable time, and you MUST get Samsung’s  consent or inform Samsung about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 date before disclosing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability.
- In some cases, Samsung may request not to disclose cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability at all.

I was not able to submit this form without agreeing to allow Samsung some level of control over disclosure of reported vulnerability. I looked around Samsung’s security page to see if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y provided an email address I could report cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue to, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y did not provide one. I was not comfortable reporting this bug through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mechanisms Samsung provides for vulnerability reporting on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir website.

Problems with Vulnerability Reporting Processes

I encountered several problems while trying to report cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above vulnerability—most of which have been since resolved by Samsung.

To start off, Samsung’s bug reporting process did not seem adequately tested. The many times that Korean text showed up while attempting to report this vulnerability suggests that it was not tested in English. As described above, is important for vendors to test vulnerability reporting processes, including for internationalization issues. The workflow is also excessively long, and requires cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporter to agree to a very large number of agreements, many of which have nothing to do with vulnerability reports. I suspect that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 people testing this interface might have already had accounts, and not seen how long cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process is for someone who just wants to report a bug.

This isn’t an uncommon problem. The Android security reporting template requires creating a GMail account, which can require clicking through many screens and verification via SMS in some circumstances. As a result of our feedback, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android Security team has improved cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 documentation that vulnerability reports can be filed via email (security@android.com), although using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 web form is still required to participate in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android Security rewards program.

Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r problem was that in order to report a bug, a reporter had to agree to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 terms of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rewards program. This is an issue that Project Zero has been seeing increasingly often. When software vendors start rewards programs, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y often remove existing mechanisms for reporting vulnerabilities, leaving bug reporters with no way to report vulnerabilities without entering into agreements.

This also occurred when Tavis Ormandy attempted to report cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability he reluctantly dubbed CloudBleed. Cloudflare’s vulnerability reporting process is tied to its rewards program with HackerOne, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no clear way to report a vulnerability without creating a HackerOne account in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir Vulnerability Disclosure Policy. The policy even states “We agree with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir disclosure philosophy, and if you do too, please submit your vulnerability reports here” without providing an alternative for vulnerability reporters who don’t agree or don’t want to participate in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 program for whatever reason. In Project Zero’s case, our disclosure deadline is 90 days meanwhile HackerOne’s deadline is 180 days. This vulnerability was also very urgent as it was actively leaking user data onto cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Internet, and we didn’t want to delay reporting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue while we read through HackerOne’s terms to determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were compatible with our disclosure policy.

We find that vendors generally don’t intend to prevent bug reports from anyone who won’t agree to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir disclosure rules, but this was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end result of Samsung and Cloudflare replacing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir bug reporting process with a rewards program.

The specific terms of Samsung’s agreement were also fairly vague. In particular, it wasn’t clear what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 consequences of breaking cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 terms would be. For example:

- You MUST hold off disclosing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability in reasonable time, and you MUST get Samsung’s  consent or inform Samsung about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 date before disclosing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability.

Does this mean that if someone discloses a vulnerability without permission, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are not eligible for a reward? Does it mean that if someone discloses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability without permission, Samsung can take legal action against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m? While requiring that bug reporters not disclose vulnerabilities to receive rewards is a policy with debatable benefit, I would have been much more comfortable agreeing to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se terms if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y had spelled out that violating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m would simply mean I would not receive a reward, as opposed to ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r legal consequences.
Overall, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issues of poorly tested bug reporting interfaces and requiring legal agreements to report vulnerabilities have come up multiple times, and led to delays of Project Zero reporting vulnerabilities. We recommend that vendors test cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir vulnerability reporting interfaces from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 perspective of someone who’s never reported a bug from outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corporate network, and make sure to do localized testing. It is also important to allow bug reports without requiring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporter to enter into excessive legal agreements.

While only accepting vulnerability reports via web forms can reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of invalid reports, which is a major challenge for teams accepting vulnerability reports, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can also be unreliable and prevent vulnerability reporting in situations that were not expected by those designing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, unless cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are very well tested. Having an alternate email address that vulnerability reporters can use to report bugs if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y encounter problems is a good way to prevent this type of problem.

Reporting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Bug
I eventually contacted some members of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Knox security team at Samsung that I had worked with on previous bugs and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y recommended reporting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue to mobile.security@samsung.com. This email is not documented on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Samsung website, except for a single blog post from 2015.

The difficulty I encountered reporting this serious vulnerability delayed my report one week. It might have caused a longer delay if I did not have contacts at Samsung who could help.

Samsung started rolling out updates for CVE-2018-10751 (Samsung’s identifier SVE-2018-11463) in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir April maintenance release.

Samsung has updated cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir account creation page so that it always displays English text if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 language is set to English. Also, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability report form can now be submitted without agreeing to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 terms for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Samsung’s rewards program, though cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user still has to agree to two ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r agreements. They have also updated cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir bug reporting page to provide an email address as well as a webform. We appreciate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 changes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have made to make reporting vulnerabilities in Samsung products easier for everyone.

Conclusion
Project Zero has occasionally had difficulty reporting vulnerabilities, leading to delays in reporting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug. Usually, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se are due to problems in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reporting process that were not intended or expected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vendor. A difficult vulnerability reporting process can have a negative impact on user security due to delays in vulnerability reports, lost vulnerability reports and even bug reporters choosing not to report a vulnerability. We appreciate when vendors do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following to make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir bug reporting processes easier for bug reporters:

  • Vendors should regularly test cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir vulnerability reporting interfaces in all supported languages
  • Vendors should streamline cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir vulnerability reporting processing as much as possible, and remove excessive clicks and legal agreements
  • Vendors should regularly solicit feedback on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir vulnerability reporting mechanisms from vulnerability reporters and people cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y think are likely to report vulnerabilities

Thursday, July 26, 2018

Drawing Outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Box: Precision Issues in Graphic Libraries

By Mark Brand and Ivan Fratric, Google Project Zero

In this blog post, we are going to write about a seldom seen vulnerability class that typically affects graphic libraries (though it can also occur in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r types of software). The root cause of such issues is using limited precision arithmetic in cases where a precision error would invalidate security assumptions made by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application.

While we could also call ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r classes of bugs precision issues, namely integer overflows, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 major difference is: with integer overflows, we are dealing with arithmetic operations where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 magnitude of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is too large to be accurately represented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given precision. With cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issues described in this blog post, we are dealing with arithmetic operations where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 magnitude of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result or a part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is too small to be accurately represented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given precision.

These issues can occur when using floating-point arithmetic in operations where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is security-sensitive, but, as we’ll demonstrate later, can also occur in integer arithmetic in some cases.

Let’s look at a trivial example:

 float a = 100000000;
 float b = 1;
 float c = a + b;

If we were making cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 computation with arbitrary precision, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result would be 100000001. However, since float typically only allows for 24 bits of precision, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is actually going to be 100000000. If an application makes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 normally reasonable assumption that a > 0 and b > 0 implies that a + b > a, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n this could lead to issues.

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 example above, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 difference between a and b is so significant that b completely vanishes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 calculation, but precision errors also happen if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 difference is smaller, for example

 float a = 1000;
 float b = 1.1111111;
 float c = a + b;

The result of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above computation is going to be 1001.111084 and not 1001.1111111 which would be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 accurate result. Here, only a part of b is lost, but even such results can sometimes have interesting consequences.

While we used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 float type in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above examples, and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se particular examples using double would result in more accurate computation, similar precision errors can happen with double as well.

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remainder of this blog post, we are going to show several examples of precision issues with security impact. These issues were independently explored by two Project Zero members: Mark Brand, who looked at SwiftShader, a software OpenGL implementation used in Chrome, and Ivan Fratric, who looked at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Skia graphics library, used in Chrome and Firefox.

SwiftShader

SwiftShader is “a high-performance CPU-based implementation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OpenGL ES and Direct3D 9 graphics APIs”. It’s used in Chrome on all platforms as a fallback rendering option to work around limitations in graphics hardware or drivers, allowing universal use of WebGL and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r advanced javascript rendering APIs on a far wider range of devices.

The code in SwiftShader needs to handle emulating a wide range of operations that would normally be performed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GPU. One operation that we commonly think of as essentially “free” on a GPU is upscaling, or drawing from a small source texture to a larger area, for example on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screen. This requires computing memory indexes using non-integer values, which is where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability occurs.

As noted in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original bug report, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code that we’ll look at here is not quite cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code which is actually run in practice - SwiftShader uses an LLVM-based JIT engine to optimize performance-critical code at runtime, but that code is more difficult to understand than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir fallback implementation, and both contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same bug, so we’ll discuss cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fallback code. This code is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 copy-loop used to copy pixels from one surface to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r during rendering:

 source->lockInternal((int)sRect.x0, (int)sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
 dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);

 float w = sRect.width() / dRect.width();
 float h = sRect.height() / dRect.height();

 const float xStart = sRect.x0 + 0.5f * w;
 float y = sRect.y0 + 0.5f * h;
 float x = xStart;

 for(int j = dRect.y0; j < dRect.y1; j++)
 {
   x = xStart;

   for(int i = dRect.x0; i < dRect.x1; i++)
   {
     // FIXME: Support RGBA mask
     dest->copyInternal(source, i, j, x, y, options.filter);

     x += w;
   }

   y += h;
 }

 source->unlockInternal();
 dest->unlockInternal();
}

So - what highlights this code as problematic? We know prior to entering this function that all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds-checking has already been performed, and that any call to copyInternal with (i, j) in dRect and (x, y) in sRect will be safe.

The examples in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 introduction above show cases where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting precision error means that a rounding-down occurs - in this case that wouldn’t be enough to produce an interesting security bug. Can we cause floating-point imprecision to result in a larger-than-correct value, leading to (x, y) values that are larger than expected?

If we look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 intention of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 developers is to compute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:

 for(int j = dRect.y0; j < dRect.y1; j++)
 {
   for(int i = dRect.x0; i < dRect.x1; i++)
   {
     x = xStart + (i * w);
     Y = yStart + (j * h);
     dest->copyInternal(source, i, j, x, y, options.filter);
   }
 }

If this approach had been used instead, we’d still have precision errors - but without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iterative calculation, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’d be no propagation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error, and we could expect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eventual magnitude of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision error to be stable, and in direct proportion to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 operands. With cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iterative calculation as performed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 errors start to propagate/snowball into a larger and larger error.

There are ways to estimate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 maximum error in floating point calculations; and if you really, really need to avoid having extra bounds checks, using this kind of approach and making sure that you have conservative safety margins around those maximum errors might be a complicated and error-prone way to solve this issue. It’s not a great approach to identifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pathological values that we want here to demonstrate a vulnerability; so instead we’ll take a brute-force approach.

Instinctively, we’re fairly sure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 multiplicative implementation will be roughly correct, and that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation with iterative addition will be much less correct. Given that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 space of possible inputs is small (Chrome disallows textures with width or height greater than 8192), we can just run a brute force over all ratios of source width to destination width, comparing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two algorithms, and seeing where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results are most different. (Note that SwiftShader also limits us to even numbers). This leads us to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values of 5828, 8132; and if we compare cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 computations in this case (left side is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iterative addition, right side is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 multiplication):

0:    1.075012 1.075012
1:    1.791687 1.791687
...
1000: 717.749878 717.749878   Up to here (at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision shown) cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values are still identical
1001: 718.466553 718.466553
...
2046: 1467.391724 1467.391724 At this point, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first significant errors start to occur, but note
2047: 1468.108398 1468.108521 that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "incorrect" result is smaller than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more precise one.
...
2856: 2047.898315 2047.898438
2857: 2048.614990 2048.614990 Here our two computations coincide again, briefly, and from here onwards
2858: 2049.331787 2049.331787 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision errors consistently favour a larger result than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more
2859: 2050.048584 2050.048340 precise calculation.
...
8129: 5827.567871 5826.924805
8130: 5828.284668 5827.641602
8131: 5829.001465 5828.358398 The last index is now sufficiently different that int conversion results in an oob index.

(Note also that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re will also be error in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “safe” calculation; it’s just that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lack of error propagation means that that error will remain directly proportional to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input error, which we expect to be “small.”)

We can indeed see that, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 multiplicative algorithm would remain within bounds; but that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iterative algorithm can return an index that is outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input texture!

As a result, we read an entire row of pixels past cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of our texture allocation - and this can be easily leaked back to javascript using WebGL. Stay tuned for an upcoming blog post in which we’ll use this vulnerability togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r with anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r unrelated issue in SwiftShader to take control of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GPU process from javascript.

Skia

Skia is a graphics library used, among ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r places, in Chrome, Firefox and Android. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 web browsers it is used for example when drawing to a canvas HTML element using CanvasRenderingContext2D or when drawing SVG images. Skia is also used when drawing various ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r HTML elements, but canvas element and SVG images are more interesting from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security perspective because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y enable more direct control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects being drawn by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 graphic library.

The most complex type of object (and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore, most interesting from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security perspective) that Skia can draw is a path. A path is an object that consists of elements such as lines, but also more complex curves, in particular quadratic or cubic splines.

Due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way software drawing algorithms work in Skia, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision issues are very much possible and quite impactful when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y happen, typically leading to out-of-bounds writes.

To understand why cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se issues can happen, let’s assume you have an image in memory (represented as a buffer with size = width x height x color size). Normally, when drawing a pixel with coordinates (x, y) and color c, you would want to make sure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pixel actually falls within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 space of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image, specifically that 0 <= x < width and 0 <= y < height. Failing to check this could result in attempting to write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pixel outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocated buffer. In computer graphics, making sure that only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image region are being drawn is called clipping.

So, where is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem? Making a clip check for every pixel is expensive in terms of CPU cycles and Skia prides itself on speed. So, instead of making a clip check for every pixel, what Skia does is, it first makes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clip check on an entire object (e.g. line, path or any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r type of object being drawn). Depending on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clip check, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are three possible outcomes:

  1. The object is completely outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area: The drawing function doesn’t draw anything and returns immediately.

  1. The object is partially inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area: The drawing function proceeds with per-pixel clip enabled (usually by relying on SkRectClipBlitter).

  1. The entire object is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area: The drawing function draws directly into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 buffer without performing per-pixel clip checks.

The problematic scenario is c) where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clip check is performed only per-object and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more precise, per-pixel checks are disabled. This means, if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a precision issue somewhere between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-object clip check and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing of pixels and if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision issue causes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pixel coordinates to go outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area, this could result in a security vulnerability.

We can see per-object clip checks leading to dropping per-pixel checks in several places, for example:

  • In hair_path (function for drawing a path without filling), clip is initially set to null (which disables clip checks). The clip is only set if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path, rounded up and extended by 1 or 2 depending on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing options don’t fit in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area. Extending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path bounds by 1 seems like a pretty large safety margin, but it is actually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 least possible safe value because drawing objects with antialiasing on will sometimes result in drawing to nearby pixels.

  • In SkScan::FillPath (function for filling a path with antialiasing turned off), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path are first extended by kConservativeRoundBias and rounded to obtain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “conservative” path bounds. A SkScanClipper object is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n created for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current path. As we can see in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 definition of SkScanClipper, it will only use SkRectClipBlitter if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinates of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path bounds are outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area or if irPreClipped is true (which only happens when path coordinates are very large).

Similar patterns can be seen in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r drawing functions.

Before we take a closer look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issues, it is useful to quickly go over various number formats used by Skia:

  • SkScalar is a 32-bit floating point number

  • SkFDot6 is defined as an integer, but it is actually a fixed-point number with 26 bits to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 left and 6 bits to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 decimal point. For example, SkFDot6 value of 0x00000001 represents cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number 1/64.

  • SkFixed is also a fixed-point number, this time with 16 bits to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 left and 16 bits to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 decimal point. For example, SkFixed value of 0x00000001 represents 1/(2**16)

Precision error with integer to float conversion

We discovered cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial problem when doing DOM fuzzing against Firefox last year. This issue where Skia wrote out-of-bounds caught our eye so we investigated furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. It turned out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root cause was a discrepancy in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way Skia converted floating point to ints in several places. When making cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-path clip check, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower coordinates (left and top of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounding box) were rounded using this function:

static inline int round_down_to_int(SkScalar x) {
   double xx = x;
   xx -= 0.5;
   return (int)ceil(xx);
}

Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code you see that it will return a number greater or equal to zero (which is necessary for passing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path-level clip check) for numbers that are strictly larger than -0.5. However, in anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code, specifically SkEdge::setLine if SK_RASTERIZE_EVEN_ROUNDING is defined (which is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case in Firefox), floats are rounded to integers differently, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following function:

inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0)
{
   union {
       double fDouble;
       int32_t fBits[2];
   } tmp;
   int fractionalBits = 6 + shift;
   double magic = (1LL << (52 - (fractionalBits))) * 1.5;

   tmp.fDouble = SkScalarToDouble(x) + magic;
#ifdef SK_CPU_BENDIAN
   return tmp.fBits[1];
#else
   return tmp.fBits[0];
#endif
}

Now let’s take a look at what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se two functions return for a number -0.499. For this number, round_down_to_int returns 0 (which always passes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clipping check) and SkScalarRoundToFDot6 returns -32 which corresponds to -0.5, so we actually end up with a number that is smaller than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one we started with.

That’s not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only problem, though, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r place where a precision error occurs in SkEdge::setLine.

Precision error when multiplying fractions

SkEdge::setLine calls SkFixedMul which is defined as:

static inline SkFixed(SkFixed a, SkFixed b) {
   return (SkFixed)((int64_t)a * b >> 16);
}

This function is for multiplying two SkFixed numbers. An issue comes up when using this function to multiply negative numbers. Let’s look at a small example. Let’s assume a = -1/(2**16) and b = 1/(2**16). If we multiply cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se two numbers on paper, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is -1/(2**32). However, due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way SkFixedMul works, specifically because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right shift is used to convert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result back to SkFixed format, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result we actually end up with is 0xFFFFFFFF which is SkFixed for  -1/(2**16). Thus, we end up with a result with a magnitude much larger than expected.

As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of this multiplication is used by SkEdge::setLine to adjust cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinate of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial line point here, we can use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue in SkFixedMul to cause an additional error up to 1/64 of a pixel to go outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area bounds.

By combining cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous two issues, it was possible to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinate of a line sufficiently small (smaller than -0.5), so that, when a fractional representation was rounded to an integer here, Skia attempted to draw at coordinates with x = -1, which is clearly outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image bounds. This cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n led to an out-of-bounds write as can be seen in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original bug report. This bug could be exploited in Firefox by drawing an SVG image with coordinates as described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous section.

Floating point precision error when converting splines to line segments

When drawing paths, Skia is going to convert all non-linear curves (conic shapes, quadratic and cubic splines) to line segments. Perhaps unsurprisingly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se conversions suffer from precision errors.

The conversion of splines into line segments happen in several places, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most susceptible to floating-point precision errors are hair_quad (used for drawing quadratic curves) and hair_cubic (used for drawing cubic curves). Both of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se functions are called from hair_path, which we already mentioned above. Because (unsurprisingly), larger precision errors occur when dealing with cubic splines, we’ll only consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cubic case here.

When approximating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spline, first cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cubic coefficients are computed in SkCubicCoeff. The most interesting part is:

fA = P3 + three * (P1 - P2) - P0;
fB = three * (P2 - times_2(P1) + P0);
fC = three * (P1 - P0);
fD = P0;

Where P1, P2 and P3 are input points and fA, fB, fC and fD are output coefficients. The line segment points are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n computed in hair_cubic using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code

const Sk2s dt(SK_Scalar1 / lines);
Sk2s t(0);

...

Sk2s A = coeff.fA;
Sk2s B = coeff.fB;
Sk2s C = coeff.fC;
Sk2s D = coeff.fD;
for (int i = 1; i < lines; ++i) {
   t = t + dt;
   Sk2s p = ((A * t + B) * t + C) * t + D;
   p.store(&tmp[i]);
}

Where p is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output point and lines is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of line segments we are using to approximate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve. Depending on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spline, a cubic spline can be approximated with up to 512 lines.

It is obvious that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 arithmetic here is not going to be precise. As identical computations happen for x and y coordinates, let’s just consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinate in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 post.

Let’s assume cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area is 1000 pixels. Because hair_path is used for drawing path with antialiasing turned on, it needs to make sure that all points of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path are between 1 and 999, which is done in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial, path-level clip check. Let’s consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following coordinates that all pass this check:

p0 = 1.501923
p1 = 998.468811
p2 = 998.998779
p3 = 999.000000

For cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se points, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 coefficients are as follows

a = 995.908203
b = -2989.310547
c = 2990.900879
d = 1.501923

If you do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same computation in larger precision, you’re going to notice that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 numbers here aren’t quite correct. Now let’s see what happens if we approximate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spline with 512 line segments. This results in 513 x coordinates:

0: 1.501923
1: 7.332130
2: 13.139574
3: 18.924301
4: 24.686356
5: 30.425781
...
500: 998.986389
501: 998.989563
502: 998.992126
503: 998.994141
504: 998.995972
505: 998.997314
506: 998.998291
507: 998.999084
508: 998.999695
509: 998.999878
510: 999.000000
511: 999.000244
512: 999.000000

We can see that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinate keeps growing and at point 511 clearly goes outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “safe” area and grows larger than 999.

As it happens, this isn’t sufficient to trigger an out-of-bounds write, because, due to how drawing antialiased lines works in Skia, we need to go at least 1/64 of a pixel outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clip area for it to become a security issue. However, an interesting thing about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision errors in this case is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 larger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 larger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error that can happen.

So let’s instead consider a drawing area of 32767 pixels (maximum canvas size in Chrome). The initial clipping check cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n checks that all path points are in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interval [1, 32766]. Now let’s consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following points:

p0 = 1.7490234375
p1 = 32765.9902343750
p2 = 32766.000000
p3 = 32766.000000

The corresponding coefficients

a = 32764.222656
b = -98292.687500
c = 98292.726562
d = 1.749023

And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding line approximation

0: 1.74902343
1: 193.352295
2: 384.207123
3: 574.314941
4: 763.677246
5: 952.295532
505: 32765.925781
506: 32765.957031
507: 32765.976562
508: 32765.992188
509: 32766.003906
510: 32766.003906
511: 32766.015625
512: 32766.000000

You can see that we went out-of-bounds significantly more at index 511.

Fortunately for Skia and unfortunately for aspiring attackers, this bug can’t be used to trigger memory corruption, at least not in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 up-to-date version of skia. The reason is SkDrawTiler. Whenever Skia draws using SkBitmapDevice (as opposed to using a GPU device) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing area is larger than 8191 pixels in any dimension, instead of drawing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whole image at once, Skia is going to split it into tiles of size (at most) 8191x8191 pixels. This change was made in March, not for security reasons, but to be able to support larger drawing surfaces. However, it still effectively prevented us from exploiting this issue and will also prevent exploiting ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cases where a surface larger than 8191 is required to reach cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision error of a sufficient magnitude.

Still, this bug was exploitable before March and we think it nicely demonstrates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 concept of precision errors.

Integer precision error when converting splines to line segments

There is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r place where splines are approximated as line segments when drawing (in this case: filling) paths that was also affected by a precision error, in this case an exploitable one. Interestingly, here cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision error wasn’t in floating-point but racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r in fixed-point arithmetic.

The error happens in SkQuadraticEdge::setQuadraticWithoutUpdate and SkCubicEdge::setCubicWithoutUpdate. For simplicity, we are again going to concentrate just on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cubic spline version and, again, only on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x coordinate.

In SkCubicEdge::setCubicWithoutUpdate, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve coordinates are first converted to SkFDot6 type (integer with 6 bits used for fraction). After that, parameters corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first, second and third derivative of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial point are going to be computed:

SkFixed B = SkFDot6UpShift(3 * (x1 - x0), upShift);
SkFixed C = SkFDot6UpShift(3 * (x0 - x1 - x1 + x2), upShift);
SkFixed D = SkFDot6UpShift(x3 + 3 * (x1 - x2) - x0, upShift);

fCx     = SkFDot6ToFixed(x0);
fCDx    = B + (C >> shift) + (D >> 2*shift);    // biased by shift
fCDDx   = 2*C + (3*D >> (shift - 1));           // biased by 2*shift
fCDDDx  = 3*D >> (shift - 1);                   // biased by 2*shift

Where x0, x1, x2 and x3 are x coordinates of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 4 points that define cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cubic spline and shift and upShift depend on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve (this corresponds to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of linear segments cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve is going to be approximated in). For simplicity, we can assume shift = upShift = 6 (maximum possible values).

Now let’s see what happens for some very simple input values:

x0 = -30
x1 = -31
x2 = -31
x3 = -31

Note that x0, x1, x2 and x3 are of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 type SkFDot6 so value -30 corresponds to -0.46875 and -31 to -0.484375. These are close to -0.5 but not quite and are thus perfectly safe when rounded. Now let’s examine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 computed parameters:

B = -192
C = 192
D = -64

fCx = -30720
fCDx = -190
fCDDx = 378
fCDDDx = -6

Do you see where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue is? Hint: it’s in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 formula for fCDx.

When computing fCDx (first derivation of a curve), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of D needs is right-shifted by 12. However, D is too small to do that precisely, and since D is negative, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right shift

D >> 2*shift

Is going to result in -1, which is larger in magnitude than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 intended result. (Since D is of type SkFixed its actual value is -0.0009765625 and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shift, when interpreted as division by 4096, would result in -2.384185e-07). Because of this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whole fCDx ends up as a larger negative value than it should (-190 vs. -189.015).

Afterwards, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of fCDx gets used when calculating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x value of line segments. This happens in SkCubicEdge::updateCubic on this line:

newx    = oldx + (fCDx >> dshift);

The x values, when approximating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spline with 64 line segments (maximum for this algorithm), are going to be (expressed as index, integer SkFixed value and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding floating point value):

index raw      interpretation
0:    -30720   -0.46875
1:    -30768   -0.469482
2:    -30815   -0.470200
3:    -30860   -0.470886
4:    -30904   -0.471558
5:    -30947   -0.472214
...
31:   -31683   -0.483444
32:   -31700   -0.483704
33:   -31716   -0.483948
34:   -31732   -0.484192
35:   -31747   -0.484421
36:   -31762   -0.484650
37:   -31776   -0.484863
38:   -31790   -0.485077
...
60:   -32005   -0.488358
61:   -32013   -0.488480
62:   -32021   -0.488602
63:   -32029   -0.488724
64:   -32037   -0.488846

You can see that for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 35th point, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 x value (-0.484421) ends up being smaller than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 smallest input point (-0.484375) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trend continues for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 later points. This value would still get rounded to 0 though, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r problem.

The x values computed in SkCubicEdge::updateCubic are passed to SkEdge::updateLine, where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are converted from SkFixed type to SkFDot6 on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following lines:

x0 >>= 10;
x1 >>= 10;

Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r right shift! And when, for example, SkFixed value -31747 gets shifted we end up with SkFDot6 value of -32 which represents -0.5.

At this point we can use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same trick described above in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “Precision error when multiplying fractions” section to go smaller than -0.5 and break out of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image bounds. In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, we can make Skia draw to x = -1 when drawing a path.

But, what can we do with it?

In general, given that Skia allocates image pixels as a single allocation that is organized row by row (as most ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r software would allocate bitmaps), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are several cases of what can happen with precision issues. If we assume an width x height image and that we are only able to go one pixel out of bounds:

  1. Drawing to y = -1 or y = height immediately leads to heap out-of-bounds write
  2. Drawing to x = -1 with y = 0 immediately leads to a heap underflow of 1 pixel
  3. Drawing to x = width with y = height - 1 immediately leads to heap overflow of 1 pixel
  4. Drawing to x = -1 with y > 0 leads to a pixel “spilling” to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous image row
  5. Drawing to x = height with y < height-1 leads to a pixel “spilling” to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next image row

What we have here is scenario d) - unfortunately we can’t draw to x = 1 with y = 0 because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision error needs to accumulate over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 growing values of y.

Let’s take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following example SVG image:


If we render this in an unpatched version of Firefox what we see is shown in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following image. Notice how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SVG only contains coordinates on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 left side of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screen, but some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 red pixels get drawn on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right. This is because, due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way images are allocated, drawing to x = -1 and y = row is equal to drawing to x = width - 1 and y = row - 1.


Opening an SVG image that triggers a Skia precision issue in Firefox. If you look closely you’ll notice some red pixels on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right side of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image. How did those get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re? :)

Note that we used Mozilla Firefox and not Google Chrome because, due to SVG drawing internals (specifically: Skia seems to draw cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire image at once, while Chrome uses additional tiling) it is easier to demonstrate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue in Firefox. However, both Chrome and Firefox were equally affected by this issue.

But, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than drawing a funny image, is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re real security impact to this issue? Here, SkARGB32_Shader_Blitter comes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rescue (SkARGB32_Shader_Blitter is used whenever shader effects are applied to a color in Skia). What is specific about SkARGB32_Shader_Blitter is that it allocates a temporary buffer of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same size as a single image row. When SkARGB32_Shader_Blitter::blitH is used to draw an entire image row, if we can make it draw from x = -1 to x = width - 1 (alternately from x = 0 to x = width), it will need to write width + 1 pixels into a buffer that can only hold width pixels, leading to a buffer overflow as can be seen in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ASan log in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug report.

Note how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoCs for Chrome and Firefox contain SVG images with a linearGradient element - cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 linear gradient is used specifically to select SkARGB32_Shader_Blitter instead of drawing pixels to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image directly, which would only result in pixels spilling to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous row.

Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r specific of this issue is that it can only be reached when drawing (more specifically: filling) paths with antialiasing turned off. As it is not currently possible to draw paths to a HTML canvas elements with antialiasing off (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is an imageSmoothingEnabled property but it only applies to drawing images, not paths), an SVG image with shape-rendering="crispEdges" must be used to trigger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue.

All precision issues we reported in Skia were fixed by increasing kConservativeRoundBias. While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current bias value is large enough to cover cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 maximum precision errors we know about, we should not dismiss cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 possibility of ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r places where precision issues can occur.

Conclusion

While precision issues, such as described in this blog post, won’t be present in most software products, where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are present cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can have quite serious consequences. To prevent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m from occurring:

  • Don’t use floating-point arithmetic in cases where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is security-sensitive. If you absolutely have to, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you need to make sure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 maximum possible precision error cannot be larger than some safety margin. Potentially, interval arithmetic could be used to determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 maximum precision error in some cases. Alternately, perform security checks on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than input.

  • With integer arithmetic, be wary of any operations that can reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precision of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result, such as divisions and right shifts.

When it comes to finding such issues, unfortunately, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re doesn’t seem to be a great way to do it. When we started looking at Skia, initially we wanted to try using symbolic execution on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 drawing algorithms to find input values that would lead to drawing out-of-bounds, as, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 surface, it seemed this is a problem symbolic execution would be well suited for. However, in practice, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re were too many issues: most tools don’t support floating point symbolic variables and, even when running against just cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 integer parts of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simplest line drawing algorithm, we were unsuccessful in completing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 run in a reasonable time (we were using KLEE with STP and Z3 backends).

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end, what we ended up doing was a combination of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more old-school methods: manual source review, fuzzing (especially with values close to image boundaries) and, in some cases, when we already identified potentially problematic areas of code, even bruteforcing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range of all possible values.

Do you know of ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r instances where precision errors resulted in security issues? Let us know about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 comments.