[llvm] [llvm] Fix behavior of llvm.objectsize in presence of negative / large offset (PR #115504)

Harald van Dijk via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 13 04:10:59 PST 2024


================
@@ -580,6 +585,11 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
   if (!Data.bothKnown())
     return false;
 
+  // We could compute an over-approximation in that situation, may be if
+  // Opts.EvalMode == Max, but let's bee conservative and bail out.
+  if (Data.Offset.isNegative())
+    return false;
----------------
hvdijk wrote:

> which looks like a decent usage of `__builtin_object_size`.

I actually don't think it is. [The documentation](https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html) says that __builtin_object_size(ptr, type) "is a built-in construct that returns a constant number of bytes from *ptr* to the end of the object *ptr* pointer points to (if known at compile time)." If your function `access` is specifically relying on `ptr` not pointing to an object, it should not be using `__builtin_object_size`. The typical users of it are the fortified string functions, where it is important for the fortification that out-of-bounds pointers result in a reported size of zero. This general concept can be seen in e.g. `char array[10]; strcpy(array - 4, "hello, world!");`  which results in "*** buffer overflow detected ***: terminated" when compiled with `-D_FORTIFY_SOURCE=2`, both with GCC and Clang. That `array - 4` should not be interpreted as the start of 14 potentially accessible bytes of memory. (This particular example does continue to behave as expected even with your PR.)

https://github.com/llvm/llvm-project/pull/115504


More information about the llvm-commits mailing list