Jump to page: 1 211  
Page
Thread overview
Typical security issues in C++: why the GC isn't your enemy
Dec 05, 2022
H. S. Teoh
Dec 05, 2022
Sergey
Dec 06, 2022
Alexandru Ermicioi
Jan 22, 2023
Sergey
Dec 05, 2022
Timon Gehr
Dec 06, 2022
drug007
Dec 06, 2022
Arjan
Dec 06, 2022
deadalnix
Dec 08, 2022
Walter Bright
Dec 08, 2022
Zealot
Dec 09, 2022
Walter Bright
Dec 09, 2022
deadalnix
Dec 09, 2022
Walter Bright
Dec 09, 2022
deadalnix
Dec 12, 2022
Walter Bright
Dec 06, 2022
Timon Gehr
Dec 08, 2022
Walter Bright
Dec 08, 2022
Timon Gehr
Dec 09, 2022
Dom DiSc
Dec 09, 2022
Timon Gehr
Dec 09, 2022
Walter Bright
Feb 13, 2023
Quirin Schroll
Dec 06, 2022
Iain Buclaw
Dec 06, 2022
Timon Gehr
Dec 08, 2022
Walter Bright
Dec 08, 2022
Walter Bright
Dec 09, 2022
Timon Gehr
Dec 06, 2022
Tejas
Dec 06, 2022
Commander Zot
Dec 09, 2022
Walter Bright
Dec 06, 2022
Siarhei Siamashka
Dec 06, 2022
Iain Buclaw
Dec 06, 2022
Sergey
Dec 07, 2022
Siarhei Siamashka
Dec 09, 2022
Walter Bright
Dec 09, 2022
Siarhei Siamashka
Dec 09, 2022
Walter Bright
Dec 09, 2022
Adam D Ruppe
Dec 09, 2022
bauss
Dec 09, 2022
Walter Bright
Dec 09, 2022
H. S. Teoh
Dec 12, 2022
Walter Bright
Dec 12, 2022
youSureAboutThat
Dec 12, 2022
Siarhei Siamashka
Dec 12, 2022
Nick Treleaven
Dec 12, 2022
Siarhei Siamashka
Dec 15, 2022
Nick Treleaven
Dec 12, 2022
Nick Treleaven
Dec 12, 2022
Siarhei Siamashka
Dec 12, 2022
Nick Treleaven
Dec 12, 2022
Timon Gehr
Dec 13, 2022
Siarhei Siamashka
Dec 14, 2022
Dukc
Dec 14, 2022
Siarhei Siamashka
Dec 15, 2022
Dom DiSc
Jan 22, 2023
Timon Gehr
Jan 22, 2023
Dom Disc
Jan 23, 2023
Siarhei Siamashka
Jan 23, 2023
Dom DiSc
Jan 23, 2023
RTM
Jan 23, 2023
Timon Gehr
Jan 23, 2023
Walter Bright
Dec 13, 2022
Siarhei Siamashka
Dec 14, 2022
Siarhei Siamashka
Dec 14, 2022
Siarhei Siamashka
Dec 15, 2022
norm
Dec 15, 2022
H. S. Teoh
Dec 15, 2022
H. S. Teoh
Dec 15, 2022
Siarhei Siamashka
Dec 15, 2022
rikki cattermole
Dec 15, 2022
H. S. Teoh
Apr 28, 2023
Was
Dec 15, 2022
Dom DiSc
Dec 15, 2022
Dom DiSc
Dec 12, 2022
Adam D Ruppe
Dec 12, 2022
youSureAboutThat
Dec 12, 2022
youSureAboutThat
Dec 12, 2022
youSureAboutThat
Dec 12, 2022
Nick Treleaven
Dec 12, 2022
Basile B.
Dec 12, 2022
Basile B.
Dec 12, 2022
Basile B.
Dec 12, 2022
Adam D Ruppe
Dec 12, 2022
Siarhei Siamashka
Dec 12, 2022
Dukc
Dec 12, 2022
Siarhei Siamashka
Dec 08, 2022
Walter Bright
Dec 09, 2022
Max Samukha
Dec 09, 2022
Max Samukha
Dec 09, 2022
Walter Bright
Dec 09, 2022
Walter Bright
Dec 08, 2022
Walter Bright
Re: Typical security issues in C++: lifetime
Dec 08, 2022
Walter Bright
December 05, 2022
In the past, I've posted about my impressions of coding issues encountered in a large C codebase (approx 2M LOC), as found by Coverity. My impression was that there was a large predominance of bugs related to memory management and raw pointers.  However, I didn't have actual data to back up my memory.  So I decided to do a slightly more evidence-based analysis by doing a little informal analysis of the following list of CVE issues in the Chromium browser, a commonly-used browser, from the Debian/Linux security tracker page:

	https://security-tracker.debian.org/tracker/source-package/chromium

