`ZstdCompressionWriter()` constructs successfully but leads to `segmentation fault`
メンテナーはふだん 2 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
まず Python reproducer を実行し、その後、writer の構築経路と併せて c-ext/compressionwriter.c:64 および c-ext/decompressionwriter.c:50 を調査します。引数なしの構築について、C extension の動作を CFFI backend と比較します。直接構築で到達可能な NULL の内部フィールドが残らず、segfault ではなく Python exception が発生すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
I've been fuzzing Python C extension modules for a small research project.
I found a sanitizer issue which is a null-pointer dereference in ZstdCompressionWriter_memory_size.
I reproduced it with the binary wheel from a plain pip install zstandard.
The process terminates with SIGSEGV there as well.
I'm not sure whether zero-argument construction of this type is considered supported (calling ZstdCompressionWriter() with no arguments),
but since it currently terminates the interpreter rather than raising a Python exception, I thought it was worth reporting.
Versions
zstandard 0.25.0, cext backend, CPython 3.12, Linux x86_64.
Reproducer
import zstandard
w = zstandard.ZstdCompressionWriter() # succeeds
w.memory_size() # SIGSEGV
Five calls across the two writer types behave the same way, each from a fresh direct construction:
| class | methods that segfault |
|---|---|
ZstdCompressionWriter |
memory_size(), close(), flush() |
ZstdDecompressionWriter |
memory_size(), flush() |
Sanitizer build
Same call, zstandard built with -fsanitize=address,undefined:
c-ext/compressionwriter.c:64:65: runtime error:
member access within null pointer of type 'ZstdCompressor'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
c-ext/compressionwriter.c:64:65
AddressSanitizer: SEGV on unknown address 0x000000000020
#0 ZstdCompressionWriter_memory_size c-ext/compressionwriter.c:64:65
ZstdDecompressionWriter.memory_size() reports the equivalent at
c-ext/decompressionwriter.c:50:67.
Expected behavior
I think that direct construction should be rejected with a Python exception, as it is by the CFFI backend.
Under PYTHON_ZSTANDARD_IMPORT_POLICY=cffi the same construction is refused outright:
TypeError: ZstdCompressionWriter.__init__() missing 5 required positional
arguments: 'compressor', 'writer', 'source_size', 'write_size',
and 'write_return_read'
Actual behavior
The C extension permits construction with no arguments, leaving internal fields NULL.
Several methods dereference those fields and terminate the process with SIGSEGV.
Although these objects are normally obtained through stream_writer(), I wonder whether the C extension should reject zero-argument construction, as the CFFI backend already does, rather than produce an uninitialized object.
- 主要言語
- C
- スター
- 641
- フォーク
- 117
- 平均マージ
- 1日 14時間
- マージ済み PR(30日)
- 5
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
indygreg/python-zstandard のほかの issue
-
`multi_decompress_to_buffer([])` terminates the process with SIGFPE対応中かも @mikamikasuki が 8 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
indygreg/python-zstandard#335 ·
メンテナーはふだん 2 日以内に返信
-
Silent data-correctness bug: `readinto()` / `readinto1()` on `stream_reader` return `tell() == 0` after successful reads対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
indygreg/python-zstandard#295 ·
メンテナーはふだん 2 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 64/100
indygreg/python-zstandard#345 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 55/100
indygreg/python-zstandard#334 ·
メンテナーはふだん 2 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 54/100
indygreg/python-zstandard#333 ·
メンテナーはふだん 2 日以内に返信
indygreg/python-zstandard の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
severity: low
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
luainkernel/lunatik#1853 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 半日 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
resetes12/pokeemerald#204 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 6 日以内に返信