svn commit: r360048 - head/sys/cam/scsi

John Baldwin jhb at FreeBSD.org
Fri Apr 17 18:19:14 UTC 2020


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);


More information about the svn-src-all mailing list