SystemC error, using visual c++ 2008 - c++

I am using systemC with visual C++ 2008. I wrote a simple hello world program. However I am getting this error repeatedly:
warning C4996: 'sprintf': This function or variable may be unsafe.
Why this is happening? I would appreciate any help.

The compiler warns against sprintf() use because it may cause buffer overflow since it doesn't check buffer's limit. Instead, use snprintf() which never fills the buffer beyond the passed-in limit.
This advice is also given by the manpage:
Because sprintf() and vsprintf() assume an arbitrarily long string, callers must be
careful not to overflow the actual space; this is often impossible to assure. Note that
the length of the strings produced is locale-dependent and difficult to predict. Use
snprintf() and vsnprintf() instead (or asprintf(3) and vasprintf(3)).

It's insecure because - From MSDN
There is no way to limit the number of characters written, which means that code using sprintf is susceptible to buffer overruns. Consider using the related function _snprintf, which specifies a maximum number of characters to be written to buffer, or use _scprintf to determine how large a buffer is required. Also, ensure that format is not a user-defined string.

Related

vswprintf() without buffer size crashes on small buffer instead of EOF. How to pass buffer size

Using Borland C++ Builder 2009
I use vswprintf per RAD Studio's Help (F1) :
int vswprintf(wchar_t *buffer, const wchar_t *format, va_list arglist);
Up to now I always provided a big buffer wchar_t OutputStr[1000] and never had any issues. As a test and wanting to do an improvement action, I tried a small buffer wchar_t OutputStr[12] and noticed that the program crashes entirely. Even try{}catch(...){} doesn't catch it. Codeguard reports that a memcpy() fails, which seems to be the internal implementation. I had expected an EOF as return value instead.
When searching online for vswprintf I find the c++ variant takes a buffer size as input, but I can't seem to convince my compiler to use that variant ?
Any idea how to force it using BCB2009 ?
The whole point of the exercise was to implement a fall back scenario for when the buffer is too small in possibly one or two freak situations, so that I can allocate more memory for the function and try again. But this mechanism doesn't seem to work at all.
Not sure how to best test for the exact amount of bytes/characters needed either ?
You can use vswprintf_s. It returns negative value on failure

Why is strncpy marked as unsafe?

I am getting a warning:
warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
F:\vuStudio\VC\include\string.h(188) : see declaration of 'strncpy'
I read on stackoverflow.com that strcpy is not safe and I should use strncpy instead. But now why I am getting warning that strncpy is unsafe ?
I am calling it as:
strncpy(this->title, title.c_str(), sizeof(this->title));
strncpy has a few dangerous quirks.
First, it zeros the target buffer past the end of the copy, which can be surprising.
Second, if there is not enough room in the target buffer, it does not null terminate the target buffer.
Third, if it truncates, it 'mostly works'. Which discourages error handling (truncated strings are often worse than useless, but do not appear to be worse than useless at first glance).
strncpy_s requires an input length (or explicit truncation request), and errors if there is not enough room to null terminate (writing just a zero length string in the output). The input length is sometimes inefficient to provide (and not required for some of its changes), but it does guarantee a null terminated output buffer (so long as it isn't a nullptr, or zero length) even in error conditions. I am unsure if it zeros past the end of the copied string or not.
This behavior prevents or mitigates some common fenceposting errors in string code.
Visual studio compiler has it's own implementation of strncpy, you won't get this warning with gcc or clang. It is safe, and more portable (because strncpy_s is not standard) to use strncpy.
If you don't care about portability, strncpy_s is indeed more secure because it has an additional length check (but like strncpy it won't save you if you pass bad parameter).
The "n" variants of str functions (like strncmp, strncpy, etc) are the "safe" choice, because they all are limiting the size of string buffer used.
The "old" str functions (not the "n" variants, like strcpy) are all subject to many programming errors and memory attacks (off by one, heap overwriting, etc).

Struggling with sprintf... something stupid?

Sorry to pester everyone, but this has been causing me some pain. Here's the code:
char buf[500];
sprintf(buf,"D:\\Important\\Calibration\\Results\\model_%i.xml",mEstimatingModelID);
mEstimatingModelID is an integer, currently holding value 0.
Simple enough, but debugging shows this is happening:
0x0795f630 "n\Results\model_0.xml"
I.e. it's missing the start of the string.
Any ideas? This is simple stuff, but I can't figure it out.
Thanks!
In an effort to make this an actual general answer: Here's a checklist for similar errors:
Never trust what you see in release mode, especially local variables that have been allocated from stack memory. Static variables that exist in heap data are about the only thing that will generally be correct but even then, don't trust it. (Which was the case for the user above)
It's been my experience that the more recent versions of VS have less reliable release mode data (probably b/c they optimize much more in release, or maybe it's 64bitness or whatever)
Always verify that you are examining the variable in the correct function. It is very easy to have a variable named "buf" in a higher function that has some uninitialized garbage in it. This would be easily confused with the same named variable in the lower subroutine/function.
It's always a good idea to double check for buffer overruns. If you ever use a %s in your sprintf, you could get a buffer overrun.
Check your types. sprintf is pretty adaptable and you can easily get a non-crashing but strange result by passing in a string pointer when an int is expected etc.

