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 CID1008328
. 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
This commit is contained in:
parent
359a939783
commit
d142cf7cea
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user