summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2016-05-23 01:01:23 +0000
committertruckman <truckman@FreeBSD.org>2016-05-23 01:01:23 +0000
commitd142cf7cea6adc20a96a0a7aa48a1c2ae61c7264 (patch)
treeee28858c22f7e3cd82d1b61ced08e18fb2efe8dc /bin
parent359a9397836436cfa9d00eafcc8e54af71328f1c (diff)
downloadFreeBSD-src-d142cf7cea6adc20a96a0a7aa48a1c2ae61c7264.zip
FreeBSD-src-d142cf7cea6adc20a96a0a7aa48a1c2ae61c7264.tar.gz
Hopefully fix Coverity CID 1008328 (Out-of-bounds write) in /bin/sh.
Replace the magic constant 127 in the loop interation count with "PROMPTLEN - 1". gethostname() is not guaranteed to NUL terminate the destination string if it is too short. Decrease the length passed to gethostname() by one, and add a NUL at the end of the buffer to make sure the following loop to find the end of the name properly terminates. The default: case is the likely cause of Coverity CID 1008328. If i is 126 at the top of the loop interation where the default case is triggered, i will be incremented to 127 by the default case, then incremented to 128 at the top of the loop before being compared to 127 (PROMPTLENT - 1) and terminating the loop. Then the NUL termination code after the loop will write to ps[128]. Fix by checking for overflow before incrementing the index and storing the second character in the buffer. These fixes are not guaranteed to satisfy Coverity. The code that increments i in the 'h'/'H' and 'w'/'W' cases may be beyond its capability to analyze, but the code appears to be safe. Reported by: Coverity CID: 1008328 Reviewed by: jilles, cem MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D6482
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/parser.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index f3cc98d..cc04a2a 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -1998,7 +1998,7 @@ getprompt(void *unused __unused)
/*
* Format prompt string.
*/
- for (i = 0; (i < 127) && (*fmt != '\0'); i++, fmt++)
+ for (i = 0; (i < PROMPTLEN - 1) && (*fmt != '\0'); i++, fmt++)
if (*fmt == '\\')
switch (*++fmt) {
@@ -2011,7 +2011,8 @@ getprompt(void *unused __unused)
case 'h':
case 'H':
ps[i] = '\0';
- gethostname(&ps[i], PROMPTLEN - i);
+ gethostname(&ps[i], PROMPTLEN - i - 1);
+ ps[PROMPTLEN - 1] = '\0';
/* Skip to end of hostname. */
trim = (*fmt == 'h') ? '.' : '\0';
while ((ps[i] != '\0') && (ps[i] != trim))
@@ -2061,8 +2062,9 @@ getprompt(void *unused __unused)
* Emit unrecognized formats verbatim.
*/
default:
- ps[i++] = '\\';
- ps[i] = *fmt;
+ ps[i] = '\\';
+ if (i < PROMPTLEN - 1)
+ ps[++i] = *fmt;
break;
}
else
OpenPOWER on IntegriCloud