boostorg / boostorg/circular_buffer

undefined behavior in do_fill_uninitialized_memory()

オープン
#39 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
C++
スター
65
フォーク
64
PR マージ指標
30日以内にマージされた PR はありません

説明

Using gcc 9.1 with -fsanitize=undefined and -DBOOST_CB_ENABLE_DEBUG=1, the following code results in a ubsan error: "boost/circular_buffer/debug.hpp:37:16: runtime error: null pointer passed as argument 1, which is declared to never be null".

```
using Q = boost::circular_buffer;
Q q;
const Q q2(q);
```

The ubsan error is a result of the following code in circular_buffer/debug.h:

```
template
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
std::memset(static_cast(data), UNINITIALIZED, size_in_bytes);
}
```

During copy construction, the function gets called with data == nullptr and size_in_bytes == 0. I believe that passing a null pointer to memset is technically undefined behavior even if the size is 0.

Changing the above function as follows avoids the ubsan error:

```
template
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
if (size_in_bytes != 0u) {
std::memset(static_cast(data), UNINITIALIZED, size_in_bytes);
}
}
```

I had originally written it to check for data != nullptr, but since this is debug code I thought it seemed desirable to know if the function is ever called with data == null and size_in_bytes != 0. In any case, either way will prevent the ubsan error.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

boost/circular_buffer/debug.h の do_fill_uninitialized_memory() から始め、空の circular_buffer に対するコピー構築の経路を確認します。GCC 9.1、-fsanitize=undefined、-DBOOST_CB_ENABLE_DEBUG=1 を使って例を再現します。空のコピーの場合に null-pointer エラーが報告されなくなり、ゼロ以外の fill は引き続きチェックされれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
cpp
領域
backend
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
52/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。