English 中文(简体)
strndup call is currupting stack frames
原标题:
  • 时间:2010-01-19 06:05:23
  •  标签:
  • c
  • aix

I have seen a strange behavior with "strndup" call on AIX 5.3 and 6.1. If I call strndup with size more than the size of actual source string length, then there is a stack corruption after that call.

Following is the sample code where this issue can come:

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;
}

Does anybody have experienced this behavior?

If yes please let me know.

As per my observation, there must be a patch from OS where this issue got fixed. but i could not get that patch if at all there is any. Please throw some light.

Thanks & Regards, Thumbeti

问题回答

You are missing a #include <string.h> in your code. Please try that—I am fairly sure it will work. The reason is that without the #include <string.h>, there is no prototype for strndup() in scope, so the compiler assumes that strndup() returns an int, and takes an unspecified number of parameters. That is obviously wrong. (I am assuming you re compiling in POSIX compliant mode, so strndup() is available to you.)

For this reason, it is always useful to compile code with warnings enabled.

If your problem persists even after the change, there might be a bug.

Edit: Looks like there might be a problem with strndup() on AIX: the problem seems to be in a broken strnlen() function on AIX. If, even after #include <string.h> you see the problem, it is likely you re seeing the bug. A google search shows a long list of results about it.

Edit 2:

Can you please try the following program and post the results?

#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<
",verify);
     if (strcmp(control, verify))
         printf("strndup is broken
");
}

(Taken from https://bugzilla.samba.org/show_bug.cgi?id=1097#c10.)

Edit 3: After seeing your output, which is >01234567890123456789012345678<, and with no strndup is broken, I don t think your version of AIX has the strndup bug.

Most likely you are corrupting memory somewhere (given the fact that the problem only appears in a large program, under certain conditions). Can you make a small, complete, compilable example that exhibits the stack corruption problem? Otherwise, you will have to debug your memory allocation/deallocation in your program. There are many programs to help you do that, such as valgrind, glibc mcheck, dmalloc, electricfence, etc.

Old topic, but I have experienced this issue as well. A simple test program on AIX 6.1, in conjunction with AIX s MALLOCDEBUG confirms the issue.

#include <string.h>

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

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

Compile and run the program with buffer overflow detection:

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

Now run dbx to analyze the core:

~$  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"

Tracing through the instructions in strndup, it appears that it mallocs a buffer that is just large enough to handle the string in s plus a NULL terminator. However, it will always copy n characters to the new buffer, padding with zeros if necessary, causing a buffer overflow if 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;
}

Alok is right. and with the gcc toolchain under glibc, you would need to define _GNU_SOURCE to get the decl of strndup, otherwise it s not decl d, e.g.:

#include <string.h>
...

compilo:

gcc -D_GNU_SOURCE a.c

Thanks a lot for your prompt responses. I have tried the given program.

following is the result:

bash-2.05b# ./mystrndup3
>01234567890123456789012345678<

In my program I have included , still problem is persistent. Following is the strndup declaration in prepossessed code.

extern char * strndup(const char *, size_t);

I would like to clarify one thing, with small program I don t get effect of stack corruption. It is consistently appearing in my product which has huge amount of function calls.

Using strndup in the following way solved the problem:

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

Please note: used strlen instead of sizeof as i need only the valid string. I am trying to understand why it is happening.

Behavior i am seeing with my product when i use strndup with large size:

  1. At the "exit" of main, execution is coring with "illegal instruction"
  2. intermittently "Illegal Instruction" in the middle of execution (after strndup call).
  3. Corrupt of some allocated memory, which is no where related to strndup.

All these issues are resolved by just modifying the usage of strndup with actual size of source string.

Thanks & Regards, Thumbeti





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签