...
If len
is equal to sizeof(buf)
, the null terminator is written one written 1 byte past the end of buf
.
Code Block | ||||
---|---|---|---|---|
| ||||
char buf[1024];
ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf));
buf[len] = '\0';
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
long symlink_max;
size_t bufsize;
char *buf;
ssize_t len;
errno = 0;
symlink_max = pathconf("/usr/bin/", _PC_SYMLINK_MAX);
if (symlink_max == -1) {
if (errno != 0) {
/* handle error condition */
}
bufsize = 10000;
}
else {
bufsize = symlink_max+1;
}
buf = (char *)malloc(bufsize);
if (buf == NULL) {
/* handle error condition */
}
len = readlink("/usr/bin/perl", buf, bufsize);
buf[len] = '\0';
|
This modification incorrectly assumes that the symbolic link cannot be longer than the value of SYMLINK_MAX
returned by pathconf()
. However, the value returned by pathconf()
is out of date by the time readlink()
is called, so the off-by-one buffer-overflow risk is still present because, in between the two calls, the location of /usr/bin/perl
can change to a file system with a larger SYMLINK_MAX
value. Also, if SYMLINK_MAX
is indeterminate (that is, if pathconf()
returned -1
without setting errno
), the code uses an arbitrary large buffer size (10,000) that it hopes will be sufficient, but there is a small chance that readlink()
can return exactly this size.
...
This compliant solution ensures there is no overflow by only reading in only sizeof(buf)-1
characters. It also properly checks to see if an error has occurred.
Code Block | ||||
---|---|---|---|---|
| ||||
enum { BUFFERSIZE = 1024 };
char buf[BUFFERSIZE];
ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf)-1);
if (len != -1) {
buf[len] = '\0';
}
else {
/* handle error condition */
}
|
...
Tool | Version | Checker | Description | |
---|---|---|---|---|
Section | Compass/ROSE |
|
|
|
Related Vulnerabilities
...
MITRE CWE: CWE-170, "Improper Null Terminationnull termination"
...
Sources
[Ilja 2006]
[Open Group 1997a]
[Open Group 2004]
...