Date: Wed, 1 Jun 2016 17:09:50 +0000 (UTC) From: Don Lewis <truckman@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r301140 - stable/10/bin/sh Message-ID: <201606011709.u51H9oxA044590@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: truckman Date: Wed Jun 1 17:09:50 2016 New Revision: 301140 URL: https://svnweb.freebsd.org/changeset/base/301140 Log: MFC r300442 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 Differential Revision: https://reviews.freebsd.org/D6482 Modified: stable/10/bin/sh/parser.c Directory Properties: stable/10/ (props changed) Modified: stable/10/bin/sh/parser.c ============================================================================== --- stable/10/bin/sh/parser.c Wed Jun 1 16:56:29 2016 (r301139) +++ stable/10/bin/sh/parser.c Wed Jun 1 17:09:50 2016 (r301140) @@ -1974,7 +1974,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) { @@ -1987,7 +1987,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)) @@ -2037,8 +2038,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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606011709.u51H9oxA044590>