成田です。

Takashi SHIRAI wrote:

>>> この過ちを侵している代表例が Samba ですね。こいつは一つも
>>> strcpy() を使わないように工夫していますが、長さ指定ミスによ
>>> る buffer overflow は過去幾つも発見されています。
>>
>>具体的にどんなバグだったのでしょうか。これを検証すると面白い
>>データが得られると思います。
> 
> Samba では文字列 (正確には char 型配列) は二種類のサイズに
> 大別されていまして、pathname を表す pstring 型 (実体は 1,024
> 文字分の char 型配列) と filename を表す fstring 型 (同様に
> 256 文字分) が用意されています。
> strcpy() を使おうとすると compile 時に error を吐くように
> 指定されていますので、文字列 copy は pstrcpy() か fstrcpy()
> しか使えません。
> ところが、内部実装を追っていくと pstring 型を fstring 型で
> 受けたりその逆をしたりという実装が非常に多くて、結局この枠組
> は全くと言っていい程役に立っていません。

これが出来る時点で、私には全然文字列コピー対策は万全なんて思えない
のですけれど。

Samba のソースは見たことないから
<http://samba.org/doxygen/samba/winbind__nss__config_8h.html>
を見てみましたが、

        typedef char fstring[FSTRING_LEN];

とかしてるんで、

        fstring fstrcpy(fstring, fstring);

とか?pstring を fstring で受けれたりということは、せいぜいこん
なところかと思うのですが、これじゃコンパイラの支援は期待できないの
でやっぱり嬉しくないですよね。最低でも、

        typedef struct { char name[FSTRING_LEN]; } fstring;

とかにすれば良いのですかね?んで、

        result f2p(fstring, pstring);

とか準備しておく?まあ、asprintf の方が簡単か。

> 文字列 copy の際には、strncpy() でも構わないから常に size
> を指定するように心がけておけば、このような size の違いは見落
> とす可能性が減ると思うのですが、「文字列 copy 対策は既に万全
> なのでチェックしなくてよい」という思い込みが幾つも security
> hole を生んでしまうのです。
> どういう実装で bug を回避しようとも構わないのですが、問題
> 意識を低下させてしまう結果を生むような実装だけはやめておいた
> 方がいいというのが私の持論です。

中途半端さが変な安心とそれにまつわるリスクを呼び込んでいる気がします。
本当に「万全」ならそれはそれで良いのでは。もちろん本当の本当に万全な
んてあり得ないということで、頭の片隅に問題意識をすまわせておくことは
必要なことでしょうけれど、常に綱渡りを強要することで問題意識を喚起す
るというのも妙な気もする。

--
        「十分間で決断し、短い理由を添えよ」
        A.I.Soft, Inc. CS・品質推進課 成田隆興