diff options
author | Mark Johnston <markj@FreeBSD.org> | 2019-01-05 15:28:20 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2019-01-05 15:28:20 +0000 |
commit | cb56711d68b21fbc890ddd586604e7f3bdedca4d (patch) | |
tree | 0687119f3bc6589b8db556906fccc3155a68715e /sys | |
parent | a9f7119bb8ddfee4c42841ead46ff3eed3d943f3 (diff) | |
download | src-cb56711d68b21fbc890ddd586604e7f3bdedca4d.tar.gz src-cb56711d68b21fbc890ddd586604e7f3bdedca4d.zip |
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
Notes
Notes:
svn path=/head/; revision=342787
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/tws/tws_user.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/dev/tws/tws_user.c b/sys/dev/tws/tws_user.c index a3970f0af408..2afdccbf7b46 100644 --- a/sys/dev/tws/tws_user.c +++ b/sys/dev/tws/tws_user.c @@ -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; |