古いトピックですが、私もこの問題を経験しました。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;
}