Skip site navigation (1)Skip section navigation (2)
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>