-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SonarScanで検出されたStaticVectorの範囲外アクセスを修正する #1679
SonarScanで検出されたStaticVectorの範囲外アクセスを修正する #1679
Conversation
azpでリリースビルドのテストが失敗しました(想定通りです。 |
❌ Build sakura 1.0.3792 failed (commit 8a69775b9f by @berryzplus) |
✅ Build sakura 1.0.3793 completed (commit 99ad40b03b by @berryzplus) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StaticVector
はリリースビルドでは範囲外チェックを行わないようにしているのは意図的じゃないかなと思います。operator[]
や resize
メソッドもそうなので。
ヒープを用いないvector型を用意しているのはその方が軽量だからでしょうね。
いや、設計仕様ではなく「漏れ」でしょう。 assertが入ってるので不正な呼出しに対してデバッグ処理が止まり、対応できたような気になってたのではないかと思います。リリースではそのまま続行してしまうので実際には危険で「何が起きるか分からない」という最も厄介な不具合を引き起こします。 「ヒープを使わないVector」は、共有メモリの一部に「特定の型の配列」が含まれていて、これに安全にアクセスするために共有メモリのレイアウトと互換性のある疑似Vectorクラスが必要になったから作られた、と理解しています。 疑似Vectorクラスの開発要件は、以下のようなものだったと推定されます。 よって、軽量化を意図した機能省略が行われたとは考えにくく、純粋に処理が漏れていたものと考えられます。
|
うーん、そうなんでしょうか?まぁ明言されていないので真相は闇の中じゃないかと思います。
おっしゃる通り不正メモリアクセスが行われていると問題になりかねないです。行われていれば、なのでもし行われていなかった場合には余計なチェックになります。ただし追加したチェックの為にどれだけ性能が低下するかというとおそらく微々たるものだと思います(きちんと計測すれば性能低下の度合いが見えるかもしれませんが手間だし…)。 ところで Visual Studio 2019 version 16.9 から AddressSanitizer がサポートされたようなのでデバッグに役立てられそうです。
列挙して頂いた推定内容から「軽量化を意図した機能省略が行われたとは考えにくく」に、どのように繋がるのかよくわかりません。論理の飛躍とまで言ったら失礼かもしれませんが、想像力が働かない自分みたいな杓子定規な人間には行間を読むのが難しいです。開発要件というほど明確に内容を定めてから実装したのかどうかは自分には不明です。冒頭でも書きましたが、コメントで解説されているわけではないのでなんともです…。
berryzplusさんがどうしてそれが「筋」だと思うのかは省略して書かれていないので想像してみますが、おそらく足並みを揃えるというか ところで サクラエディタの StaticVector の 仮に境界チェックを行う場合の話ですが、境界越えの範囲が指定された場合にメモリアクセスは行わないのは前提としてその後にどうするかについてですが、
が思いつきます。このPRでは3番の何もしない方式ですが、それで問題が起きないのかどうか、呼び出し元では何もしないでよいのかどうかはちゃんと確認してないのでわかりません。 まぁとにかくSonarScanで検出されたBugを潰さないと怒られるとかいう状況だったら自分は何も考えずにApproveしてMergeします。 |
断言しといてアレですが、結論はどっちでもいいです。
高速化のために、必要なチェックをまとめて1回にすることはあると思います。 どうしても速度が欲しい処理のためにC言語やアセンブラを使うことに異論はないです。
これはよく知らんです。 msvcには、スコープ脱出時にヒープ破壊が行われていないかチェックする機能がありますが、それ系かな?
ああ、確かに。
どうして対応するのが「筋」なのか? 👉 対応方針に統一感がないのはキモいからっす。 もっとも、
まぁそういうこと(≒operator[]で境界チェックしてるの、おかしくね?)です。
例外は、導入コストが高そうなので除外しました。 ※処理の失敗を考慮しないループ内で「何もしない」を行うと、ループ脱出条件が満たされなくなりハングアップする危険があります。おそらく #1635 がこのケースの実例っす:smiley:
誰に?w |
AddressSanitizer ぐらいしか知りませんでしたが、Clang 13 (開発中)のドキュメントによると、 |
m_aElements[m_nCount-1]=e; | ||
if (0 <= m_nCount && m_nCount < MAX_SIZE) { | ||
m_aElements[m_nCount++] = e; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
範囲外のときにクラッシュさせても既存コードに影響はない建前ですよね?
気付いてないならないのと同じ?って見方もできます。
「何もしない」の危険性を考慮するなら、セオリー通り例外を使えばよいような。
a2e9a87
to
2ac84f2
Compare
Kudos, SonarCloud Quality Gate passed! |
✅ Build sakura 1.0.3800 completed (commit c66035543f by @berryzplus) |
✅ Build sakura 1.0.3801 completed (commit da6a4bfbc0 by @berryzplus) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
問題無いと思います。
レビューありがとうございます。マージしちゃいます。 |
PR の目的
SonarCloudにBugだと言われている警告を減らします。
カテゴリ
PR の背景
停滞中の #1504 で対応を進められそうなものを見つけたので作ってみました。
SonarCloudで以下のBugが検出されています。
sakura/sakura_core/util/StaticType.h
Line 121 in 0f97078
PR のメリット
SonarCloudのBugsレベル警告が1つ解消します。
PR のデメリット (トレードオフとかあれば)
とくにないと思います。
仕様・動作説明
問題のあるコードはココです。
sakura/sakura_core/util/StaticType.h
Lines 62 to 67 in 0f97078
m_nCount == MAX_SIZE
な場合、デバッグビルドではassertに失敗して、正常にクラッシュします。
リリースビルドでは66行目を実行してメモリ範囲外に書き込みます。
範囲外アドレスへの書き込みを行った結果がどうなるかは予測不能です。
このPRでは、単体テストを用意することにより、リリースビルドで実際にデータ破壊が発生することを示した後、データ破壊が起こらないように修正する提案を行います。
PR の影響範囲
テスト内容
妥当と思えるテストコードを用意して検証します。
・変更前 テストが失敗します。
・変更後 テストが成功します。
関連 issue, PR
#1504
参考資料