Currently, we have a framework to widen bounds for null-terminated arrays pointers. If an _Nt_array_ptr
is dereferenced at the current upper bound then we can widen its bounds by 1. For example,
_Nt_array_ptr<T> p : bounds(p, p) = "";
if (*p) // Widen bounds by 1. New bounds for p : bounds(p, p + 1)
Now, we want to support cases where the length of an _Nt_array_ptr
is obtained using calls to strlen
.
int x = strlen(p); // New bounds for p : bounds(p, p + x)
if (*(p + x)) // Widen bounds by 1. New bounds for p : bounds(p, p + x + 1)
...
...
if (*(p + x + 2)) // Error: Out-of-bounds memory access.
Design for handling strlen
in bounds widening
We will support strlen
in bounds widening if the following conditions are satisfied:
-
We will only support calls to
strlen
whose return value is assigned to a variable, likeint x = strlen(p)
. This means we will not consider calls likeif (i < strlen(p))
in bounds widening. -
When using
strlen
with an_Nt_array_ptr
the user should redeclare the bounds of the_Nt_array_ptr
using awhere
clause. For example,int x = strlen(p) where p : bounds(p, p + x)
. If astrlen
call is not annotated with awhere
clause redeclaring the bounds then we will not consider thatstrlen
in bounds widening. -
The bounds redeclared using
strlen
with awhere
clause only remain valid inside the block where the redeclaration happens. For example,
_Nt_array_ptr<T> p : bounds(p, p); // Bounds for p : bounds(p, p)
if (some condition) {
int x = strlen(p) where p : bounds(p, p + x); // New bounds for p : bounds(p, p + x)
}
// Outside the if condition we fallback to the declared bounds. Thus bounds for p : bounds(p, p)
- In a particular block, the bounds redeclared by the most recent
strlen
with awhere
clause will override all previous bounds redeclarations. For example,
int x = strlen(p) where p : bounds(p, p + x); // Bounds for p : bounds(p, p + x)
...
...
int y = strlen(p) where p : bounds(p, p + y); // New bounds for p : bounds(p, p + y)
- At join points if there are two conflicting/different redeclarations of bounds using
strlen
withwhere
clause we will fallback to the declared bounds along with a warning. For example,
int x, y;
if (some condition) {
x = strlen(p) where p : bounds(p, p + x);
goto L1;
}
else {
y = strlen(p) where p : bounds(p, p + y);
goto L1;
}
L1: // At this point we have two conflicting redeclared bounds for p: bounds(p, p + x) and bounds(p, p + y).
// So we reset the bounds here to the declared bounds and issue a warning.