Safe counterparts of itoa()?

I am converting some old c program to a more secure version. The following functions are used heavily, could anyone tell me their secure counterparts? Either windows functions or C runtime library functions. Thanks.
itoa()
getchar()
strcat()
memset()
itoa() is safe as long as the destination buffer is big enough to receive the largest possible representation (i.e. of INT_MIN with trailing NUL). So, you can simply check the buffer size. Still, it's not a very good function to use because if you change your data type to a larger integral type, you need to change to atol, atoll, atoq etc.. If you want a dynamic buffer that handles whatever type you throw at it with less maintenance issues, consider an std::ostringstream (from the <sstream> header).
getchar() has no "secure counterpart" - it's not insecure to begin with and has no buffer overrun potential.
Re memset(): it's dangerous in that it accepts the programmers judgement that memory should be overwritten without any confirmation of the content/address/length, but when used properly it leaves no issue, and sometimes it's the best tool for the job even in modern C++ programming. To check security issues with this, you need to inspect the code and ensure it's aimed at a suitable buffer or object to be 0ed, and that the length is computed properly (hint: use sizeof where possible).
strcat() can be dangerous if the strings being concatenated aren't known to fit into the destination buffer. For example: char buf[16]; strcpy(buf, "one,"); strcat(buf, "two"); is all totally safe (but fragile, as further operations or changing either string might require more than 16 chars and the compiler won't warn you), whereas strcat(buf, argv[0]) is not. The best replacement tends to be a std::ostringstream, although that can require significant reworking of the code. You may get away using strncat(), or even - if you have it - asprintf("%s%s", first, second), which will allocate the required amount of memory on the heap (do remember to free() it). You could also consider std::string and use operator+ to concatenate strings.
None of these functions are "insecure" provided you understand the behaviour and limitations. itoa is not standard C and should be replaced with sprintf("%d",...) if that's a concern to you.
The others are all fine to the experienced practitioner. If you have specific cases which you think may be unsafe, you should post them.
I'd change itoa(), because it's not standard, with sprintf or, better, snprintf if your goal is code security. I'd also change strcat() with strncat() but, since you specified C++ language too, a really better idea would be to use std::string class.
As for the other two functions, I can't see how you could make the code more secure without seeing your code.

Using sprintf without a manually allocated buffer

In the application that I am working on, the logging facility makes use of sprintf to format the text that gets written to file. So, something like:
char buffer[512];
sprintf(buffer, ... );
This sometimes causes problems when the message that gets sent in becomes too big for the manually allocated buffer.
Is there a way to get sprintf behaviour without having to manually allocate memory like this?
EDIT: while sprintf is a C operation, I'm looking for C++ type solutions (if there are any!) for me to get this sort of behaviour...
You can use asprintf(3) (note: non-standard) which allocates the buffer for you so you don't need to pre-allocate it.
No you can't use sprintf() to allocate enough memory. Alternatives include:
use snprintf() to truncate the message - does not fully resolve your problem, but prevent the buffer overflow issue
double (or triple or ...) the buffer - unless you're in a constrained environment
use C++ std::string and ostringstream - but you'll lose the printf format, you'll have to use the << operator
use Boost Format that comes with a printf-like % operator
I dont also know a version wich avoids allocation, but if C99 sprintfs allows as string the NULL pointer. Not very efficient, but this would give you the complete string (as long as enough memory is available) without risking overflow:
length = snprintf(NULL, ...);
str = malloc(length+1);
snprintf(str, ...);
"the logging facility makes use of sprintf to format the text that gets written to file"
fprintf() does not impose any size limit. If you can write the text directly to file, do so!
I assume there is some intermediate processing step, however. If you know how much space you need, you can use malloc() to allocate that much space.
One technique at times like these is to allocate a reasonable-size buffer (that will be large enough 99% of the time) and if it's not big enough, break the data into chunks that you process one by one.
With the vanilla version of sprintf, there is no way to prevent the data from overwriting the passed in buffer. This is true regardless of wether the memory was manually allocated or allocated on the stack.
In order to prevent the buffer from being overwritten you'll need to use one of the more secure versions of sprintf like sprintf_s (windows only)
http://msdn.microsoft.com/en-us/library/ybk95axf.aspx