Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add GCC option for checking virtual table pointers #440

Closed
wants to merge 0 commits into from

Conversation

Flo4152
Copy link

@Flo4152 Flo4152 commented Mar 28, 2024

GCC offers an option to add virtual table pointer verification at runtime (-fvtable-verify).

@thomasnyman
Copy link
Contributor

Hi @Flo4152 and thank you for your contribution. The OpenSSF Charter requires all contributions to be accompanied by a Developer Certificate of Origin (DCO) sign-off in the commit message that certifies the contribution is made according to the stipulations of the Linux Foundation DCO. Could you please read the DCO at the above link, and if you are able and willing to certify that the DCO requirements are met, amend the commit message with your sign-off.

@@ -205,6 +205,7 @@ Table 2: Recommended compiler options that enable run-time protection mechanisms
| [`-fno-strict-overflow`](#-fno-strict-overflow) | GCC 4.2 | Integer overflow may occur |
| [`-fno-strict-aliasing`](#-fno-strict-aliasing) | GCC 2.95.3<br/>Clang 18.0.0 | Do not assume strict aliasing |
| [`-ftrivial-auto-var-init`](#-ftrivial-auto-var-init) | GCC 12<br/>Clang 8.0 | Perform trivial auto variable initialization |
| [`-fvtable-verify=std`](#-fvtable-verify) | GCC 4.9.4 | Enable run-time checks for virtual function pointers corruption (C++). Can impact performance. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested rewording:

Enable run-time type checks for C++ virtual function pointers. Can impact performance.

  • Would move C++ to the description from the parenthesis to be consistent with the wording for -D_GLIBCXX_ASSERTIONS
  • The GCC documentation specifes the check is validates the vtable pointer is correct for the type of object. It would be good to represent that in the short description.

@@ -864,6 +865,28 @@ https://godbolt.org/z/6qTPz9n6h

---

### Vtable pointers check
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the first sentence of short description from Table 2 as title here to be consistent with the other option descriptions.


| Compiler Flag | Supported since | Description |
|:--------------------------------------------------------------------|:-------------------:|:---------------------------------------------|
| <span id="-fvtable-verify">`-fvtable-verify`</span> | GCC 4.9.4 | Enable run-time checks for virtual function pointers corruption (C++). Can impact performance. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've generally tried to ensure that the options is depicted in the various tables it appears in is in a form where the option can be copy-pasted as is into a compiler command line.

Since -fvtable-verify needs one of the std, preinit or none arguments, it would be better to include those variants in the correct calling form in this table, with the recommended argument first in the list.

Also, rather than repeating the "Can impact performance" here, it would be better to have a separate "Performance implications" subsection with a more detailed description of what factors impact the performance degradation, as you note in the associated issue. (But shouldn't the performance impact scale with the number of virtual methods calls though, not the number of class methods?).

Any references to benchmarks or documented cases performance degradation to get an idea of the scale here would be great.

Reading the option description in GCC implies that the std variant would already be the default. Is that the case? If so, then any performance impact of the the run-time check would already be part of the baseline performance.


#### Synopsis

In object-oriented programming, object methods rely on dynamic dispatching to select the right virtual function to call at runtime. The vtable is the table of virtual function pointers linked to the code of the virtual function to be executed. The vtable can be overwritten by memory corruption. This option enables vtable checking at runtime for each virtual function calls. This check prevents virtual function pointers from being corrupted or overwritten, and stops the application if the pointer integrity check fails. This virtual table pointer check is based on the data structure built at application start-up.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vtable can be overwritten by memory corruption.

This could name "vtable hijacking" explicitly as that is a well-established name for this particular type of attack.

This option enables vtable checking at runtime for each virtual function calls.

Typo: "each virtual call" (singular)

and stops the application if the pointer integrity check fails

Is this a SIGABRT as in the case for the stack protector functionality?

Copy link
Author

@Flo4152 Flo4152 Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The process termination that failed vtable pointer verification from vtv feature rely on __fortify_fail() function from libc to print error message (stack trace and memory map dump), then a explicit call to abort() is done. This call to abort() generate a SIGABRT signal. (https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libvtv/vtv_fail.cc#l169)

This option has three choices:

- `std` - vtable checks based on data structure built after shared libraries have been loaded and initialized
- `preinit` - vtable checks based on data structure built before shared libraries have been loaded and initialized
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the tradeoff between std and preinit and why would one choose one over the other?

<!-- More information
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fvtable-verify
-->

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When not to use?

@david-a-wheeler
Copy link
Contributor

I'm very concerned about the performance impact:
#341

@david-a-wheeler
Copy link
Contributor

I'm worried if the performance impact is too much to be usable in production. Are there projects or Linux distributions or even a Linux distro package that uses this option (suggesting it's not too bad)? Also, I think we need to document the performance impact in this flag if it's option.

@GabrielDosReis
Copy link

I'm worried if the performance impact is too much to be usable in production. Are there projects or Linux distributions or even a Linux distro package that uses this option (suggesting it's not too bad)? Also, I think we need to document the performance impact in this flag if it's option.

I share similar concerns.

I understand it was used at some places, but it isn't free and the cost is not necessarily commensurate to what is sought. Maybe, there are some realistic benchmarks to point to, to help programmers to assess when it is the right thing for them?

@Flo4152
Copy link
Author

Flo4152 commented Apr 19, 2024

@thomasnyman @david-a-wheeler @GabrielDosReis To answer to the question about performance penalties, in addition to Caroline Tice's articles about performance penalties, I think scripts and tools suites from Caroline Tice's commit offers ways to evaluate the number of vcall being verified.

The -fvtv-counts flags from GCC provides way to process source codes to count of vcalls being verified by the feature -fvtable-verify. (https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fvtv-counts and https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libvtv/scripts/sum-vtv-counts.c;h=fc99498e70522a77645d27f01f4b3cdf754a8829;hb=2077db1be5b18b94a91095a3fb380bbc4a81e61b)

These counters offers a evaluation of performance penalty of vtable verification feature of GCC.

I'm working on adding a description of -fvtv-counts flag.

Regards,


### Special considerations

Virtual table verification is disabled in the default GCC configuration. GCC must be compiled with the `--enable-vtable-verify` option to enable virtual table verification. The current GCC configuration is given by `gcc -v` or `gcc -###` command.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback from C/C++ Compiler BP Guide call from 2024-04-24:

This would be good to in addition to include in Section 6.5 with the same caveat as above about significant performance impact to code produced by the compiler.

@@ -205,6 +205,7 @@ Table 2: Recommended compiler options that enable run-time protection mechanisms
| [`-fno-strict-overflow`](#-fno-strict-overflow) | GCC 4.2 | Integer overflow may occur |
| [`-fno-strict-aliasing`](#-fno-strict-aliasing) | GCC 2.95.3<br/>Clang 18.0.0 | Do not assume strict aliasing |
| [`-ftrivial-auto-var-init`](#-ftrivial-auto-var-init) | GCC 12<br/>Clang 8.0 | Perform trivial auto variable initialization |
| [`-fvtable-verify=std`](#-fvtable-verify) | GCC 4.9.4 | (C++) Enable run-time checks for virtual function pointers corruption. Can impact performance. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback from C/C++ Compiler BP Guide call from 2024-04-24:

Suggest to reword "Can impact performance" to "Significantly impacts performance"

https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fvtable-verify
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=2077db1be5b18b94a91095a3fb380bbc4a81e61b
https://gcc.gnu.org/wiki/cauldron2012?action=AttachFile&do=get&target=cmtice.pdf#page=38
https://www.usenix.org/sites/default/files/conference/protected-files/sec14_slides_tice.pdf#page=14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Turn the relevant references here to footnotes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality requested on the IT forum leads to this ticket: https://sir.ext.ti.com/jira/browse/EXT_EP-10096

This request has been classified as "non-priority" since November 2020 and this issue is still open with no activity. I don't think this message is relevant as it hasn't been implemented yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vtable verification during compiling C++ code
4 participants