What happened to strcmp?

In answering the question Reading in a line and comparing it with C more than one person did not encourage the use of strcmp() , saying things like

I also highly recommend that you get used to using strncmp () now ... to avoid many problems in the future.

or (in Why does my string comparison fail? )

Make sure you use strncmp and not strcmp. strcmp is deeply insecure.

What problems are they hinting at?

The reason scanf() with line qualifiers and gets() very discouraged because they almost inevitably lead to buffer overflow vulnerabilities. However, it is not possible to overflow the buffer with strcmp() , right?

"A buffer overflow or buffer overflow is an anomaly when a program overwrites a buffer boundary and overwrites neighboring memory when writing data to the buffer."

(- Wikipedia: buffer overflow ).

Since the strcmp () function never writes a single buffer, the strcmp () function cannot cause a buffer overflow, right?

What is the reason people do not recommend using strcmp() and instead recommend strncmp() ?

+6
source share
3 answers

While strncmp can prevent you from intercepting a buffer, its main purpose is not safe. Rather, it exists for the case when you need to compare only the first N characters of the string ( correctly , possibly with zero termination).

On the page :

The strcmp() function compares two strings s1 and s2 . It returns an integer less than, equal to or greater than zero, if s1 found, respectively, less to match or be greater than s2 .

The strncmp() function is similar, except that it only compares the first (at most) n bytes s1 and s2 .

Note that strncmp cannot be replaced with simple strncmp in this case, because you still need to use its stop-on-NUL behavior if one of the lines is shorter than n .

If strcmp causes a buffer overflow, then one of two things is true:

  • Your data should not be NUL-terminated, and you should use memcmp .
  • It is expected that your data will be completed using the NUL, but you already messed up when you filled the buffer, somehow not completing its NUL.

Note that reading beyond the end of the buffer is still considered buffer overflow. . Although this may seem harmless, it can be as dangerous as writing at the end.

Reading, writing, fulfilling ... it doesn't matter. Any memory link to an unintended address is undefined. In the most obvious scenario, you are trying to access a page that does not appear in the address space of your process, which results in a page error and subsequent SIGSEGV. In the worst case, you sometimes run byte \ 0, but in other cases, you run some other buffer, causing inconsistent program behavior.

+14
source

A string is by definition a "continuous sequence of characters ending in and including the first null character".

The only case where strncmp() would be safer than strcmp() , when you compare two character arrays as strings, you are sure that both arrays are at least n bytes long (the third argument passed to strncmp() ), and you not sure if both arrays contain strings (i.e. contain the terminator character '\0' ).

In most cases, your code (if correct) ensures that any arrays that must contain null-terminated strings do indeed contain null-terminated strings.

This added n to strncmp() not a magic wand that makes safe code safe. It does not protect against null pointers, uninitialized pointers, uninitialized arrays, an invalid value of n or simply passes invalid data. You can shoot yourself in the foot with any function.

And if you are trying to call strcmp or strncmp with an array that, in your opinion, contains a string with a terminating zero, but does not actually do this, your code already has an error. Using strncmp() can help you avoid the immediate symptom of this error, but it will not be fixed.

+5
source

strcmp compares the character of two lines with the character until a difference is found, or \0 not found in one of them.

On the other hand, strncmp provides a way to limit the number of characters to compare, so if the lines do not end with \0 , the function will not continue checking after reaching the size limit.

Imagine what happens if you compare two lines in these two memory areas:

0x40, 0x41, 0x42,... 0x40, 0x41, 0x42,...

And you are only interested in the first two characters. Somehow, \0 was removed from the end of the lines, and the third byte matches the two regions. strncmp will avoid comparing this third byte if the num parameter is 2.

EDIT As can be seen from the comments below, this situation stems from improper or very specific use of the language.

+1
source

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


All Articles