Date: Tue, 20 Feb 2007 21:22:39 GMT From: Jung-uk Kim <jkim@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 114771 for review Message-ID: <200702202122.l1KLMdXR029790@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=114771 Change 114771 by jkim@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200702202122.l1KLMdXR029790>
