Re: strcpy, strlcpy.
新城@筑波大学情報です。こんにちは。
ネットワークニュースのは、主張は何度でも繰り返してよいことに
なっています。
In article <c8dnnb$jnk$1@news2.rim.or.jp>
dohzono@hf.rim.or.jp (Kazuo Fox DOHZONO) writes:
> 堂園です.
> > いいえ。「既にチェックされたかどうかを判断する」というコスト
> > を無視しては困ります。「既にチェックされたかどうかを判断する」
> > のは、相当大きなコストがかかります。関数呼出しがあったり、長
> > 年に渡って別の人が維持したりする時。
> そのような判断の必要性を排除し, 排除されたことをレビューによって理解す
> ればよろしい, ということを前にも書いたはずです.
レビューすれば、何書いてもいいという話ですか?レビューって、
結局、書いた人と受け取る人の間の話で終りじゃないですか。プロ
グラムの寿命を考えると、書いた人とは別の人が直したり、レビュー
を受けた人とは別の人が使ったりするわけでしょ。レビュー、つま
り、言訳がしっかりしていれば、どんなプログラムでもよいという
結論にはならないはずです。2000年問題の時もありましたが、プロ
グラムの寿命はかなり長いです。会社がつぶれてもプログラムが残
るということもあります。
あと、筋としては、レビューは strlcpy() を否定する根拠にはな
りません。というのも、次の2つのプログラムを比較するとわかり
ます。
(1) レビューがしっかりしていて strlcpy() を使っている
(2) レビューがしっかりしていて strcpy() を使っている
この2つでは、(1) がいいわけですよね。
> いいえ. sizeof d が問題なんです. d の宣言部が画面 (プログラマの記憶)
> から外れている時, sizeof d が何の大きさを求めているかは一瞥ではわかり
> ません (それで正しい場合があるだけに発覚し難い誤りだと思います).
あのプログラムは、私が出した例ではありせん。しかも、悪い例で
す。よいプログラムの話をしましょう。
sizeof() は、配列を宣言した所で使います。配列ではなくて、
malloc() したらな、その長さもいつしょに保管します。そうする
と、必ずメモリの先頭番地と長さがペアになります。引数で渡す時
には、必ず先頭番地と長さをペアにします。おしまい。
> もっといえば, プログラム中に (明に/暗に) 存在する全ての strcpy を
> strlcpy にして, いきなり全て正しい長さと挙動を書ける程のスキルは誰にも
> 備わっていないと思います. 仮にそれをやったとして, 増加するテストのコス
> トも無視出来ません.
これは、上のようにやれば、ほとんど形式的にできます。コストは
無視できます。それに、最初から strcpy() を使わなければコスト
増加は0です。
> もちろんうまく wrap する (一々手で指定しない) 方法は幾つも考えられます.
> C++ を使うのも一つの手でしょう (C++ を使ったからといって必ずしもそうい
> うプログラムになるわけではありませんが). 私の例はそれとは違うアプロー
> チを採ってパラメータを隠しただけのことです.
C++の話は、私も書きました。堂園さんのアプローチは、似て非
なるものです。
> セキュリティの話をしていてそのような (挙動が予測出来る) 名前が出てきた
> 場合, 反応すべきなのは「大きさのわからない文字列はヒープ上に置く (スタッ
> ク上に置かない)」の方だと思うのですが.
スタックに文字列を置かなければ安全、というわけでもないんです
ね、これが。ポインタを使って間接的にスタックを攻撃するという
手法が知られています。まずバッファ・オーバーフローで(ヒープ
上の)ポインタを書き換えて、スタックの戻り番地を差させます。
次に、そのポインタに危ないコードを先頭番地を store します。
攻撃側もよく考えるよね。まったく。
今度出る Intel のチップは、スタックを実行禁止にできるんでし
たっけ。攻撃側は、普通は弱い方を狙うんだけど、スタックが守ら
れたらヒープを狙うようになるのかも。
\\ 新城 靖 (しんじょう やすし) \\
\\ 筑波大学 電子・情報 \\
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735