[llvm-commits] change objectsize signature

Evan Cheng evan.cheng at apple.com
Tue May 8 14:01:37 PDT 2012


On May 8, 2012, at 1:35 PM, Nuno Lopes wrote:

>>> The planed usage is the following:
>>> 
>>> a[i] = ..
>>> 
>>> converts to (using some loose syntax, and assuming that a[i] writes  
>>> 4 bytes):
>>> 
>>> %ptr = GEP(%a, %i)
>>> if (objectsize(%ptr) >= 4)
>>> // OK
>>> else
>>> __builtin_trap()
>>> 
>>> (this is exactly what the current implementation does;
>> 
>> I'm confused here: what is generating this code?  Clang? Dragonegg?   
>> I assume we're talking about LLVM IR that was generated for C code.   
>> Is my assumption wrong?
> 
> It can be C, yes. For example, clang can already emit this code.

I like this approach. It's leveraging existing feature for a class of (optional) new runtime checks. It's not solving all of memory safety check problems but it's a step in the right direction. I don't think this patch should be controversial.

Evan

> 
> 
>>> I'm just proposing to extend objectsize to return non-constant values)
>> 
>> Okay.  I don't think your original proposal was very clear.  You  
>> want objectsize to return non-constant values so that it is more  
>> effective at implementing these run-time checks; objectsize will not  
>> be doing the check itself.  Do I understand correctly?
> 
> Yes!
> 
> 
>> %p = load %q
>> objectsize (%p)
>> 
>> If you're doing lookups, how do you add/remove memory objects in the  
>> lookup data structure?  If the addition/removal is not done at the  
>> LLVM IR level, then how can it be optimized away when it is not  
>> needed?
> 
> That's up to the implementation, but my proposal is not to go that  
> far. Fat pointers, for example, usually incur in a big performance  
> penalty.
> But you can always extend the default implementation of objectsize to  
> perform more checks. Also, that's why the proposal includes a  
> "penalty" parameter, so that the user can specify how much performance  
> he is willing to loose.
> 
> 
>> o) Your check does not guarantee that %a and %ptr belong to the same  
>> memory object.  All you're guaranteeing is that %ptr points into a  
>> valid memory object with 4 bytes remaining in the memory object.   
>> It's possible that %ptr overflowed the object pointed to by %a and  
>> is now within the bounds of another memory object (stack objects  
>> often have no padding in between them).  That's fine, but then it's  
>> not an array indexing check; it's a load/store check.
> 
> Well, it's a GEP from %a, so it must point somewhere inside the buffer  
> of %a. objectsize should not allow buffer overflows.
> 
> 
>> o) The object size lookup (if you have one), object size comparison,  
>> and trap are not atomic, which means that other instructions may get  
>> executed in-between them.  What happens if the memory object is  
>> freed by another thread in-between the comparison and the use of  
>> %ptr?  Is that okay for your goals?
> 
> That's an interesting point that I didn't think about yet.
> 
> 
>> o) If you're doing lookups, then objectsize can fail to find the  
>> bounds because the %ptr is invalid or because %ptr could be pointing  
>> to memory objects external to the code.  How do you tell if the  
>> latter case is possible?
> 
> return (size_t)-1. If you don't know the object's size, just skip the  
> check to avoid false positives.
> 
> 
>> What you are proposing is a memory safety tool for production use;  
>> it will be fast because it won't try to do expensive checks.  The  
>> security policy it enforces seems reasonable.  You can build it the  
>> way you describe, but I'd rather see it built with a more general  
>> set of run-time checks that multiple tools can use.
> 
> Feel free to propose an alternative specification. Of course we're  
> open to better designs.
> 
> Nuno
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list