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

Compare with Current View Page History

« Previous Version 12 Next »

The readlink() function reads where a link points to. It is unusual, as makes no effort to null terminate its second argument, buffer. Instead, it just returns the number of characters it has written.

Non-Compliant Coding Example

If len is equal to sizeof(buf), the null terminator will be written one byte past the end of buf.

char buf[256];
ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf));
buf[len] = '\0';

A simple (but incorrect) solution to this problem is to try to make buf large enough that it can always hold the result:

char buf[PATH_MAX+1];
ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf));
buf[len] = '\0';

This "fix" incorrectly assumes that PATH_MAX represents the longest possible path for a file in the filesystem. (PATH_MAX only bounds the longest possible relative path that can be passed to the kernel in a single call.) On most Unix and Linux systems, there is no easily-determined maximum length for a file path, and so the off-by-one buffer overflow risk is still present.

An additional issue is that readlink() can return -1 if it fails, causing an off-by-one underflow.

Compliant Solution

This example ensures there will be no overflow by only reading in sizeof(buf)-1 characters. It also properly checks to see if an error has occurred.

char buf[256];
ssizet_t len;

if ((len = readlink("/usr/bin/perl", buf, sizeof(buf)-1)) != -1)
    buf[len] = '\0';
else {
   /* handle error condition */
}

Risk Analysis

This is a fairly easy mistake to make. Fortunately the consequences are not that harsh, most likely resulting in abnormal program termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

POS30-C

1 (low)

2 (probable)

2 (medium)

P4

L3

References

[[ilja 06]]
[[Open Group 97]]
[[Open Group 04]]

  • No labels