Date: Tue, 21 Apr 2020 17:47:06 +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: r360171 - head/sys/cam/scsi Message-ID: <202004211747.03LHl6Gg019190@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Tue Apr 21 17:47:05 2020 New Revision: 360171 URL: https://svnweb.freebsd.org/changeset/base/360171 Log: Don't access a user buffer directly from the kernel. The handle_string callback for the ENCIOC_SETSTRING ioctl was passing a user pointer to memcpy(). Fix by using copyin() instead. For ENCIOC_GETSTRING ioctls, the handler was storing the user pointer in a CCB's data_ptr field where it was indirected by other code. Fix this by allocating a temporary buffer (which ENCIOC_SETSTRING already did) and copying the result out to the user buffer after the CCB has been processed. Reviewed by: kib Obtained from: CheriBSD MFC after: 1 week Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D24487 Modified: head/sys/cam/scsi/scsi_enc_ses.c Modified: head/sys/cam/scsi/scsi_enc_ses.c ============================================================================== --- head/sys/cam/scsi/scsi_enc_ses.c Tue Apr 21 17:42:32 2020 (r360170) +++ head/sys/cam/scsi/scsi_enc_ses.c Tue Apr 21 17:47:05 2020 (r360171) @@ -2904,13 +2904,19 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *s buf[1] = 0; buf[2] = sstr->bufsiz >> 8; buf[3] = sstr->bufsiz & 0xff; - memcpy(&buf[4], sstr->buf, sstr->bufsiz); + ret = copyin(sstr->buf, &buf[4], sstr->bufsiz); + if (ret != 0) { + ENC_FREE(buf); + return (ret); + } break; case ENCIOC_GETSTRING: payload = sstr->bufsiz; amt = payload; + buf = ENC_MALLOC(payload); + if (buf == NULL) + return (ENOMEM); ses_page_cdb(cdb, payload, SesStringIn, CAM_DIR_IN); - buf = sstr->buf; break; case ENCIOC_GETENCNAME: if (ses_cache->ses_nsubencs < 1) @@ -2950,6 +2956,8 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *s return (EINVAL); } ret = enc_runcmd(enc, cdb, 6, buf, &amt); + if (ret == 0 && ioc == ENCIOC_GETSTRING) + ret = copyout(buf, sstr->buf, sstr->bufsiz); if (ioc == ENCIOC_SETSTRING) ENC_FREE(buf); return (ret);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004211747.03LHl6Gg019190>