0

なぜこれが起こるのか誰にも分かりますか?

私は AIX 5.3 に C プログラムを持っています。それを SPARC Solaris 10 マシンで実行するように依頼されましたが、実際に実行したところ、多くの無謀な strcat の使用の 1 つでバッファ オーバーフローが発生していることに気付きました。私の目標は、コードをサニタイズすることではなく、AIX ではなく、Solaris でこのオーバーフローが発生する理由について、具体的かつ十分に根拠のある答えを提供することです。

これが次の原因で発生する可能性があるかどうかについて少し読んでいます。

  1. AIX と Solaris ではエンディアンが異なります。

  2. strcat 関数の実行 (AIX は右から左に、Solaris は左から右にコピーします) が、これに関するドキュメントを見つけることができませんでした。

  3. この問題が AIX で発生しないという単純な幸運です。

あなたがこれに当てることができるどんな光も高く評価されます.

編集:これは、solaris の noexec_user_stack フラグで回避できますか?

編集 2: 両方の OS が実際のバイト コピーを行う方法について誰か情報を持っていますか? 上記のオプション 2 のような状況では?

編集 3: コードのチャンクは次のとおりです。

/*global*/
char bufferA[101];
/*inside function*/
bufferA[0]='\0';
strcpy(bufferA,"1");
if (atoi(something)==0) {
strcat(bufferA,pieces_of_data);
count ++ ;
}

明らかにそれ以上のものがありますが、これはbufferAが使用されている唯一の部分であり、bufferAに追加された最後の文字列の最後の部分で破損するbufferAの後に2つの変数がグローバルに宣言されています.

前に言ったように、宣言を 101 から 201 に変更すると、破損は発生しません。

編集 4: solaris の -misalign および -misalign2 コンパイラ オプションについて何か知っている人はいますか? これらのオプションに光が当たる可能性はありますか? 実際には、AIX powerPC と Solaris SPARC のアライメントに関して違いはありますか? これはおそらくserverfaultの質問ですが、何か知っている場合は共有してください.

4

5 に答える 5

2

これは (不運な?) 運が良かったか、またはおそらく、Solaris よりも AIX に多くのスペースが割り当てられた、わずかに異なるメモリ管理システムの成果物でした。

それは、オーバーフローがどれほどひどいものであるかに部分的に依存します。それらが範囲外の数バイトでありたとえば、Solaris が 16 バイトの最小ブロックを割り当てるのに対し、AIX が習慣的に 32 バイトの最小ブロックを割り当てる場合、Solaris よりも AIX の方が損傷なしでエラーが発生する可能性が高くなります。それでも、間違ったコンテキストで間違った場合、AIXにも問題があるはずです.AIXの問題を観察しなかったのは不運だと考えることができます. Solaris でコンパイルしているソース コードが同じ場合。

さらに調査すると、次のことがわかります。

  • 32 ビット コンパイルの場合、AIX 5.3 は、Solaris と同様に、割り当てごとに 16 バイトの倍数を割り当てます。
  • 64 ビット コンパイルの場合、AIX 5.3 は割り当てごとに 32 バイトの倍数を割り当てます。これはSolarisでも同じです。

ただし、AIX と Solaris の間で 32 ビットと 64 ビットのビルドを変更した場合、これが問題の原因である可能性があります。

答えが何であれ、それを認識したので、1 つの変更セットで両方のプラットフォーム用に修正してください。あなたはそのような暴露されたすべてのバグを感謝して扱います。いつでも、元のプラットフォームの変更によって問題が明らかになる可能性があり、不満を抱く顧客に大きな問題を引き起こす可能性があります。

(ああ、私は SPARC と PPC の両方がビッグ エンディアンのマシンだと思います。リトル エンディアンであり、他の世界とは異なるのは Intel です。)


テスト コード - 意図的、意図的なリークあり

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    int sz ;
    char *buffer;
    for (sz = 1; sz < 1025; sz *= 2)
    {
        buffer = malloc(sz);
        printf("0x%08lX\n", (unsigned long)buffer);
    }   
    return 0;
} 
于 2010-09-23T17:49:30.033 に答える
2

あるプラットフォームで発生すると、他のプラットフォームでも発生します。1 つのプラットフォームのメモリ レイアウトが原因でエラーが発生したことは幸運でした。

これは未定義の動作です。

コードに無防備なstrcpy/catsが大量に散らばっている場合は、コードを修正してください。プラットフォームを責めないでください。作者を責める。

ヴァルグリンドはあなたの友達です。

于 2010-09-23T19:13:03.047 に答える
0

mallocこれが答えとしてカウントされるかどうかはわかりませんが、コード内のすべてのインスタンスを検索して置換しworkaround_malloc、後者をmalloc(size+100)..:-の呼び出しとして実装することで、手っ取り早い解決策が得られる可能性があります。 )。

于 2010-09-23T19:02:10.453 に答える
0

これはおそらく、バグのプロセッサ依存の症状です。データのパディングとアラインメントは、通常、ターゲット プロセッサの特性によって決まります。あるターゲットでは追加のパディング バイトがエラーを隠している可能性がありますが、別のターゲットではパディング バイトが少なくなっています。

また、strcat が渡される実際のデータが異なることにも関係している可能性があります。たとえば、構築中の文字列の一部が、OS、プロセッサ、またはシステム ファイルのパスの名前で構成されている場合です。

また、ヘッダー定数またはsizeofターゲットごとに異なるサイズに基づいて文字列が割り当てられた可能性があるため、実際のバッファーは小さくなります。

私が試みるかもしれないことの 1 つは、コンパイラに各ターゲットのソース ファイルの前処理されたバージョンを生成させ、それらを比較させることです。最初のヘッダー コードではおそらく大きく異なりますが、コードが存在する最後の部分ではほぼ同じになるはずです。そのコードに疑わしい違いがないかどうかを確認してください。残念ながらsizeof、ここでは数値に置き換えられませんが、マクロ定数は置き換えられます。

于 2010-09-23T19:14:17.223 に答える
0

次に、Solaris Studio デバッガを使用してメモリ アクセス/使用エラーを見つける方法を示します。

1: Download studio
  http://www.oracle.com/technetwork/server-storage/solarisstudio/overview/index.html
2: Install it
  Uncompress/Extract the downloaded file somewhere in your disk
  Run the installer
3: Recompile your program with debugging on
  $ PATH=$PATH:/opt/<studio-installation-directory>/bin
  $ cc -g program.c
4: Launch your program under debugger control
  $ dbx program
5: Enable run time checking
  (dbx) check -all
  access checking - ON
  memuse checking - ON
6: Run your program
  (dbx) run
7: Watch all the error messages
  ...
于 2010-09-28T07:57:46.183 に答える