- PR -

32bit環境から64bit環境へのCプログラムの移植について

投稿者投稿内容
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-20 23:51
引用:

ぽんすさんの書き込み (2007-06-20 20:10) より:
長さ3バイトのバッファに対して、長さ2バイト以内のコピーを行っているので
バッファオーバーフローは生じ得ません。



その後のatoi()でしていませんか?
atoi()は書き込みではないので最悪プロセスが落ちる程度ですが、
書き込みを行う場合は戻りアドレスの上書きの可能性があります。

読み込みだけでもバッファオーバーランと呼ぶかは微妙ですが、
似たような挙動である事は確かです。

引用:

それは最初にcoasmさんが指摘されたことで言い尽くされてますよね。
"20070617"から"06"を切り出しているのだから、もとより06のうしろは
null終端されていません。
strncpyする前に長さをチェックしても意味がありません。


意味がよく伝わらないのですが、

宣言時の初期化構文やmemset()、strncpy()後にpDst[2] = '\0';
などでNUL終端させる必要があるのには変わりないのでは?

strncpy()の場合は、指定サイズ全体を書き込んだ場合に
NUL終端されないのは仕様なので、呼び出し前に指定サイズよりも
文字列長が短い事が判明していない限り自前でのNUL終端が必須です。
kalze
ぬし
会議室デビュー日: 2003/10/23
投稿数: 406
お住まい・勤務地: 東京・東京
投稿日時: 2007-06-21 01:30
引用:

その後のatoi()でしていませんか?
atoi()は書き込みではないので最悪プロセスが落ちる程度ですが、
書き込みを行う場合は戻りアドレスの上書きの可能性があります。



ぽんすさんは、コピーする部分ではバッファオーバーランは発生しないと書かれていますが、それ以上のことは書かれていませんよね。
それ以上のことである、atoiの話持ち出してもかみ合わないと思うのです。

引用:

宣言時の初期化構文やmemset()、strncpy()後にpDst[2] = '�';
などでNUL終端させる必要があるのには変わりないのでは?

strncpy()の場合は、指定サイズ全体を書き込んだ場合に
NUL終端されないのは仕様なので、呼び出し前に指定サイズよりも
文字列長が短い事が判明していない限り自前でのNUL終端が必須です。



最初のcoasmさんの書き込み読みました?
「NULL終端文字がないから、atoiが保証されないよ」(要約)と書かれていて、
ぽんすさんもそれに同意されているだけで、
あしゅさんと言ってることは一緒ですよ。

処理全体で話ししてるのがあしゅさんで、
処理をひとつずつ話ししてるのがぽんすさん。
結局指摘しているというか、懸念しているというか、問題にしている内容は同じかと。

#なにかかみ合っていないようなので、でしゃばりました
#気になったらすいません
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2007-06-21 01:31
null終端しなきゃならないのは当たり前です。

この例の場合、strncpy()の前に長さをチェックすることと
null終端が保証されることとは全く関係ないですよね。

長さをチェックしようとしまいと、終端するためのnull文字を
書き込んでおかなくてはならないことに変わりはない。
長さをチェックしようとしまいと、strncpy()でpDstが
オーバーフローすることはない。

追記。
mioさんの指摘もそうだし、&pSrc[4]なんていう書き方をみても
どうやらポインタがあまり分かってない人が試行錯誤して
「とりあえず意図した通りに動いているらしい」というものを
作っているように感じます。
探せばまだまだおかしなところは見つかるかもしれませんが、
それを追求すべきかどうかはなんとも。
この世はどうせバグだらけのソフトでいっぱいだし、
労働力のリソースは有限ですから。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2007-06-21 08:59 ]
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-21 09:07
ああ。そういうことでしたか。納得しました。

引用:

ちゃっぴさんの書き込み (2007-06-20 00:48) より:
C言語で入力の長さすら検証せず strncpy するのは気持ち悪いので。。。


元の内容は単にpSrcにstrlen()かけるかどうかの話だったのですね。
NUL終端の話とごっちゃになってて勘違いしていました。
ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2007-06-22 01:40
気持ち悪いと書いた理由を説明しますが、この場合 6文字以内の文字列の pointer を与えたら、本来は読み取りするべきでない data が読み取れてしまうことなんです。

ただ、実際それが攻撃に使えるかというと使えないでしょうから、問題は無いんですがね。。。

でも、この場合返ってくる値は 1 〜 12 が返るべきでして、
# そのほかに例外用の値を返す方法は十分ありだと思います。
それ以外の値を返す可能性があるのはやっぱり気持ち悪いですね。

個人的には、関数内で返ってくる値を制限すべきだと思います。
_________________
progman
大ベテラン
会議室デビュー日: 2005/06/08
投稿数: 227
投稿日時: 2007-06-25 13:44
ポンスさんが2007-06-20 01:53投稿されてる内容で

>なにが入ってるのか、なにが返ってきたのかチェックしてないのが気になるといえば
>気になりますが、それはよそでやっているかもしれないし、これだけではなんとも。

とありますよね、ここでやるべきか、呼び出された時点で保証されてるのかは、
この関数だけ見てもわからないですよ。

スキルアップ/キャリアアップ(JOB@IT)