Is strcpy always dangerous?

Are functions like strcpy, gets, etc. always dangerous? What if I write this code:

int main(void) { char *str1 = "abcdefghijklmnop"; char *str2 = malloc(100); strcpy(str2, str1); } 

Thus, the function does not accept arguments (parameters ...), and the str variable will always be the same length ... which is 16 here or a little more depending on the version of the compiler ... but yes 100 will be enough from March 2011 :). Is there a way for a hacker to use the code above? 10x!

+4
source share
9 answers

Absolutely not. Unlike Microsoft's marketing campaign, strcpy is safe to use for its non-standard features.

The above is redundant, but mostly safe. The only potential problem is that you are not checking the returned malloc value, so that you can dereference zero (as indicated by kotlinski). In practice, this can lead to the immediate termination of SIGSEGV and termination of the program.

Improper and dangerous use:

 char array[100]; // ... Read line into uncheckedInput // Extract substring without checking length strcpy(array, uncheckedInput + 10); 

This is unsafe because strcpy can overflow, causing undefined behavior. In practice, this is likely to overwrite other local variables (which in itself is a serious security breach). One of them may be a return address. Using a return to lib C attack, an attacker could use C functions, such as system , to execute arbitrary programs. There may be other consequences for overflow.

However, gets really unsafe and will be removed from the next version of C (C1X). There is simply no way to guarantee that the input will not overflow (leading to the same consequences given above). Some people find this safe when used with a known input file, but there really is no reason to use it. POSIX getline is a much better alternative.

In addition, the length of str1 not dependent on the compiler. It should always be 17, including the terminating NUL.

+14
source

You forcefully stuff completely different things into one category.

The gets functions are really always dangerous. It is impossible to make a secure call gets no matter what steps you are ready to take, and how to defend you are ready to receive.

The strcpy function is completely safe if you are ready to take the [simple] necessary steps to make sure your calls to strcpy safe.

This already puts gets and strcpy in completely different categories that have nothing to do with security.

Popular criticism of strcpy security aspects is based solely on anecdotal social observations, rather than formal facts, for example. "programmers are lazy and incompetent, so don't let them use strcpy ." In the context of C programming, this is, of course, complete nonsense. Following this logic, we must also declare the partition operator just as unsafe for the same reasons.

In fact there is no problem with strcpy . gets , on the other hand, a completely different story, as I said above.

+4
source

Yes, it’s dangerous. After 5 years of service, your code will look like this: int main (void) {

char * str1 = "abcdefghijklmnop";

{enough rows were inserted here so that str1 and str2 were not nice and close to each other on the screen}

char * str2 = malloc (100); strcpy (str2, str1);

}

at that moment someone will go and change str1 to

str1 = "THIS IS A REALLY LONG LINE THAT NOW TRANSFERS ANY BOOFERS USED FOR COPYING THIS IF THE PRECAUTIONS ARE TAKEN TO SHORTLY, SHORTLY, SHORTLY.

and forget to see where str1 is used and then random errors will start ...

+4
source

strcpy not dangerous as far as you know that the destination buffer is large enough to hold the characters of the original string; otherwise strcpy will gladly copy more characters than your target buffer can hold, which can lead to several unfortunate consequences (rewriting strings and other variables, which can lead to crashes, stack-breaking attacks and co.).

But: if you have a common char * input that has not yet been verified, the only way to make sure is to apply strlen to such a string and check if this is too much for your buffer; however, now you need to go through the entire source line twice, once to check its length, once to make a copy.

This is suboptimal, since if strcpy was a little more advanced, it could get the buffer size as a parameter and stop copying if the source string was too long; in a perfect world, this is how strncpy will execute (following the diagram of other strn*** functions). However, this is not an ideal world, and strncpy not intended for this. Instead, a non-standard (but popular) alternative is strlcpy , which truncates instead of exiting the boundaries of the target buffer.

Several CRT implementations do not provide this function (especially glibc), but you can still get one of the BSD implementations and put it in your application. A standard (but slower) alternative would be to use snprintf with "%s" as the format string.

However, since you are programming in C ++ ( edit , now I see that the C ++ tag has been removed), why don't you just avoid all the errors in the C-string (when you can, obviously) and go with std::string ? All of these potential security issues disappear, and string operations become much simpler.

+1
source

The only way malloc can fail is when an out-of-memory error occurs, which in itself is a disaster. You cannot reliably restore it, because almost anything can cause it again, and the OS will probably kill your process anyway.

+1
source

Your code is unsafe. The returned malloc value is not checked, if it fails and returns 0, strcpy will give undefined behavior.

In addition, I see no problem, except that the example basically does nothing.

0
source

As you point out, under limited circumstances strcpy is not dangerous. It is more typical to take a string parameter and copy it to a local buffer, and this is when things can become dangerous and lead to a buffer overflow. Just remember to check the length of your copy before calling strcpy and null. Then complete the line.

0
source

Besides the potential dereferencing of NULL (since you are not checking the result from malloc), which is UB and probably does not pose a security risk, there is no potential security problem with this.

0
source

gets() always insecure ; Other functions can be used safely.
gets() not safe even if you have full control over the input - someday, the program may be launched by someone else.

The only safe way to use gets() is to use it for a single run: create a source; compilation; run; delete the binary and source; interpret the results.

0
source

Source: https://habr.com/ru/post/1343839/


All Articles