There are 1239 issues listed on this page, with several frequently- recurring keywords / key phrases, that one could argue represents the most commonly encountered issues in a typical large C++ codebase. Here are some of keywords of interest with their counts:

Use after free:				423	(34%)
Insufficient policy enforcement:	159	(13%)
Inappropriate implementation:		149	(12%)
Buffer overflow:			98	(8%)
Data validation:			91	(7%)
Out of bounds access/read/write/etc:	71	(6%)
Type confusion (JS):			48	(4%)
Incorrect security UI:			33	(3%)
Integer overflow:			22	(2%)
Object lifecycle/lifetime:		15	(1%)
Uninitialized data/use:			14	(1%)
Information leak:			14	(1%)
Side-channel:				7	(<1%)
Handling of confusable characters:	7	(<1%)
Data race:				7	(<1%)
Double free:				3	(<1%)


Most interesting point here is that the largest category of bugs is use-after-free bugs, constituting 34% of the reported issues.  (Arguably we should include "object lifecycle/lifetime" in this category, but I think those refer to bugs in the JS implementation. In any case, it doesn't change the conclusion.)  This is strong evidence that memory management is a major source of bugs, and a strong argument for GC use in application code.

The next largest categories are insufficient policy enforcement and inappropriate implementation (it's unclear what exactly the latter means, at a glance it looks like various issues with JS and various browser features).  I contend that these two categories could be lumped together as application / business logic bugs.  Tellingly, these add up to 25%, overshadowed by use-after-free bugs.

D's bounds checks are often touted as a major feature to prevent issues with buffer overflow and out-of-bounds accesses.  Interestingly, "buffer overflow" and "out of bounds..." add up only to about 14% of the total issues.  Nothing to sneeze at, but nonetheless not as big an issue as use-after-free bugs.

Integer overflow is also sometimes brought up as something important; but at least according to the above categorization it only accounts for 2% of issues.  So not as big a deal as some may have made it sound.

Similarly, D's initialized-by-default variables are often touted as a big thing, but overall issues with uninitialized variables only constitute about 1% of the total issues.

I included also a few categories with small counts that are nonetheless interesting: side-channel attacks, which in recent years have been making noise in security circles, seem not as common as one might think (<1% of total issues).  Also interesting is the "confusable character" category: apparently this is increasingly being recognized as an issue in today's climate of spoofers and online swindling. But it's still only a rather minor category of issues.  Data races are also only a small category, at least as far as Chromium is concerned.

Most interestingly, "double free" only has 3 counts of the total, less than 1%, compared with "use after free", which constitute the largest category of issues.  This seems to suggest that it's not memory management in general that's necessarily problematic, but it's keeping track of the *lifetime* of allocated memory.  One could say that this is proof that lifetime is a complex problem. But again it's a strong argument that the GC brings a major benefit: it relieves the programmer from having to worry about lifetime issues.  You can instantly be freed from 34% of security issues, if the above numbers are anything to go by. :-P


T

-- 
If Java had true garbage collection, most programs would delete themselves upon execution. -- Robert Sewell
December 05, 2022
On Monday, 5 December 2022 at 19:57:39 UTC, H. S. Teoh wrote:
> but it's keeping track of the *lifetime* of allocated memory.  One could say that this is proof that lifetime is a complex problem. But again it's a strong argument that the GC brings a major benefit: it relieves

Thank you for interesting statistics and analysis. Unfortunately it seems that the IT community (biggest companies with largest code bases) stick with borrow-checker lifetime approach to solve those issues and not on GC.
December 06, 2022
On 12/5/22 20:57, H. S. Teoh wrote:
> Similarly, D's initialized-by-default variables are often touted as a
> big thing, but overall issues with uninitialized variables only
> constitute about 1% of the total issues.

Default initialization does not even fix all initialization issues, it just makes them reproducible. Anyway, I think neither default initialization nor uninitialized variables are the right solution, but you kind of have to do it this way given how scoping works in C++ and in D.
December 06, 2022
On Monday, 5 December 2022 at 20:28:42 UTC, Sergey wrote:
> On Monday, 5 December 2022 at 19:57:39 UTC, H. S. Teoh wrote:
>> but it's keeping track of the *lifetime* of allocated memory.  One could say that this is proof that lifetime is a complex problem. But again it's a strong argument that the GC brings a major benefit: it relieves
>
> Thank you for interesting statistics and analysis. Unfortunately it seems that the IT community (biggest companies with largest code bases) stick with borrow-checker lifetime approach to solve those issues and not on GC.

I think you haven't explored quite entire domain IT is. Just check java, C#, or any other GC language, I'm pretty sure you'd find employment positions for them, and quite a lot.

Best regards,
Alexandru.
December 06, 2022

On Monday, 5 December 2022 at 19:57:39 UTC, H. S. Teoh wrote:

>

In the past, I've posted about my impressions of coding issues encountered in a large C codebase (approx 2M LOC), as found by Coverity. My impression was that there was a large predominance of bugs related to memory management and raw pointers. However, I didn't have actual data to back up my memory. So I decided to do a slightly more evidence-based analysis by doing a little informal analysis of the following list of CVE issues in the Chromium browser, a commonly-used browser, from the Debian/Linux security tracker page:

[...]

People will resort have to resort to @nogc stuff when writing performance critical code anyways, so the protection from D's GC will go away in those cases; and Chrome engineers aren't the kind of folk who will find the Rust learning curve to be steep.

It will most likely be a competition between Rust and Carbon, as far as Chrome's future is concerned, and that is even assuming that they're interested in changing languages

December 06, 2022

On Monday, 5 December 2022 at 19:57:39 UTC, H. S. Teoh wrote:

>

D's bounds checks are often touted as a major feature to prevent issues with buffer overflow and out-of-bounds accesses. Interestingly, "buffer overflow" and "out of bounds..." add up only to about 14% of the total issues. Nothing to sneeze at, but nonetheless not as big an issue as use-after-free bugs.

This doesn't mean that there are fewer "out of bounds" bugs in general. But they are less likely to become exploitable security vulnerabilities. The "use after free" bugs are relatively easily to exploit:

  1. The old buffer is freed.
  2. This part of memory is later allocated for storing some security sensitive information.
  3. Access via the old pointer results in leaking the sensitive information.

GC surely helps to mitigate the security aspect of this. But the bug in the application logic may still be there and only manifest itself as a memory leak (if the application still keeps a pointer to the data that is not supposed to be used anymore). A good coding practice in C/C++ is to explicitly set a pointer to NULL immediately after deallocating memory.

>

Integer overflow is also sometimes brought up as something important; but at least according to the above categorization it only accounts for 2% of issues. So not as big a deal as some may have made it sound.

First, not every bug easily results in an exploitable security vulnerability. It's the same as with the "buffer overflow" vs. "use after free" case. And more importantly, C/C++ compilers are just safer than D compilers when it comes to integer overflows detection. Chromium developers are actively using UBSAN, which even allows detecting unsigned integer overflows:

-fsanitize=unsigned-integer-overflow: Unsigned integer overflow, where the result
of an unsigned integer computation cannot be represented in its type. Unlike signed
integer overflow, this is not undefined behavior, but it is often unintentional.

You can grep Chromium source code for no_sanitize or even __attribute__((no_sanitize("unsigned-integer-overflow"))) if you don't believe me.

Many of the integer overflow bugs are caught by the C++ compiler via UBSAN during the development and never reach the end users. While D compilers don't offer any reasonable protection. Except for GDC, which supports -ftrapv option as an undocumented "Easter egg".

December 06, 2022
06.12.2022 02:58, Timon Gehr пишет:
> Anyway, I think neither default initialization nor uninitialized variables are the right solution

What is the right solution in your opinion?

December 06, 2022
On Monday, 5 December 2022 at 23:58:58 UTC, Timon Gehr wrote:
> On 12/5/22 20:57, H. S. Teoh wrote:
> Default initialization does not even fix all initialization issues, it just makes them reproducible. Anyway, I think neither default initialization nor uninitialized variables are the right solution, but you kind of have to do it this way given how scoping works in C++ and in D.

Now I'm curious, what, in you opinion, would be best for initialization?
How is C++/D scoping limiting in this?

December 06, 2022

On Tuesday, 6 December 2022 at 03:13:41 UTC, Tejas wrote:

>

On Monday, 5 December 2022 at 19:57:39 UTC, H. S. Teoh wrote:

>

People will resort have to resort to @nogc stuff when writing performance critical code anyways, so the protection from D's GC will go away in those cases; and Chrome engineers aren't the kind of folk who will find the Rust learning curve to be steep.

This is just wrong. if you have performance critical code, you won't allocate in it. so you can just slap @nogc on it without problems.
the rest of your code can still use the gc just fine.

December 06, 2022

On Tuesday, 6 December 2022 at 04:35:18 UTC, Siarhei Siamashka wrote:

>

Many of the integer overflow bugs are caught by the C++ compiler via UBSAN during the development and never reach the end users. While D compilers don't offer any reasonable protection. Except for GDC, which supports -ftrapv option as an undocumented "Easter egg".

It isn't undocumented, and it certainly isn't an easter egg. All GCC optimization and code generation options are common to all front-end languages (C/C++/D/Fortran/Go/Rust/...)

It's mentioned right there in the first sentence, and the documentation for -ftrapv is just two page links away.

The default behaviour is -fwrapv because that is what the D spec asks for (also mentioned in the spec for binary+, binary- and binary* operators specifically).

« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11