Author: markj
Date: Sat Jan  5 15:28:20 2019
New Revision: 342787
URL: https://svnweb.freebsd.org/changeset/base/342787

Log:
  Add a bounds check to the tws(4) passthrough ioctl handler.
  
  tws_passthru() was doing a copyin of a user-specified request
  without validating its length, so a malicious request could overrun
  the buffer.  By default, the tws(4) device file is only accessible
  as root.
  
  admbug:               825
  Reported by:  Anonymous of the Shellphish Grill Team
  Reviewed by:  delphij
  MFC after:    1 week
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D18536

Modified:
  head/sys/dev/tws/tws_user.c

Modified: head/sys/dev/tws/tws_user.c
==============================================================================
--- head/sys/dev/tws/tws_user.c Sat Jan  5 15:09:50 2019        (r342786)
+++ head/sys/dev/tws/tws_user.c Sat Jan  5 15:28:20 2019        (r342787)
@@ -92,9 +92,13 @@ tws_passthru(struct tws_softc *sc, void *buf)
     struct tws_request *req;
     struct tws_ioctl_no_data_buf *ubuf = (struct tws_ioctl_no_data_buf *)buf;
     int error;
+    u_int32_t buffer_length;
     u_int16_t lun4;
 
-
+    buffer_length = roundup2(ubuf->driver_pkt.buffer_length, 512);
+    if ( buffer_length > TWS_MAX_IO_SIZE ) {
+        return(EINVAL);
+    }
     if ( tws_get_state(sc) != TWS_ONLINE) {
         return(EBUSY);
     }
@@ -118,7 +122,7 @@ tws_passthru(struct tws_softc *sc, void *buf)
         }
     } while(1);
 
-    req->length = (ubuf->driver_pkt.buffer_length + 511) & ~511;
+    req->length = buffer_length;
     TWS_TRACE_DEBUG(sc, "datal,rid", req->length, req->request_id);
     if ( req->length ) {
         req->data = sc->ioctl_data_mem;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to