0

I am writing some programs in C (rarely C++). Normally they are simple, but often they can get larger.

I am looking to learn more about using the secure versions of functions, for example strcpy() is insecure and strcpy_s() is Microsoft's new secure version of that function.

I normally use Visual Studio 2010 when coding for Windows * I removed part about Linux - focus on Windows only*

My question is if I use the newer secure version will I still be able to execute my programs on older versions of Windows, for example Windows 95? Due to requirements we can only have a single executable file.

Thank you.

EDIT: Sorry this just appeared in my mind now - ignore the Linux part above. If we write code for Windows I do not mind if it's not portable to Linux, I only care if it still works on older versions of Windows.

securityauditor
  • 293
  • 3
  • 13
  • 1
    I would remove the `c++` tag from this question. I believe the _s versions are non standard Microsoft additions however I am a `c++` programmer and never ever use these. – drescherjm Jan 09 '19 at 14:23
  • Why remove the C++ tag since I sometimes code in C++, or is it these secure versions only exist for C? – securityauditor Jan 09 '19 at 14:25
  • 3
    @securityauditor Because tags should describe what the question is about. – Lundin Jan 09 '19 at 14:27
  • 1
    They exist in `c++` but `c++` has better ways of using strings in the standard library. – drescherjm Jan 09 '19 at 14:28
  • Lundin Well it's about using C and C++ with the standard library which is what my code bases use. I do not want to update each one to then not be able to execute them on our old legacy Win 2000 etc... computers! – securityauditor Jan 09 '19 at 14:29
  • 1
    Personally I feel it is debatable if these functions add any real security. Also, generally in `C++` code, you would not be handling raw buffers that do not know their length. That's one of the main benefits of OO. – Galik Jan 09 '19 at 14:33
  • 1
    "If we write code for Windows I do not mind if it's not portable to Linux" - I'd caution against that unless it's purely Win32 gui / api stuff. – Bathsheba Jan 09 '19 at 14:53

3 Answers3

9

strcpy is perfectly safe, see this.

strcpy_s was only standardized as late as 2011 in the C11 optional bounds-checking interface. It is not supported by many compilers at all - the new library was a fiasco.

Microsoft non-standard libraries are only partially compatible with the standardized bounds-checking interface. In some cases they don't follow the standard but have the same function name.

Thus functions ending with _s are generally unsafe, since both standard and non-standard versions exists and are not necessarily compatible. They are certainly not portable.

My advise is to avoid the following entirely:

  • The C11 bounds-checking interface.
  • Any function ending with _s.
  • Visual Studio for the purpose of compiling C code.

Instead use the safe and portable function strcpy which has been standardized and documented for over 30 years. Together with this, you should use an ISO C standard compliant compiler.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    Upped; nice and sensible. – Bathsheba Jan 09 '19 at 14:41
  • 1
    UV warranted by "the new library was a fiasco" alone. – John Bollinger Jan 09 '19 at 14:44
  • Indeed. [**Field Experience With Annex K — Bounds Checking Interfaces**](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm): "Microsoft Visual Studio implements an early version of the APIs. However, the implementation is incomplete and conforms neither to C11 nor to the original TR 24731-1. ... As a result of the numerous deviations from the specification the Microsoft implementation cannot be considered conforming or portable." – Andrew Henle Jan 10 '19 at 16:10
  • More detailed post here: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518) – Lundin Aug 10 '21 at 06:45
4

Avoid strcpy_s() if you want to write portable C (or C++) as it's a non-standard function.

strncpy() is the standard way of copying up to a certain number of characters, and can help guard against buffer overrun for which the term "security" is abused.

There's nothing wrong with using strcpy so long as you know what you're doing. Much of this sentiment applies to C in general: its power is in its simplicity and minimal run-time checking.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Buffer overrun has plenty to do with security. Do you know how many vulnerabilities are exploitable through buffer overruns? – Lightness Races in Orbit Jan 09 '19 at 14:33
  • Granted, there are other ways to avoid such a bug and fix that security problem ;) – Lightness Races in Orbit Jan 09 '19 at 14:34
  • @LightnessRacesinOrbit: Yup, I had a warped childhood and had a lot of fun on the exploiting side ;-) "atdt" still rings in my lugholes. – Bathsheba Jan 09 '19 at 14:35
  • `strncpy` is **not** acceptable substitute when speaking about protecting against buffer overruns. – user694733 Jan 09 '19 at 14:36
  • @LightnessRacesinOrbit `strcpy` has nothing to do with buffer overruns. To protect against buffer overruns, you verify the data _before_ you copy. – Lundin Jan 09 '19 at 14:38
  • @LightnessRacesinOrbit Adding a length parameter does not guarantee you won't overrun a buffer. It gives you additional code-sites where you have to make the same change when you come to maintain the code and more chances for error if you forget one imo. It is a choice between getting the code correct in one place (the caller) or trying to get the code right every time you use a function (in the callee). – Galik Jan 09 '19 at 14:40
  • @Galik Maybe. There's ways to minimise that risk to the point that it's better than the risk of having no length checking at all. IMO those ways are numerous and easy when compared to the ghastly alternative. But YMMV – Lightness Races in Orbit Jan 09 '19 at 14:45
3

My question is if I use the newer secure version will I still be able to execute my programs on older versions of Windows, for example Windows 95? Due to requirements we can only have a single executable file.

The _s versions are not "secure", whether you're talking about Microsoft's implementations or implementations conforming to the actual standard. They do incorporate mechanisms intended to help avoid or mitigate certain programming errors that have security implications, but the effectiveness of those is limited.

But with respect to whether they will be supported on very old Windows versions, no, not by default. The _s functions did not exist during Windows 95's lifetime, so versions of the C runtime library distributed with that version of Windows do not support them. It is relatively common, however, for Windows applications to be packaged with a version of the MS C runtime library that supports their needs. It may be that you can take that route, but I cannot speak to whether there is any version of the MS C runtime that supports all Windows versions from the past 24 years and contains the _s functions.

Your best bet is to limit yourself to functions from the C90 standard library, WinAPI functions supported across all targeted Windows versions, and functions provided by your application itself and any third-party libraries distributed with it (which themselves should comply with the same limitations). Or you could consider limiting support to fewer versions of Windows. Microsoft itself has not supported Windows 95 for 18 years.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157