Author Topic: 'strcpy' unsafe?  (Read 807 times)

Ad_Rienks

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
'strcpy' unsafe?
« on: June 22, 2024, 12:13:10 AM »
I just translated some basic code into C with BCX 8.1.0.

I want to use the emitted C code in a Visual Studio project. There I get the error message that using 'strcpy' might be unsafe. Consider using strcpy_s, or another alternative.
 
I have posed the question to ChatGPT too, and the answer is:
"The warning you're seeing is due to the fact that strcpy does not perform bounds checking, which can lead to buffer overflows and potential security vulnerabilities. The strcpy_s function is a safer alternative introduced in the C11 standard and by Microsoft in their C runtime library. It includes additional parameters to specify the size of the destination buffer, helping to prevent buffer overflows."

You, developers of BCX, use `strcpy` in a lot of places; apparently, you are not impressed by that possible unsafety. Or you are not aware of it, which I find extremely unlikely!

I am very curious to hear your opinion in this issue. Should I consider replacing all occurances of `strcpy'?

Or, should I use _CRT_SECURE_NO_WARNINGS to disable deprecation; that is what Visual Studio offers as an alternative?

EDIT: I just had a closer look at the emitted code and saw these lines in the head:

#ifdef _MSC_VER
  #ifndef _CRT_SECURE_NO_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
  #endif
#endif

So that answers my question for the most part. You are aware of the `strcpy`warning and have chosen this approach!
« Last Edit: June 22, 2024, 12:18:33 AM by Ad_Rienks »

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2476
    • View Profile
Re: 'strcpy' unsafe?
« Reply #1 on: June 22, 2024, 07:39:39 AM »
Hello Ad,

Yes ... I and many others have been aware of the safe string library for many years.
I personally see the safe string library as pointless because I believe it is no more
safe than what has been used for 75 years.

I posed the following question to ChatGPT a few minutes ago:

There are millions of lines of code that use strcpy. I am aware that strcpy_s is designed to make string copying safer and I understand how it claims to achieve that. However, it doesn't take much imagination to counter those claims, considering that the third argument of strcpy_s can hold a flawed value, leading to an immediate buffer overrun. Additionally, strcpy_s and likely all of the so-called "safe strings" take longer to complete their function, resulting in measurably slower application times.

What is the adoption rate of the "safe string" library, and are there any truly compelling expert opinions to support its use?


Here is ChatGPT's response:


The adoption rate of "safe string" functions like strcpy_s varies across different programming environments and industries. These functions are primarily promoted by Microsoft and have been integrated into the Microsoft C Runtime Library. Their usage is more prevalent in environments where security and robustness are critical, such as in enterprise and government software development​.

One of the main arguments for using strcpy_s and similar functions is to enhance security by preventing buffer overflows. These functions include additional parameters that specify the size of the destination buffer, enabling the function to check and ensure that the buffer is large enough to hold the copied string. This reduces the risk of buffer overruns, which are common vulnerabilities in software that can lead to security breaches​​.

However, there are concerns and criticisms about these functions. Critics argue that the third argument in strcpy_s (the size of the destination buffer) can still be flawed, potentially leading to the same vulnerabilities it aims to prevent. Moreover, the additional checks performed by these functions can result in longer execution times, potentially slowing down applications, especially those where performance is critical​​.

In terms of expert opinions
, while many security professionals advocate for the use of these safer functions to mitigate risks associated with buffer overflows, others highlight that proper coding practices and thorough validation of input and output sizes are equally effective in preventing such vulnerabilities. Additionally, some experts argue that relying on these non-standard, Microsoft-specific functions can lead to portability issues and lock the codebase into a specific platform​.

In summary, while strcpy_s and similar functions offer a layer of safety by design, their adoption should be considered within the context of the specific requirements and constraints of the project, and balanced with best coding practices and performance considerations.





« Last Edit: June 22, 2024, 08:43:18 AM by MrBcx »

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2476
    • View Profile
Re: 'strcpy' unsafe?
« Reply #2 on: June 22, 2024, 08:40:28 AM »
Here is a little more to chew on - I compiled this with my various c/c++ compilers

Code: [Select]
DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null

a$ = "This string obviously has more than 4 letters in it"

strcpy_s (b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PAUSE

Pelles C could not compile it at all because strcpy_s does not exist in any header files.

Lcc-Win32 compiled and popped up a runtime assertion error:
In function strcpy_s, assertion s1max <=RSIZE_MAX failed. (as I expected)
( I was impressed by that! )

Mingw (Nuwen) compiled and ran it with no visible problems.  (That seems particularly scary to me) (this was unexpected)

MSVC (crt and ucrt) compiled fine but when run both exe versions immediately crashed (as I expected)

Embarcadero compiled and when executed displayed: strcpy_s  Abnormal program termination (as I expected)


« Last Edit: June 22, 2024, 11:37:58 AM by MrBcx »

Ed Davis

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: 'strcpy' unsafe?
« Reply #3 on: June 22, 2024, 11:58:09 AM »
It is a shame that the sanitizers don't work the same on Windows.

I changed the code so I could compile it with gcc on linux, with gcc -fsanitize=address,undefined foo.c

It generated a runtime error.

On Windows, using the sanitizers with MSVC:

cl /Zi /fsanitize=address  foo.c

But no runtime error is generated when foo runs :(


Robert

  • Hero Member
  • *****
  • Posts: 1314
    • View Profile
Re: 'strcpy' unsafe?
« Reply #4 on: June 22, 2024, 03:54:38 PM »
Here is a little more to chew on - I compiled this with my various c/c++ compilers

Code: [Select]
DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null

a$ = "This string obviously has more than 4 letters in it"

strcpy_s (b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PAUSE

Pelles C could not compile it at all because strcpy_s does not exist in any header files.

Lcc-Win32 compiled and popped up a runtime assertion error:
In function strcpy_s, assertion s1max <=RSIZE_MAX failed. (as I expected)
( I was impressed by that! )

Mingw (Nuwen) compiled and ran it with no visible problems.  (That seems particularly scary to me) (this was unexpected)

MSVC (crt and ucrt) compiled fine but when run both exe versions immediately crashed (as I expected)

Embarcadero compiled and when executed displayed: strcpy_s  Abnormal program termination (as I expected)

Pelles C has support for all safe string functions.
In the Pelles help file search for TR24731-1

Code: [Select]
$DEFINE __STDC_WANT_LIB_EXT1__ 1

DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null
DIM AS SIZE_T errnum

a$ = "This string obviously has more than 4 letters in it"

errnum = strcpy_s(b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PRINT errnum

PAUSE

Result:

Code: [Select]
This string obviously has more than 4 letters in it
 34

Robert

  • Hero Member
  • *****
  • Posts: 1314
    • View Profile
Re: 'strcpy' unsafe?
« Reply #5 on: June 22, 2024, 03:59:39 PM »
Good discussion

Do you use the TR 24731 'safe' functions?

here

https://stackoverflow.com/questions/372980/do-you-use-the-tr-24731-safe-functions

Robert

  • Hero Member
  • *****
  • Posts: 1314
    • View Profile
Re: 'strcpy' unsafe?
« Reply #6 on: June 22, 2024, 04:11:34 PM »
Code: [Select]
DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null
DIM AS SIZE_T errnum

a$ = "This string obviously has more than 4 letters in it"

errnum = strcpy_s(b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PRINT errnum

PAUSE


Nuwen, LLVM-MinGW Result:

Code: [Select]
This string obviously has more than 4 letters in it
 34

MSVC and LLVM Result:

Compiled, no warnings, but no output when run.



MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2476
    • View Profile
Re: 'strcpy' unsafe?
« Reply #7 on: June 22, 2024, 05:12:20 PM »
Good discussion

Do you use the TR 24731 'safe' functions?

here

https://stackoverflow.com/questions/372980/do-you-use-the-tr-24731-safe-functions

Hi Robert ,

Not surprising, I am squarely in the camp that agrees with Robert Gamble's opinion over at SO.

I didn't know about the $DEFINE __STDC_WANT_LIB_EXT1__ 1 in Pelles C, so thanks for that.

I earlier grepped Pelles' include folder but didn't get a hit on strcpy_s which, I admit, I did find surprising.


MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2476
    • View Profile
Re: 'strcpy' unsafe?
« Reply #8 on: June 22, 2024, 05:37:08 PM »
Code: [Select]
DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null
DIM AS SIZE_T errnum

a$ = "This string obviously has more than 4 letters in it"

errnum = strcpy_s(b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PRINT errnum

PAUSE


Nuwen, LLVM-MinGW Result:

Code: [Select]
This string obviously has more than 4 letters in it
 34

MSVC and LLVM Result:

Compiled, no warnings, but no output when run.

A mild curiosity -- have you found what error code 34 means?

When I run the Nuwen built version, although the PAUSE command seems to work,
when I Press any key to continue . . ., it takes 1 - 2 seconds for the console
to close which feels a little "crashy" to me.

Re: MSVC/Clang  Compiled, no warnings, but no output when run.

That's right - Even the PAUSE command failed as well which screams C R A S H to me.




Robert

  • Hero Member
  • *****
  • Posts: 1314
    • View Profile
Re: 'strcpy' unsafe?
« Reply #9 on: June 22, 2024, 10:44:48 PM »
Code: [Select]
DIM a$ * 2048   ' This variable can hold 2047 chars + the terminating null
DIM b$ * 5      ' This variable can hold    4 chars + the terminating null
DIM AS SIZE_T errnum

a$ = "This string obviously has more than 4 letters in it"

errnum = strcpy_s(b, strlen(a), a)  ' Intentionally cause a memory overflow with the "safe string" function

PRINT a$
PRINT errnum

PAUSE


Nuwen, LLVM-MinGW Result:

Code: [Select]
This string obviously has more than 4 letters in it
 34

MSVC and LLVM Result:

Compiled, no warnings, but no output when run.

A mild curiosity -- have you found what error code 34 means?

When I run the Nuwen built version, although the PAUSE command seems to work,
when I Press any key to continue . . ., it takes 1 - 2 seconds for the console
to close which feels a little "crashy" to me.

Re: MSVC/Clang  Compiled, no warnings, but no output when run.

That's right - Even the PAUSE command failed as well which screams C R A S H to me.

Constant ERANGE, value 34, defined in #include <errno.h>

Quote
Result too large. An argument to a math function is too large, resulting in partial or total loss of significance in the result. This error can also occur in other functions when an argument is larger than expected (for example, when the buffer argument to _getcwd is longer than expected).

Quote from

https://learn.microsoft.com/en-us/cpp/c-runtime-library/errno-constants?view=msvc-170