Skip to content

Commit 3d6e6a8

Browse files
eugenismemfrob
authored andcommitted
Fix CFI issues in <future>
This change fixes errors reported by Control Flow Integrity (CFI) checking when using `std::packaged_task`. The errors mostly stem from casting the underlying storage (`__buf_`) to `__base*`, even if it is uninitialized. The solution is to wrap `__base*` access to `__buf_` behind a getter marked with _LIBCPP_NO_CFI. Differential Revision: https://reviews.llvm.org/D82627
1 parent d94f699 commit 3d6e6a8

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

libcxx/include/future

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,10 @@ template<class _Rp, class ..._ArgTypes>
18231823
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
18241824
{
18251825
typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1826+
1827+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1828+
__base* __get_buf() { return (__base*)&__buf_; }
1829+
18261830
typename aligned_storage<3*sizeof(void*)>::type __buf_;
18271831
__base* __f_;
18281832

@@ -1856,10 +1860,10 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged
18561860
{
18571861
if (__f.__f_ == nullptr)
18581862
__f_ = nullptr;
1859-
else if (__f.__f_ == (__base*)&__f.__buf_)
1863+
else if (__f.__f_ == __f.__get_buf())
18601864
{
1865+
__f.__f_->__move_to(__get_buf());
18611866
__f_ = (__base*)&__buf_;
1862-
__f.__f_->__move_to(__f_);
18631867
}
18641868
else
18651869
{
@@ -1877,8 +1881,8 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
18771881
typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
18781882
if (sizeof(_FF) <= sizeof(__buf_))
18791883
{
1884+
::new (&__buf_) _FF(_VSTD::forward<_Fp>(__f));
18801885
__f_ = (__base*)&__buf_;
1881-
::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
18821886
}
18831887
else
18841888
{
@@ -1920,17 +1924,17 @@ template<class _Rp, class ..._ArgTypes>
19201924
__packaged_task_function<_Rp(_ArgTypes...)>&
19211925
__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
19221926
{
1923-
if (__f_ == (__base*)&__buf_)
1927+
if (__f_ == __get_buf())
19241928
__f_->destroy();
19251929
else if (__f_)
19261930
__f_->destroy_deallocate();
19271931
__f_ = nullptr;
19281932
if (__f.__f_ == nullptr)
19291933
__f_ = nullptr;
1930-
else if (__f.__f_ == (__base*)&__f.__buf_)
1934+
else if (__f.__f_ == __f.__get_buf())
19311935
{
1932-
__f_ = (__base*)&__buf_;
1933-
__f.__f_->__move_to(__f_);
1936+
__f.__f_->__move_to(__get_buf());
1937+
__f_ = __get_buf();
19341938
}
19351939
else
19361940
{
@@ -1943,13 +1947,14 @@ __packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&
19431947
template<class _Rp, class ..._ArgTypes>
19441948
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
19451949
{
1946-
if (__f_ == (__base*)&__buf_)
1950+
if (__f_ == __get_buf())
19471951
__f_->destroy();
19481952
else if (__f_)
19491953
__f_->destroy_deallocate();
19501954
}
19511955

19521956
template<class _Rp, class ..._ArgTypes>
1957+
_LIBCPP_NO_CFI
19531958
void
19541959
__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
19551960
{

0 commit comments

Comments
 (0)