[llvm-commits] change objectsize signature
Nuno Lopes
nunoplopes at sapo.pt
Tue May 8 13:35:21 PDT 2012
>> 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'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
More information about the llvm-commits
mailing list