何が起きたか・対象

PDF解析ライブラリPopplerで、多数の参照を含むPDFを解析すると、まだ使用中の注釈を解放してしまう問題がありました。識別子はCVE-2025-52886です。

PDFの注釈は、ページに付けるコメントなどのオブジェクトです。同じ注釈を複数ページで共有する場合、注釈本体が一つでも、各ページはその本体を指す参照を持てます。参照数は、その本体をまだ使う箇所を数えるための値です。

注釈のメモリは、それを使う参照の数が0になったときに解放します。しかし、攻撃者が同じ注釈への参照を大量に作ると、32ビットのカウンターが表せる範囲を超えて0へ回り込む場合がありました。処理が「もう使っていない」と誤認して解放した後、残っていた参照から同じ領域へアクセスするため、メモリ破壊につながります。研究では発生まで12時間かかり、実用上の悪用リスクは低いと評価されています。 桁あふれの仕組みだけを小さく例示すると、0〜3を循環する2ビットの値は、3に1を足すと0になります。実際の問題は32ビットの参照数で起きます。どの解放関数が0を確認するかという全行の追跡は本記事では未確認ですが、研究は桁あふれ後に注釈が削除されることを示しています。

報告・修正・公開の時系列

25.02.0で検証され、2025-04-03に非公開報告、06-02に注釈数を制限する修正が入りました。06-03に問題が公開され、25.06.0がリリースされました。研究記事は07-01の公開です。

正常ならどう動くはずだったか

参照カウントは、オブジェクトを使っている箇所の数を数える仕組みです。参照が残る間は領域を解放せず、最後の利用が終わった後だけ解放する必要があります。 例えば注釈本体が一つあり、ページAとBがそれを指すなら参照は二つです。片方を使い終えてももう片方が残るため、本体を解放してはいけません。参照を保持・破棄する処理が数を更新し、本当に利用箇所がなくなったときだけ解放します。

技術的な原因

注釈オブジェクトを共有する参照数は32ビットのstd::atomic_intで管理されていました。PDF内の多数の参照で加算を繰り返し、表せる範囲を超えてゼロへ戻ると、処理は参照が残っていないと誤認して注釈のメモリを解放します。別の処理がまだ持つ参照からその領域へアクセスし、解放後使用になります。

攻撃が成立する条件と流れ

研究のPDFは、圧縮ストリームを展開すると大きな注釈配列になり、その同じ配列を多数のページが参照する構造です。Popplerが各ページの注釈を処理するたびに共有オブジェクトへの参照数を加算し、配列の項目数とページ数を掛けた回数だけ同じカウンターが増えます。小さい圧縮ファイルでも解析時の反復が大きくなるため、入力バイト数だけではカウンターの増加を抑えられません。

確認された事実と、想定される影響

研究は解放後使用によるメモリ破壊を示しています。使用中の注釈が解放されることで、後のアクセスが異常終了やデータ破壊につながるおそれがあります。攻撃者が情報や資格情報を取得できたという実証ではありません。試験では発生まで12時間かかり、研究者は実用上の悪用リスクを低いと評価しています。コード実行の可能性への言及と、実際のコード実行・侵害の観測を区別します。

実際の修正・対応方針

研究の時系列では、MR #1828で最大注釈数を制限し、25.06.0に含めています。注釈配列の項目をページごとに処理して参照を増やすため、扱う注釈数を制限することは加算回数を抑える方向の対策です。ただし差分全体は直接確認しておらず、制限値や全ページを通じた上限の保証はここでは断定しません。atomicは同時更新を取りこぼさない性質で、カウンターの桁あふれとは別の問題です。

利用者・運用者が確認すること

Popplerを使うPDF変換サービスや間接依存も確認して更新します。入力サイズに加え、展開後の処理時間やメモリを制限し、解析プロセスを隔離すると、長時間の異常処理や破壊時の範囲を抑えられます。

開発者への教訓(教材としての考察)

atomicは同時更新を一つの操作として扱う性質で、数値の上限を保証するものではありません。参照の数、カウンターの範囲、解放時期は別々に確認します。

出典・確認範囲

  1. [1] Use After Free in PopplerGitHub Security Lab / 確認日 2026-10-29
未確認事項・限界

参照資料では実悪用や実際の被害件数を確認できません。未記載の実装差分は推測していません。