...
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
...
.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} char buf[256]; ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf)); buf[len] = '\0'; {code} |
A
...
simple
...
(but
...
incorrect)
...
solution
...
to
...
this
...
problem
...
is
...
to
...
try
...
to
...
make
...
buf
...
large
...
enough
...
that
...
it
...
can
...
always
...
hold
...
the
...
result:
Code Block | ||||
---|---|---|---|---|
| =
| |||
} char buf[PATH_MAX+1]; ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf)); buf[len] = '\0'; {code} |
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
Code Block | ||||
---|---|---|---|---|
| =
| |||
} char buf[256]; ssizet_t len; if ((len = readlink("/usr/bin/perl", buf, sizeof(buf)-1)) != -1) buf[len] = '\0'; else { /* handle error condition */ } {code} h2. Risk Analysis || Rule || Severity || Likelihood || Remediation Cost || Priority || Level || | POS30-C | *1* (low) | *2* (probable) | *2* (medium) | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} | h2. References |
Risk Analysis
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
POS30-C | 1 (low) | 2 (probable) | 2 (medium) | P4 | L3 |
References
Wiki Markup |
---|
\[[ilja 06|AA. C References#ilja 06]\]
\[[Open Group 97|AA. C References#Open Group 97]\]
\[[Open Group 04|AA. C References#Open Group 04]\] |