Author: emaste
Date: Wed Dec  5 21:51:39 2018
New Revision: 341607
URL: https://svnweb.freebsd.org/changeset/base/341607

Log:
  MFC r341484: Always treat firmware request and response sizes as unsigned.
  
  This fixes an incomplete bounds check on the guest-supplied request
  size where a very large request size could be interpreted as a negative
  value and not be caught by the bounds check.
  
  Submitted by: jhb
  Reported by:  Reno Robert
  Security:     CVE-2018-17160

Modified:
  stable/10/usr.sbin/bhyve/fwctl.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/bhyve/fwctl.c
==============================================================================
--- stable/10/usr.sbin/bhyve/fwctl.c    Wed Dec  5 21:49:39 2018        
(r341606)
+++ stable/10/usr.sbin/bhyve/fwctl.c    Wed Dec  5 21:51:39 2018        
(r341607)
@@ -77,8 +77,8 @@ static u_int ident_idx;
 
 struct op_info {
        int op;
-       int  (*op_start)(int len);
-       void (*op_data)(uint32_t data, int len);
+       int  (*op_start)(uint32_t len);
+       void (*op_data)(uint32_t data, uint32_t len);
        int  (*op_result)(struct iovec **data);
        void (*op_done)(struct iovec *data);
 };
@@ -117,7 +117,7 @@ errop_set(int err)
 }
 
 static int
-errop_start(int len)
+errop_start(uint32_t len)
 {
        errop_code = ENOENT;
 
@@ -126,7 +126,7 @@ errop_start(int len)
 }
 
 static void
-errop_data(uint32_t data, int len)
+errop_data(uint32_t data, uint32_t len)
 {
 
        /* ignore */
@@ -186,7 +186,7 @@ static int fget_cnt;
 static size_t fget_size;
 
 static int
-fget_start(int len)
+fget_start(uint32_t len)
 {
 
        if (len > FGET_STRSZ)
@@ -198,7 +198,7 @@ fget_start(int len)
 }
 
 static void
-fget_data(uint32_t data, int len)
+fget_data(uint32_t data, uint32_t len)
 {
 
        *((uint32_t *) &fget_str[fget_cnt]) = data;
@@ -283,8 +283,8 @@ static struct req_info {
        struct op_info *req_op;
        int      resp_error;
        int      resp_count;
-       int      resp_size;
-       int      resp_off;
+       size_t   resp_size;
+       size_t   resp_off;
        struct iovec *resp_biov;
 } rinfo;
 
@@ -344,13 +344,14 @@ fwctl_request_start(void)
 static int
 fwctl_request_data(uint32_t value)
 {
-       int remlen;
 
        /* Make sure remaining size is >= 0 */
-       rinfo.req_size -= sizeof(uint32_t);
-       remlen = MAX(rinfo.req_size, 0);
+       if (rinfo.req_size <= sizeof(uint32_t))
+               rinfo.req_size = 0;
+       else
+               rinfo.req_size -= sizeof(uint32_t);
 
-       (*rinfo.req_op->op_data)(value, remlen);
+       (*rinfo.req_op->op_data)(value, rinfo.req_size);
 
        if (rinfo.req_size < sizeof(uint32_t)) {
                fwctl_request_done();
@@ -399,7 +400,7 @@ static int
 fwctl_response(uint32_t *retval)
 {
        uint32_t *dp;
-       int remlen;
+       ssize_t remlen;
 
        switch(rinfo.resp_count) {
        case 0:
@@ -434,7 +435,7 @@ fwctl_response(uint32_t *retval)
        }
 
        if (rinfo.resp_count > 3 &&
-           rinfo.resp_size - rinfo.resp_off <= 0) {
+           rinfo.resp_off >= rinfo.resp_size) {
                fwctl_response_done();
                return (1);
        }
_______________________________________________
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