Date: Fri, 17 Apr 2020 18:19:13 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r360048 - head/sys/cam/scsi Message-ID: <202004171819.03HIJDpV023747@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Fri Apr 17 18:19:13 2020 New Revision: 360048 URL: https://svnweb.freebsd.org/changeset/base/360048 Log: Don't try to copyout() to a kernel buffer. The handle_string callback for the ENCIOC_GET_ENCNAME and ENCIOC_GETENCID ioctls tries to copy the size of the generated string out to userland. However, the callback only has access to the kernel copy of the structure populated by copyin(). The copyout() call simply overwrites the value in the kernel's copy preventing the subsequent overflow prevention logic from working. Fix this by instead doing a copyout() of the updated length in the caller after the callback returns. Reviewed by: kib Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D24456 Modified: head/sys/cam/scsi/scsi_enc.c head/sys/cam/scsi/scsi_enc_ses.c Modified: head/sys/cam/scsi/scsi_enc.c ============================================================================== --- head/sys/cam/scsi/scsi_enc.c Fri Apr 17 17:05:58 2020 (r360047) +++ head/sys/cam/scsi/scsi_enc.c Fri Apr 17 18:19:13 2020 (r360048) @@ -489,6 +489,10 @@ enc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg_ad cam_periph_lock(periph); error = enc->enc_vec.handle_string(enc, &sstr, cmd); cam_periph_unlock(periph); + if (error == 0 || error == ENOMEM) + (void)copyout(&sstr.bufsiz, + &((encioc_string_t *)addr)->bufsiz, + sizeof(sstr.bufsiz)); break; case ENCIOC_GETELMSTAT: Modified: head/sys/cam/scsi/scsi_enc_ses.c ============================================================================== --- head/sys/cam/scsi/scsi_enc_ses.c Fri Apr 17 17:05:58 2020 (r360047) +++ head/sys/cam/scsi/scsi_enc_ses.c Fri Apr 17 18:19:13 2020 (r360048) @@ -2926,11 +2926,11 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *s vendor, product, rev) + 1; if (rsize > sizeof(str)) rsize = sizeof(str); - copyout(&rsize, &sstr->bufsiz, sizeof(rsize)); size = rsize; if (size > sstr->bufsiz) size = sstr->bufsiz; copyout(str, sstr->buf, size); + sstr->bufsiz = rsize; return (size == rsize ? 0 : ENOMEM); case ENCIOC_GETENCID: if (ses_cache->ses_nsubencs < 1) @@ -2940,11 +2940,11 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *s scsi_8btou64(enc_desc->logical_id)) + 1; if (rsize > sizeof(str)) rsize = sizeof(str); - copyout(&rsize, &sstr->bufsiz, sizeof(rsize)); size = rsize; if (size > sstr->bufsiz) size = sstr->bufsiz; copyout(str, sstr->buf, size); + sstr->bufsiz = rsize; return (size == rsize ? 0 : ENOMEM); default: return (EINVAL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004171819.03HIJDpV023747>