2

AIX5.3および6.1での「strndup」呼び出しで奇妙な動作が見られました。実際のソース文字列の長さのサイズよりも大きいサイズでstrndupを呼び出すと、その呼び出しの後にスタックが破損します。

以下は、この問題が発生する可能性のあるサンプルコードです。

int main ()
{
    char *dst_str = NULL;
    char src_str[1023] = "sample string";

    dst_str = strndup(src_str, sizeof(src_str));

    free(dst_str);
    return 0;
}

誰かがこの行動を経験したことがありますか?

はいの場合はお知らせください。

私の観察によると、この問題が修正されたOSからのパッチが必要です。しかし、パッチがあったとしても、そのパッチを入手できませんでした。少し光を当ててください。

ありがとう&よろしく、Thumbeti

4

4 に答える 4

5

#include <string.h>コードにがありません。それを試してみてください—私はそれがうまくいくとかなり確信しています。その理由は、がないと、スコープ内に#include <string.h>のプロトタイプがないため、コンパイラーはがを返すと想定し、不特定の数のパラメーターを受け取るためです。それは明らかに間違っています。(私はあなたがPOSIX準拠モードでコンパイルしていると仮定しているので、あなたはそれを利用できます。)strndup()strndup()intstrndup()

このため、警告を有効にしてコードをコンパイルすると常に便利です。

変更後も問題が解決しない場合は、バグがある可能性があります。

編集:AIXで問題が発生している可能性があります:問題はAIXで機能がstrndup()壊れているようです。strnlen()問題が発生した後でも#include <string.h>、バグが発生している可能性があります。グーグル検索はそれについての結果の長いリストを示しています。

編集2

次のプログラムを試して、結果を投稿していただけますか?

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
     char *test1   = "abcdefghijabcdefghijabcdefghijk";
     char *test2   = "012345678901234567890123456789";
     char *control = "01234567890123456789012345678";
     char *verify;
     free(strndup(test1, 30));
     verify = strndup(test2, 29); /* shorter then first strndup !!! */
     fprintf(stderr,">%s<\n",verify);
     if (strcmp(control, verify))
         printf("strndup is broken\n");
}

https://bugzilla.samba.org/show_bug.cgi?id=1097#c10から取得。)

編集3:出力を確認した後、つまり>01234567890123456789012345678<、なしの場合、AIXのバージョンにバグstrndup is brokenはないと思います。strndup

ほとんどの場合、どこかでメモリが破損しています(特定の条件下で、問題が大規模なプログラムでのみ発生するという事実を前提としています)。スタックの破損の問題を示す、小さくて完全なコンパイル可能な例を作成できますか?それ以外の場合は、プログラムでメモリの割り当て/割り当て解除をデバッグする必要があります。valgrindglibc mcheckdmallocelectricfenceなど、これを行うのに役立つプログラムはたくさんあります。

于 2010-01-19T06:09:16.957 に答える
2

古いトピックですが、私もこの問題を経験しました。AIX 6.1 での簡単なテスト プログラムを AIX の MALLOCDEBUG と組み合わせて実行すると、この問題が確認されます。

#include <string.h>

int main(void)
{
     char test[32] = "1234";
     char *newbuf = NULL;

     newbuf = strndup(test, sizeof(test)-1);
}

バッファ オーバーフロー検出を使用してプログラムをコンパイルして実行します。

~$ gcc -g test_strndup2.c
~$ MALLOCDEBUG=catch_overflow ./a.out
Segmentation fault (core dumped)

ここで dbx を実行してコアを分析します。

~$  dbx ./a.out /var/Corefiles/core.6225952.22190412
Type 'help' for help.
[using memory image in /var/Corefiles/core.6225952.22190412]
reading symbolic information ...

Segmentation fault in strncpy at 0xd0139efc
0xd0139efc (strncpy+0xdc) 9cc50001        stbu   r6,0x1(r5)
(dbx) where
strncpy() at 0xd0139efc
strndup@AF5_3(??, ??) at 0xd03f3f34
main(), line 8 in "test_strndup2.c"

strndup の命令をたどると、s の文字列と NULL ターミネータを処理するのに十分な大きさのバッファを malloc しているように見えます。ただし、常に n 文字を新しいバッファにコピーし、必要に応じてゼロをパディングするため、strlen(s) < n の場合はバッファ オーバーフローが発生します。

char* strndup(const char*s, size_t n)
{
    char* newbuf = (char*)malloc(strnlen(s, n) + 1);
    strncpy(newbuf, s, n-1);

    return newbuf;
}
于 2012-08-22T19:39:24.343 に答える
1

Alokは正しいです。glibcの下のgccツールチェーンでは、strndupのdeclを取得するために_GNU_SOURCEを定義する必要があります。そうしないと、declされません。例:

#include <string.h>
...

compilo:

gcc -D_GNU_SOURCE a.c
于 2010-01-19T06:14:50.393 に答える