Embarcadero C/C++ Compiler available

J

James Kuyper

Several parts of my previous message (which I just cancelled, but you
may still be able to see it) made no sense due to a stupid thinking
error about the mode argument of fopen(). Please ignore that version, in
favor of this one:

Am 10.05.2013 16:32, schrieb James Kuyper:


Sorry for getting off-topic, but could anyone explain me what on fopen()
might be insecure? ...

I think, at least in this case, that it's more about safety than about
security.
...It does not write to its arguments, expects just
const strings as arguments it has to parse, so how could one use fopen
in a way that breaches security that is not available with fopen_s()?
Ok, shoot yourself in the foot by potentially writing to files you want
to (or need to) keep, but that's not different from fopen_s(), is it?

Here's the declaration for fopen():
FILE *fopen(const char * restrict filename,
const char * restrict mode);

Here's the declaration for fopen_s():
errno_t fopen_s(FILE * restrict * restrict streamptr,
const char * restrict filename,
const char * restrict mode);

There are three mistakes you can make when calling fopen() that
fopen_s() protects against:

FILE *infile = fopen(NULL, inmode);
FILE *outfile = fopen(outfilename, NULL);

These calls have undefined behavior "by the omission of any explicit
definition of behavior" (4p2), since the description of what fopen()
does with its filename and mode arguments (7.21.5.3p2) is meaningless
when either of those arguments is a null pointer. The corresponding code
using fopen_s() has defined behavior: it will make no attempt to open a
file, *streamptr will be set to a null pointer value (K.3.5.2.1p2,3),
and fopen_s() will return a non-zero value. This strikes me as a good idea.

The third mistake would be something like the following:

fopen(outfilename, outmode);

This code opens a file without having any way to do anything with it,
including close it. The corresponding code using fopen_s() would be:

FILE *outfile;
fopen_s(&outfile, outfilename, outmode);

You can still discard outfile immediately, producing the same net
result, but the necessity of creating a valid pointer to a FILE* object
makes it harder to make that particular error accidentally.
 
K

Keith Thompson

Thomas Richter said:
Am 10.05.2013 16:32, schrieb James Kuyper:

Sorry for getting off-topic, but could anyone explain me what on fopen()
might be insecure? It does not write to its arguments, expects just
const strings as arguments it has to parse, so how could one use fopen
in a way that breaches security that is not available with fopen_s()?
Ok, shoot yourself in the foot by potentially writing to files you want
to (or need to) keep, but that's not different from fopen_s(), is it?

I do see the point for sprintf, for example.

See N1570 (available at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) section
K.3.5.2.1, for a description of fopen_s.

The differences from fopen are:
- It returns an errno_t result rather than a FILE*, and "returns" the
FILE* via a pointer-to-pointer parameter.
- It does some stuff with "runtime-constraint violations", which I'm too
lazy to look up and summarize at the moment.
- The mode string can optionally be preceded by a 'u' character.
Without 'u', when creating a file, the permissions are set to prevent
other uses on the system from accessing it "to the extent that the
underlying system supports it"; with 'u', it uses default permissions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top