The column counting loop in getfile() reads one byte past the
end of curline when the input line does not end with a separator.
The inner while loop advances p to the null terminator:
for (p = curline; *p != '\0'; p++) {
...
while (*p && *p != isep)
p++;
}
When the inner while exits because *p == '\0', the for loop's
p++ increment advances p past the null terminator. The subsequent
*p != '\0' check in the for condition reads one byte past the
allocated buffer.
Fix: break out of the for loop when the inner while exits on
the null terminator, before the for increment advances past it.
Found by AFL++ fuzzing.
Index: usr.bin/rs/rs.c
===================================================================
RCS file: /cvs/src/usr.bin/rs/rs.c,v
retrieving revision 1.30
diff -u -p -r1.30 rs.c
--- usr.bin/rs/rs.c 3 Dec 2015 12:23:15 -0000 1.30
+++ usr.bin/rs/rs.c
@@ -146,6 +146,8 @@ getfile(void)
icols++;
while (*p && *p != isep)
p++;
+ if (*p == '\0')
+ break;
}
ep = getptrs(NULL);
p = curline;