Hi Nuno, I noticed your commits related to -fbounds-checking and have some questions. The functionality of this new phase seems to (partially?) overlap with AddressSanitizer and SAFECode, so I am curious how would you compare the two existing tools with the new one. Earlier you wrote:>> So the main idea of this new flag is not for debugging, but rather forproduction.>> This means that we won't be able to perform as many checks as >> AddressSanitizer,>From the code (lib/Transforms/Scalar/BoundsChecking.cpp) I can concludethat you add checks only if you can deduct the array boundaries, either from constants or from malloc() parameter. How many run-time checks does -fbounds-checking create? Do you have such statistics? Do you also have performance numbers? Are there any bugs that -fbounds-checking can find but {SAFECode,ASan} can not?>> but the performance is supposed to be acceptable for >> binaries that are shipped for production.Btw, AddressSanitizer's performance *is* acceptable for production in many circumstances. Why do you route all run-time checks to a single trap BB? I understand this as a code-side optimization, but it makes analyzing the failure almost entirely impossible. Even if you use different traps, what is the expected user experience once he/she receives the trap? Finally, do you have any document describing the tool? Thanks, --kcc -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120524/b19f7908/attachment.html>
+John Criswell On Thu, May 24, 2012 at 1:43 PM, Kostya Serebryany <kcc at google.com> wrote:> Hi Nuno, > > I noticed your commits related to -fbounds-checking and have some > questions. > The functionality of this new phase seems to (partially?) overlap with > AddressSanitizer and SAFECode, > so I am curious how would you compare the two existing tools with the new > one. > > Earlier you wrote: > >> So the main idea of this new flag is not for debugging, but rather for > production. > >> This means that we won't be able to perform as many checks as > >> AddressSanitizer, > > From the code (lib/Transforms/Scalar/BoundsChecking.cpp) I can conclude > that you add checks only if you can > deduct the array boundaries, either from constants or from malloc() > parameter. > How many run-time checks does -fbounds-checking create? Do you have such > statistics? > Do you also have performance numbers? > > Are there any bugs that -fbounds-checking can find but {SAFECode,ASan} > can not? > > >> but the performance is supposed to be acceptable for > >> binaries that are shipped for production. > > Btw, AddressSanitizer's performance *is* acceptable for production in > many circumstances. > > Why do you route all run-time checks to a single trap BB? > I understand this as a code-side optimization, but it makes analyzing the > failure almost entirely impossible. > Even if you use different traps, what is the expected user experience once > he/she receives the trap? > > Finally, do you have any document describing the tool? > > Thanks, > > --kcc > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120524/5664c5a0/attachment.html>
Hi Kostya, I'm also curious to know where Nuno is going with this, and the details of his design. I'm worried he might be reinventing the wheel. I'm also worried that he may be inventing a square wheel :)> I noticed your commits related to -fbounds-checking and have some questions. > The functionality of this new phase seems to (partially?) overlap with > AddressSanitizer and SAFECode, > so I am curious how would you compare the two existing tools with the new one. > > Earlier you wrote: >> > So the main idea of this new flag is not for debugging, but rather for > production. >> > This means that we won't be able to perform as many checks as >> > AddressSanitizer,If it is to be like AddressSanitizer but with less checks, maybe it should be a mode for AddressSanitizer that just does fewer checks... Ciao, Duncan.
John Criswell
2012-May-24 16:21 UTC
[LLVMdev] [cfe-dev] -fbounds-checking vs {SAFECode,ASan}
On 5/24/12 4:43 AM, Kostya Serebryany wrote:> Hi Nuno, > > I noticed your commits related to -fbounds-checking and have some > questions. > The functionality of this new phase seems to (partially?) overlap with > AddressSanitizer and SAFECode, > so I am curious how would you compare the two existing tools with the > new one.Nuno's original goal (described in our first set of email exchanges on llvm-commits) was to provide lightweight security checks to programs compiled by clang by using the -fbounds-checking option. I believe the goal is to protect applications at run-time. Nuno, is this correct, or did I misinterpret what you wrote?> > Earlier you wrote: > >> So the main idea of this new flag is not for debugging, but rather > for production. > >> This means that we won't be able to perform as many checks as > >> AddressSanitizer, > > From the code (lib/Transforms/Scalar/BoundsChecking.cpp) I can > conclude that you add checks only if you can > deduct the array boundaries, either from constants or from malloc() > parameter. > How many run-time checks does -fbounds-checking create? Do you have > such statistics? > Do you also have performance numbers? > > Are there any bugs that -fbounds-checking can find but {SAFECode,ASan} > can not? > > >> but the performance is supposed to be acceptable for > >> binaries that are shipped for production. > > Btw, AddressSanitizer's performance *is* acceptable for production in > many circumstances. > > Why do you route all run-time checks to a single trap BB? > I understand this as a code-side optimization, but it makes analyzing > the failure almost entirely impossible. > Even if you use different traps, what is the expected user experience > once he/she receives the trap?I don't think Nuno is trying to make a tool that helps diagnose memory safety problems. Instead, he's trying to build a tool that prevents exploitation of code at run-time. A single trap block is the correct approach for that goal. -- John T. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120524/f1147a74/attachment.html>
On 5/24/12 5:41 AM, Duncan Sands wrote:> Hi Kostya, I'm also curious to know where Nuno is going with this, and the > details of his design. I'm worried he might be reinventing the wheel. I'm > also worried that he may be inventing a square wheel :)I believe Nuno's goal is to prevent run-time exploitation of software. Nuno, please correct me if I'm wrong. And with all due respect to Nuno, I think he's reinventing the wheel. I implemented what he described using SAFECode in an evening by writing two specialized passes that are needed to adjust SAFECode's instrumentation to what Nuno needs (one pass removes checks that are too expensive; the other inlines the fast checks to remove function call overhead). That code can still be found at http://sva.cs.illinois.edu/fastsc-llvm.tar.gz. I wrote a proposal for a common memory safety instrumentation infrastructure and sent it to llvm-commits. Would it be useful to send it to llvmdev as well for discussion, or has everyone who's already interested seen it? Having said all this, if exploit mitigation is the goal, I think it might be worth taking a step back and first determining *which* safety properties one wants to enforce and what the expected overheads might be. IMHO, if I wanted a technique that could provide the most security for the least code complexity and least run-time overhead, I would implement control-flow integrity (CFI). As far as I understand, nearly all memory safety exploitation today is done by diverting control-flow(*); CFI prevents that and is faster than any other non-probabilistic mitigation in the literature. There's a paper on CFI by Abadi et. al. (http://dl.acm.org/citation.cfm?id=1609956.1609960). However, I don't think we'd want to implement it in the same way they do; I'd recommend run-time checks on indirect function calls and a split-stack approach that allows checks on stores to just mask off bits in the pointer address to prevent them from overwriting the return address on the stack. As an aside, I have a web site called the Memory Safety Menagerie (http://sva.cs.illinois.edu/menagerie/index.html) that lists papers on the topic of memory safety attack mitigation. Those interested in exploring the mitigation options might find it useful. -- John T. (*) Attacks that only change data-flow are possible and practical, but I think these are a minority of attacks in the wild. Attacks that divert control-flow are not only common, but researchers have now built tools to automate the creation of such attacks.
On 24 May 2012 at 11:21, John Criswell wrote:> I don't think Nuno is trying to make a tool that helps diagnose memory > safety problems. Instead, he's trying to build a tool that prevents > exploitation of code at run-time. A single trap block is the correct > approach for that goal.post-mortem forensic analysis is just as important as detecting/preventing the exploit attempt itself (otherwise you will never figure out the original bug, never mind its siblings elsewhere). so any information that helps to determine the exact failure path is useful, especially if it's as cheap as an int3 or ud2 on x86.