PERFORCE change 114771 for review

Jung-uk Kim jkim at FreeBSD.org
Tue Feb 20 21:22:41 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=114771

Change 114771 by jkim at jkim_hammer on 2007/02/20 21:21:45

	- Check GUDATA_SEL for set_thread_area().
	It is default selector for %gs.
	- Force GUGS32_SEL for clone with CLONE_SETTLS.

Affected files ...

.. //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_machdep.c#40 edit

Differences ...

==== //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_machdep.c#40 (text+ko) ====

@@ -659,39 +659,19 @@
 		struct user_segment_descriptor sd;
 		struct l_user_desc info;
 	   	int a[2];
-		int idx;
 
 	   	error = copyin((void *)td->td_frame->tf_rsi, &info,
 		    sizeof(struct l_user_desc));
 		if (error) {
 			printf(LMSG("copyin failed!"));
 		} else {
+			/* We might copy out the entry_number as GUGS32_SEL. */
+		   	info.entry_number = GUGS32_SEL;
+			error = copyout(&info, (void *)td->td_frame->tf_rsi,
+			    sizeof(struct l_user_desc));
+			if (error)
+				printf(LMSG("copyout failed!"));
 
-			idx = info.entry_number;
-
-			/* 
-			 * It looks like we're getting the idx we returned
-			 * in the set_thread_area() syscall.
-			 */
-			if (idx != 6 && idx != GUGS32_SEL) {
-				printf(LMSG("resetting idx!"));
-				idx = 6;	/* or GUGS32_SEL? */
-			}
-
-			/* this doesnt happen in practice */
-			if (idx == 6) {
-				/*
-				 * We might copy out the entry_number
-				 * as GUGS32_SEL.
-				 */
-			   	info.entry_number = GUGS32_SEL;
-				error = copyout(&info,
-				    (void *)td->td_frame->tf_rsi,
-				    sizeof(struct l_user_desc));
-				if (error)
-					printf(LMSG("copyout failed!"));
-			}
-
 			a[0] = LDT_entry_a(&info);
 			a[1] = LDT_entry_b(&info);
 
@@ -1252,7 +1232,6 @@
 	struct user_segment_descriptor sd;
 	int a[2];
 	int error;
-	int idx;
 
 	error = copyin(args->desc, &info, sizeof(struct l_user_desc));
 	if (error)
@@ -1267,7 +1246,6 @@
 		    info.seg_not_present, info.useable);
 #endif
 
-	idx = info.entry_number;
 	/*
 	 * Semantics of Linux version: every thread in the system has array
 	 * of three TLS descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown.
@@ -1287,18 +1265,25 @@
 
 	/*
 	 * GLIBC reads current %gs and call set_thread_area() with it.
-	 * We should let GUGS32_SEL proceed as well because we use this
-	 * segment.
+	 * We should let GUDATA_SEL and GUGS32_SEL proceed as well because
+	 * we use these segments.
 	 */
-	if (idx != 6 && idx != -1 && idx != GUGS32_SEL)
+	switch (info.entry_number) {
+	case GUGS32_SEL:
+	case GUDATA_SEL:
+	case 6:
+	case -1:
+		info.entry_number = GUGS32_SEL;
+		break;
+	default:
 		return (EINVAL);
+	}
 
 	/*
 	 * We have to copy out the GDT entry we use.
 	 * XXX: What if userspace program does not check return value and
 	 * tries to use 6, 7 or 8?
 	 */
-	idx = info.entry_number = GUGS32_SEL;
 	error = copyout(&info, args->desc, sizeof(struct l_user_desc));
 	if (error)
 		return (error);


More information about the p4-projects mailing list