Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Rearranged so that the C11 CS comes first.

...

Note that this code first sets errno to 0 to comply with ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failure. 

Compliant Solution (

...

C11, strerror_

...

s()) 

This compliant solution uses the POSIX strerror_rs() function from Annex K of the C Standard, which has the same functionality as strerror() but guarantees thread-safety:.

Code Block
bgColor#ccccff
langc
void f(FILE *fp) {
  fpos_t pos;
  errno = 0;

  if (0 != fgetpos(fp, &pos) {
    char errmsg[BUFSIZ];
    if (strerror_rs(errnoerrmsg, errmsgBUFSIZ, BUFSIZerr) != 0) {
      /* handle error */
    }
    printf("Could not get the file position because of %s\n", errmsg);
  }
}

Note that Linux provides two versions of strerror_r(), known as the XSI-compliant version and the GNU-specific version. This compliant solution assumes the XSI-compliant version. You can get the XSI-compliant version if you compile applications in the way POSIX requires (that is, by defining _POSIX_C_SOURCE or _XOPEN_SOURCE appropriately). Check your strerror_r() manual page to see which version(s) are available on your system.

...

because of the optional nature of Annex K, strerror_s() may not be available in all implementations. 

Compliant Solution (POSIX, strerror_r())

This compliant solution uses the POSIX strerror_sr() function from Annex K of the C Standard, which has the same functionality as strerror() but guarantees thread - safety.:

Code Block
bgColor#ccccff
langc
void f(FILE *fp) {
  fpos_t pos;
  errno = 0;

  if (0 != fgetpos(fp, &pos) {
    char errmsg[BUFSIZ];
    if (strerror_sr(errno, errmsg, BUFSIZ, err) != 0) {
      /* handle error */
    }
    printf("Could not get the file position because of %s\n", errmsg);
  }
}

Note that because of the optional nature of Annex K, strerror_s() may not be available in all implementations. Linux provides two versions of strerror_r(), known as the XSI-compliant version and the GNU-specific version. This compliant solution assumes the XSI-compliant version. You can get the XSI-compliant version if you compile applications in the way POSIX requires (that is, by defining _POSIX_C_SOURCE or _XOPEN_SOURCE appropriately). Check your strerror_r() manual page to see which version(s) are available on your system.

Risk Assessment

Race conditions caused by multiple threads invoking the same library function can lead to abnormal termination of the application, data integrity violations, or denial-of-service attack.

...