简体   繁体   中英

Accessing string that was passed as argument causes stack buffer overflow

I'm studying C at uni and am trying to access the string (the string representation of a binary-number) that was passed into a function to convert it into the integer-representation of that string.

Eg. "011" should return 3 .

The string is the first 3 bits in a bitstream that's inputted in reverse.

char * temp_holder = (char *)malloc(sizeof(char) * 4);

int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
    printf("%c", buffer[i]);
    temp_holder[index_of_holder] = buffer[i];
}
printf("\n");

int decimalValue = fromBinaryToInt(&temp_holder, 3);
printf("DECIMAL_VALUE: %d\n", decimalValue);

The fromBinaryToInt function is:

int fromBinaryToInt(char *string[], int length){

    for(int i = 0; i < length; i++){
        printf("%c", *string[i]);
    }

    int int_rep = strtol(*string, (char **)NULL, 2);

    printf("REP: %d\n", int_rep);

    return int_rep;
}

The subsequent error I get is:

==21==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffda9f47a08 at pc 0x000000500cdf bp 0x7ffda9f47980 sp 0x7ffda9f47978 - READ of size 8 at 0x7ffda9f47a08 thread T0

I thought this could be due to the null-terminating character so I played around with modifying the length variable (+/- 1) in the for-loop within fromBinaryToInt but that hasn't changed anything.

I also considered the for-loop only accessing the first element and nothing more - but my understanding is I've sent through the memory address and the length of the block so the for-loop should have access to the indexes.

Any help would be greatly appreciated, Cheers :)

In this code:

int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
    printf("%c", buffer[i]);
    temp_holder[index_of_holder] = buffer[i];
}

index_of_holder is never changed, so all the characters are put in temp_holder[0] . The rest of temp_holder remains uninitialized.

This:

int fromBinaryToInt(char *string[], int length)

declares string to be an array of pointers to char . It is indeed passed &temp_holder , which may be considered to be a pointer to the first element of an array of one pointer to char . However, a more normal usage is to declare a simple pointer to char

int fromBinaryToInt(char *string, int length)

and pass it temp_holder , as in fromBinaryToInt(temp_holder, 3) .

As it is, where it is used here:

printf("%c", *string[i]);

This takes element i of the array. When i is 0 in the loop, that is fine, it takes the first element, which exists and is a pointer to char , and then deferences it with * and prints that. However, when i is 1, it attempts to take the second element of the array. That element does not exist, and the resulting behavior is undefined.

If the parameter were merely char *string , then this printf could be:

printf("%c", string[i]);

and, in calling strtol , you would simply pass string rather than *string :

int int_rep = strtol(string, (char **)NULL, 2);

Firstly, bug in below line, index_of_holder remains same all the time, please increment it.

temp_holder[index_of_holder] = buffer[i]; 

Secondly, in fromBinaryToInt() string is single pointer only so you can't do *string[i]); in the next printf statement.

Here is the working code

int fromBinaryToInt(char *string, int length){

        for(int i = 0; i < length; i++){
                printf("%c", string[i] ); /*since string is single pointer now you can do like before you did */
        }

        int int_rep = strtol(string, (char **)NULL, 2);

        printf("REP: %d\n", int_rep);

        return int_rep;
}
int main() {
        char * temp_holder = (char *)malloc(sizeof(char) * 4);
        char buffer[4] ="011";
        int index_of_holder = 0;
        for(int i = 2; i >= 0; i--){
                printf("%c", buffer[i]);
                temp_holder[index_of_holder] = buffer[i];
                index_of_holder++;
        }
        printf("\n");

        int decimalValue = fromBinaryToInt(temp_holder, 3);/* no need to pass address of temp_holder */
        printf("DECIMAL_VALUE: %d\n", decimalValue);
        return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM