[libcxx-commits] [PATCH] D96842: [dfsan] Do not specialize vector<bool> for DFSan

stephan.yichao.zhao via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 16 23:06:24 PST 2021


stephan.yichao.zhao created this revision.
stephan.yichao.zhao requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

DataFlow Sanitizer (https://clang.llvm.org/docs/DataFlowSanitizer.html)
tracks dataflow at byte granularity: all bits of a user byte share the
same dataflow label.

The default implementation of vector<bool> causes DFSan uses undefined
labels. The problem is like this:

1. push_back may reserve new memory when out of capacity. Note that after reserve, __construct_at_end initializes only the first new byte.

2. The new bit is pushed at this line, https://github.com/llvm/llvm-project/blob/main/libcxx/include/vector#L3067 which eventually calls operator= like this

  __bit_reference& operator=(bool __x) _NOEXCEPT { if (__x) *__seg_ |= __mask_; else *__seg_ &= ~__mask_; return *this; } Here note that
  - __x is not assigned to __seg_ directly, but based on if-else. So DFSan never has a chance to propagate the label of x to __seq_ without control-flow-tainting.
  - recall that reserve does not zero out new bytes. So the read of __seq_ can return undefined. However at bit-level this is fine because
    - ? & 1 = 1 and ? | 0 = 0;
    - although operator[] does not do bound check, it is obvious that reading unset bits is undefined.

      However DFSan reads uninitialized shadow values at the case, causing over-tainting. Even if DFSan tracks at bit-level, it also needs to understand the semantics of | and & to make it work.

This change, when --config=dfsan is used, disables specializing
vector<bool>, forcing using the general implementation. Although this
increases memory cost 8x, this is acceptable to DFSan because DFSan has
memory overhead anyway.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96842

Files:
  libcxx/include/vector


Index: libcxx/include/vector
===================================================================
--- libcxx/include/vector
+++ libcxx/include/vector
@@ -2148,6 +2148,8 @@
 #endif
 }
 
+#if !defined(DATAFLOW_SANITIZER)
+
 // vector<bool>
 
 template <class _Allocator> class vector<bool, _Allocator>;
@@ -3331,6 +3333,8 @@
         {return __vec.__hash_code();}
 };
 
+#endif // DATAFLOW_SANITIZER
+
 template <class _Tp, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96842.324196.patch
Type: text/x-patch
Size: 479 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210217/8b62b310/attachment.bin>


More information about the libcxx-commits mailing list