CERT-FIO32-C
In this section:
Synopsis
Do not perform operations on devices that are only appropriate for files
Enabled by default
Yes
Severity/Certainty
Medium/Low

Full description
File names may be used to access special files, which are actually devices. Performing operations on device files that are intended for ordinary character or binary files can result in crashes and denial-of-service attacks. Device files in UNIX can be a security risk when an attacker can access them in an unauthorized way. It is possible to lock certain applications by attempting to open devices rather than files.
Coding standards
- CERT FIO32-C
Do not perform operations on devices that are only appropriate for files
Code examples
The following code example fails the check and will give a warning:
#include <stdio.h>
void func(const char *file_name) {
FILE *file;
if ((file = fopen(file_name, "wb")) == NULL) {
/* Handle error */
}
/* Operate on the file */
if (fclose(file) == EOF) {
/* Handle error */
}
}
The following code example passes the check and will not give a warning about this issue:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef O_NOFOLLOW
#define OPEN_FLAGS O_NOFOLLOW | O_NONBLOCK
#else
#define OPEN_FLAGS O_NONBLOCK
#endif
void func(const char *file_name) {
struct stat orig_st;
struct stat open_st;
int fd;
int flags;
if ((lstat(file_name, &orig_st) != 0) ||
(!S_ISREG(orig_st.st_mode))) {
/* Handle error */
}
/* Race window */
fd = open(file_name, OPEN_FLAGS | O_WRONLY);
if (fd == -1) {
/* Handle error */
}
if (fstat(fd, &open_st) != 0) {
/* Handle error */
}
if ((orig_st.st_mode != open_st.st_mode) ||
(orig_st.st_ino != open_st.st_ino) ||
(orig_st.st_dev != open_st.st_dev)) {
/* The file was tampered with */
}
/*
* Optional: drop the O_NONBLOCK now that we are sure
* this is a good file.
*/
if ((flags = fcntl(fd, F_GETFL)) == -1) {
/* Handle error */
}
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) {
/* Handle error */
}
/* Operate on the file */
if (close(fd) == -1) {
/* Handle error */
}
}