svn commit: r324438 - head/sys/i386/i386

Konstantin Belousov kib at FreeBSD.org
Mon Oct 9 16:19:28 UTC 2017


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;


More information about the svn-src-head mailing list