Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Portability is an important issue to keep in mind a concern when using the fread() and fwrite() functions across multiple, heterogeneous systems. In particular, it is never guaranteed that reading or writing of simple scalar data structures types such as int'sintegers, let alone complex structures aggregate types such as float's or struct'sarrays or structures, will preserve the representation or value of the data. Different compilers use different amounts of padding. Different machines use various floating point models and may use a different Implementations may differ in structure padding, floating-point model, number of bits per byte. In addition, there is always the issue of endianness.

...

endianness, and other attributes that cause binary data formats to be incompatible.

Noncompliant Code Example

This noncompliant code example reads data from a file stream into a data structure:

Code Block
bgColor#FFCCCC
langc

struct myData {
    char c;
  long  float fl;
} myData;

/* There is no way to verify what binary model was used to write the data */
fread(&myData, sizeof(... */

FILE *file;
struct myData data;

/* Initialize file */

if (fread(&data, sizeof(struct myData), 1, fd);
file) < sizeof(struct myData)) {
  /* Handle error */
}

However, the code makes assumptions about the layout of myData, which may be represented differently on a different platform.

Compliant Solution

The best solution is to use either a text representation or a special library that will ensure the integrity of data.ensures data integrity:

Code Block
bgColor#ccccff
langc

struct myData {
    char c;
  long l;
};

/*  float f;
} myData;... */

FILE *file;
struct myData data;
char buf[25];
char *end_ptr;

/* Initialize file */

if (fscanf(fd, "%c %f\n", &myData.c, &myData.f) != 2fgets(buf, 1, file) == NULL) {
  /* Handle error */
}

data.c = buf[0];

if (fgets(buf, sizeof(buf), file) == NULL) {
  /* Handle Error */
}

data.l = strtol(buf, &end_ptr, 10);

if ((ERANGE == errno)
 || (end_ptr == buf)
 || ('\n' != *end_ptr && '\0' != *end_ptr)) {
    /* Handle errorError */
}

Risk Assessment

Reading binary data that has a different format than expected may result in unintended program behavior.

Recommendation

Severity

Likelihood

Remediation Cost

Detectable

Repairable

Priority

Level

FIO09-

A

C

Medium

low

Probable

unlikely

No

medium

No

P2

L3

P4

L3

Automated Detection

Tool

Version

Checker

Description

Compass/ROSE



Could flag possible violations of this rule by noting any pointer to struct that is passed to fread(), as the noncompliant code example demonstrates

LDRA tool suite
Include Page
LDRA_V
LDRA_V
44 SEnhanced Enforcement

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[Summit 95|AA. C References#Summit 95]\], [20.5 on C-FAQ | http://c-faq.com/misc/binaryfiles.html]

Related Guidelines

Bibliography


...

Image Added Image Added Image AddedFIO08-A. Take care when calling remove() on an open file      09. Input Output (FIO)       FIO10-A. Take care when using the rename() function