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
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to