Issue 145386
Summary __cxa_guard_acquire()'s guard byte check doesn't conform to CPPABI64
Labels libc++abi
Assignees
Reporter asl
    The generic C++ ABI [GCPPABI](http://itanium-cxx-abi.github.io/cxx-abi/abi.html) specifies the bottom byte of a static variable guard variable shall be 0 when the variable is not initialized, and 1 when it is. All other bytes are platform defined.

ARM [CPPABI64](https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/cppabi64/cppabi64.rst#guard-variables) further refines down to:
> This ABI instead only specifies the value bit 0 of the static guard variable; all other bits are platform defined. Bit 0 shall be 0 when the variable is not initialized and 1 when it is.

However, libcxxabi checks whether the whole init byte is != 0 regardless of the platform:
```c++
  /// The guard byte portion of cxa_guard_acquire. Returns true if
  /// initialization has already been completed.
  bool acquire() {
    // if guard_byte is non-zero, we have already completed initialization
    // (i.e. release has been called)
    return guard_byte.load(std::_AO_Acquire) != UNSET;
 }
```
https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/cxa_guard_impl.h#L196

This means that if the guard byte has a value != 0 with the lowest bit == 0 (i.e., 2), the guard byte is still treated as initialized, even though it is not according to CPPABI64.

This doesn't look like it will cause any problems, since the initial value of the whole guard variable is 0, and the guard byte is set to 1 (which has the lowest bit set) in `__cxa_guard_release()`.

So, the question is if this is something that should be fixed (to `== COMPLETE_BIT`), or left as-is, or if there are any security / correctness implications here.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to