You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 25 Next »

File names on various operating systems, including Windows and UNIX, may be used to access "special" files, which are actually devices. Sample reserved MS-DOS device names include AUX, CON, PRN, COM1, and LPT1. Device files on UNIX systems are used to apply access rights and to direct operations on the files to the appropriate device drivers.

Performing operations on device files that are intended for ordinary character or binary files can result in crashes and denial-of-service attacks. For example, when Windows attempts to interpret the device name as a file resource, it performs an invalid resource access that usually results in a crash [[Howard 02]] .

Non-Compliant Code Example

In this example, the user can specify a locked device or a FIFO filename, causing the program to hang on the call to open().

if (!fgets(filename, sizeof(filename), stdin)) {
    /* handle error */
}

if (open(filename, O_WRONLY) == -1) {
    /* handle error */
}

Compliant Solution (POSIX)

Device files in UNIX can be a security risk when an attacker is able to access them in an unauthorized way. For instance, if attackers can read or write to the /dev/kmem device, they may be able to alter their priority, UID, or other attributes of their process or simply crash the system. Similarly, access to disk devices, tape devices, network devices, and terminals being used by others all can lead to problems [[Garfinkel 96]].

On Linux, it is possible to lock certain applications by attempting to open devices rather than files, for example:

/dev/mouse
/dev/console
/dev/tty0
/dev/zero
etc.

A web browser that failed to check for these devices would allow an attacker to create a website with image tags such as <IMG SRC=file:///dev/mouse> that would lock the user's mouse.

Programmers can use the POSIX stat() function to obtain information about a named file, and the S_ISREG() macro to determine if the file is a regular file.

struct stat pre_s;
struct stat post_s;
int fildes;

if (!fgets(filename, sizeof(filename), stdin)) {
  /* handle error */
}

if ((stat(filename, &pre_s) != 0) || (!S_ISREG(pre_s.st_mode))) {
  /* handle error */
}

/* due to a race condition here, we will verify with fstat later */

if ((fildes = open(filename, O_WRONLY)) == -1) {
  /* handle error */
}

if (fstat(fildes, &post_s) != 0) {
  /* handle error */
}

if(!(pre_s.st_mode == post_s.st_mode &&
     pre_s.st_ino  == post_s.st_ino  &&
     pre_s.st_dev  == post_s.st_dev)) {
  /* handle error */
}

/* operate on file */

Compliant Solution (Windows)

The GetFileType() function can be used to determine if the file is a disk file.

HANDLE hFile = CreateFile(
  pFullPathName, 0, 0, NULL, OPEN_EXISTING, 0, NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
  /* handle error */
}
else {
  if (GetFileType(hFile) != FILE_TYPE_DISK) {
    /* handle error */
  }
  /* operate on file */
}

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO46-C

2 (medium)

1 (unlikely)

2 (medium)

P4

L3

Automated Detection

Fortify SCA Version 5.0 is able to detect violations of this rule.

Related Vulnerabilities

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

References

[[Garfinkel 96]] Section 5.6, "Device Files"
[[Howard 02]] Chapter 11, "Canonical Representation Issues"
[[ISO/IEC 9899-1999]] Section


FIO31-C. Do not simultaneously open the same file multiple times      09. Input Output (FIO)       FIO33-C. Detect and handle input output errors resulting in undefined behavior

  • No labels