Monday, 21 January 2019

Buffer Overrun

ま、プロならやらんだろってわけなんですが... いかんせん、考古学的プロジェクトだからな。

  Linux で動かしてみたら、free が invalid pointer と言い張る

え〜 これは malloc した領域にポインタ経由で爆撃しているので厄介なんだよな。再現性があるので場所はだいたいわかってて、

  仮想ディスクドライバ

ディスクイメージではなく、UFSを直接見れるようにした奴ですね。思い当たる所がありすぎる。

なのだが、さっぱりわからない。GNU glibc のmalloc には mcheck ってのがあるらしいんだが、

  usleep が死んでしまう

しかも、mcheck のcheckはすり抜けて free で落ちる。使えな〜 

  mallopt - set memory allocation parameters

という man の entry があって、MALLOC_CHECK_ って環境変数が。そういえばそういうのあった。これで、
最初の free で捕まるようになりました。いや、だからさ、

  free の前のどこだよ?

MALLOC_CHECK_ で呼ばれる free_check() を使って二分法すれば良いのだが、

  何故か static

C の名前空間を汚したくないんだろうけど。そこで、glibc make して呼び出したれと思ったんですが、

  glibc ってのは特定のkernelと特定の環境でないと build できない

時代遅れのCentosですが、build できたのだが動かず。まぁ、そうだよな。でも、gdb の中からなら static でも呼べる?

というわけで、free_check() で二分法と思ったんですが...

  free_check() は実は free してしまう routine で一度しか使えない

そういうの「check」とは呼ばないから! でも、まぁ、毎回最初からやる二分法は可能だったので捕まえました。
free で二分法でもできたはずです。

捕まえてみれば、strinng copy が一文字多いだけだった。for(;i<len;i++) の後に s[i]=0 とやってしまう、うっかりパターン。
macOS は malloc の前後に guard 取ったりするので動いたりする。Linux/GNUな人たちは「Buffer overunとかやるのは馬鹿だけ」
という立場なんでしょう。まあ、その通りではある。

vargrind 使ってみるべきだったかな。

No comments: