Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Oct 2017 16:19:26 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324438 - head/sys/i386/i386
Message-ID:  <201710091619.v99GJQPs059503@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Oct  9 16:19:26 2017
New Revision: 324438
URL: https://svnweb.freebsd.org/changeset/base/324438

Log:
  Change i386_get_ldt() to return 'EOF' when the requested range of
  descriptors does not fit into currently allocated LDT, or trim the
  return if the range fits partially.  Before, the function returned
  EINVAL.
  
  Fix two bugs in r324366: use capped num counter for malloc size, and
  do not leak allocated buffer on EINVAL (by handling EINVAL case as
  normal, see above).
  
  Reviewed by:	bde
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/i386/i386/sys_machdep.c

Modified: head/sys/i386/i386/sys_machdep.c
==============================================================================
--- head/sys/i386/i386/sys_machdep.c	Mon Oct  9 16:07:27 2017	(r324437)
+++ head/sys/i386/i386/sys_machdep.c	Mon Oct  9 16:19:26 2017	(r324438)
@@ -534,23 +534,20 @@ i386_get_ldt(struct thread *td, struct i386_ldt_args *
 	    uap->start, uap->num, (void *)uap->descs);
 #endif
 
-	if (uap->start >= MAX_LD)
-		return (EINVAL);
-	num = min(uap->num, MAX_LD - uap->start);
-	data = malloc(uap->num * sizeof(union descriptor), M_TEMP, M_WAITOK);
+	num = min(uap->num, MAX_LD);
+	data = malloc(num * sizeof(union descriptor), M_TEMP, M_WAITOK);
 	mtx_lock_spin(&dt_lock);
 	pldt = td->td_proc->p_md.md_ldt;
 	nldt = pldt != NULL ? pldt->ldt_len : nitems(ldt);
-	num = min(num, nldt);
-	if (uap->start > nldt || uap->start + num > nldt) {
-		mtx_unlock_spin(&dt_lock);
-		return (EINVAL);
+	if (uap->start >= nldt) {
+		num = 0;
+	} else {
+		num = min(num, nldt - uap->start);
+		bcopy(pldt != NULL ?
+		    &((union descriptor *)(pldt->ldt_base))[uap->start] :
+		    &ldt[uap->start], data, num * sizeof(union descriptor));
 	}
-	bcopy(pldt != NULL ?
-	    &((union descriptor *)(pldt->ldt_base))[uap->start] :
-	    &ldt[uap->start], data, num * sizeof(union descriptor));
 	mtx_unlock_spin(&dt_lock);
-
 	error = copyout(data, uap->descs, num * sizeof(union descriptor));
 	if (error == 0)
 		td->td_retval[0] = num;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710091619.v99GJQPs059503>