plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. |
| 3 | * Portions Copyright (c) 2000 Ulrich Drepper |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 4 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of version 2 of the GNU General Public License as |
| 7 | * published by the Free Software Foundation. |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 8 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 9 | * This program is distributed in the hope that it would be useful, but |
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 12 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 13 | * Further, this software is distributed without any warranty that it is |
| 14 | * free of the rightful claim of any third person regarding infringement |
| 15 | * or the like. Any license provided herein, whether implied or |
| 16 | * otherwise, applies only to this software file. Patent licenses, if |
| 17 | * any, provided herein do not apply to combinations of this program with |
| 18 | * other software, or any other product whatsoever. |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 19 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 20 | * You should have received a copy of the GNU General Public License along |
Wanlong Gao | fed9641 | 2012-10-24 10:10:29 +0800 | [diff] [blame] | 21 | * with this program; if not, write the Free Software Foundation, Inc., |
| 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 23 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 24 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, |
| 25 | * Mountain View, CA 94043, or: |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 26 | * |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 27 | * http://www.sgi.com$ |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 28 | * |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 29 | * For further information regarding this notice, see:$ |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 30 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 31 | * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 32 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 33 | * |
| 34 | * Linux Test Project - Silicon Graphics, Inc. |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 35 | * TEST IDENTIFIER : fork05 |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 36 | * EXECUTED BY : anyone |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 37 | * TEST TITLE : Make sure LDT is propagated correctly |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 38 | * TEST CASE TOTAL : 1 |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 39 | * CPU TYPES : i386 |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 40 | * AUTHORS : Ulrich Drepper |
| 41 | * Nate Straz |
| 42 | * |
robbiew | 5e83f22 | 2003-05-07 15:46:32 +0000 | [diff] [blame] | 43 | *On Friday, May 2, 2003 at 09:47:00AM MST, Ulrich Drepper wrote: |
| 44 | *>Robert Williamson wrote: |
| 45 | *> |
| 46 | *>> I'm getting a SIGSEGV with one of our tests, fork05.c, that apparently |
| 47 | *>> you wrote (attached below). The test passes on my 2.5.68 machine running |
| 48 | *>> SuSE 8.0 (glibc 2.2.5 and Linuxthreads), however it segmentation faults on |
| 49 | *>> RedHat 9 running 2.5.68. The test seems to "break" when it attempts to run |
| 50 | *>> the assembly code....could you take a look at it? |
| 51 | *> |
| 52 | *>There is no need to look at it, I know it cannot work anymore on recent |
| 53 | *>systems. Either change all uses of %gs to %fs or skip the entire patch |
| 54 | *>if %gs has a nonzero value. |
| 55 | *> |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 56 | *>- -- |
robbiew | 5e83f22 | 2003-05-07 15:46:32 +0000 | [diff] [blame] | 57 | *>- --------------. ,-. 444 Castro Street |
| 58 | *>Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA |
| 59 | *>Red Hat `--' drepper at redhat.com `--------------------------- |
| 60 | * |
| 61 | * |
| 62 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 63 | *On Sat, Aug 12, 2000 at 12:47:31PM -0700, Ulrich Drepper wrote: |
| 64 | *> Ever since the %gs handling was fixed in the 2.3.99 series the |
| 65 | *> appended test program worked. Now with 2.4.0-test6 it's not working |
| 66 | *> again. Looking briefly over the patch from test5 to test6 I haven't |
| 67 | *> seen an immediate candidate for the breakage. It could be missing |
| 68 | *> propagation of the LDT to the new process (and therefore an invalid |
| 69 | *> segment descriptor) or simply clearing %gs. |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 70 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 71 | *> Anyway, this is what you should see and what you get with test5: |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 72 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 73 | *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 74 | *> a = 42 |
| 75 | *> %gs = 0x0007 |
| 76 | *> %gs = 0x0007 |
| 77 | *> a = 99 |
| 78 | *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 79 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 80 | *> This is what you get with test6: |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 81 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 82 | *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 83 | *> a = 42 |
| 84 | *> %gs = 0x0007 |
| 85 | *> %gs = 0x0000 |
| 86 | *> <SEGFAULT> |
| 87 | *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 88 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 89 | *> If somebody is actually creating a test suite for the kernel, please |
| 90 | *> add this program. It's mostly self-contained. The correct handling |
| 91 | *> of %gs is really important since glibc 2.2 will make heavy use of it. |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 92 | *> |
| 93 | *> - -- |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 94 | *> - ---------------. ,-. 1325 Chesapeake Terrace |
| 95 | *> Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA |
| 96 | *> Red Hat `--' drepper at redhat.com `------------------------ |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 97 | *> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 98 | *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 99 | * |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 100 | */ |
| 101 | |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 102 | #include <stdio.h> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 103 | #include <fcntl.h> |
| 104 | #include <unistd.h> |
| 105 | #include <stdlib.h> |
| 106 | #include <sys/wait.h> |
robbiew | 4e20ed9 | 2002-06-10 15:02:59 +0000 | [diff] [blame] | 107 | #include "test.h" |
| 108 | #include "usctest.h" |
| 109 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 110 | char *TCID = "fork05"; |
robbiew | 4e20ed9 | 2002-06-10 15:02:59 +0000 | [diff] [blame] | 111 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 112 | static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" }; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame^] | 113 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 114 | #define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *)) |
| 115 | int TST_TOTAL = NUMBER_OF_ENVIRON; |
robbiew | 4e20ed9 | 2002-06-10 15:02:59 +0000 | [diff] [blame] | 116 | |
| 117 | #if defined(linux) && defined(__i386__) |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 118 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 119 | struct modify_ldt_ldt_s { |
| 120 | unsigned int entry_number; |
| 121 | unsigned long int base_addr; |
| 122 | unsigned int limit; |
| 123 | unsigned int seg_32bit:1; |
| 124 | unsigned int contents:2; |
| 125 | unsigned int read_exec_only:1; |
| 126 | unsigned int limit_in_pages:1; |
| 127 | unsigned int seg_not_present:1; |
| 128 | unsigned int useable:1; |
| 129 | unsigned int empty:25; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 130 | }; |
| 131 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 132 | static int a = 42; |
mridge | f4f3d4f | 2005-01-05 21:21:27 +0000 | [diff] [blame] | 133 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 134 | static void modify_ldt(int, struct modify_ldt_ldt_s *, int); |
mridge | f4f3d4f | 2005-01-05 21:21:27 +0000 | [diff] [blame] | 135 | asm(" .text\n\ |
| 136 | .type modify_ldt,@function \n\ |
plars | 74948ad | 2002-11-14 16:16:14 +0000 | [diff] [blame] | 137 | modify_ldt: \n\ |
| 138 | push %ebx \n\ |
| 139 | mov 0x10(%esp,1),%edx \n\ |
| 140 | mov 0xc(%esp,1),%ecx \n\ |
| 141 | mov 0x8(%esp,1),%ebx \n\ |
| 142 | mov $0x7b,%eax \n\ |
| 143 | int $0x80 \n\ |
| 144 | pop %ebx \n\ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 145 | ret"); |
| 146 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 147 | int main() |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 148 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 149 | struct modify_ldt_ldt_s ldt0; |
| 150 | int lo; |
| 151 | pid_t pid; |
| 152 | int res; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 153 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 154 | ldt0.entry_number = 0; |
| 155 | ldt0.base_addr = (long)&a; |
| 156 | ldt0.limit = 4; |
| 157 | ldt0.seg_32bit = 1; |
| 158 | ldt0.contents = 0; |
| 159 | ldt0.read_exec_only = 0; |
| 160 | ldt0.limit_in_pages = 0; |
| 161 | ldt0.seg_not_present = 0; |
| 162 | ldt0.useable = 1; |
| 163 | ldt0.empty = 0; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 164 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 165 | modify_ldt(1, &ldt0, sizeof(ldt0)); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 166 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 167 | asm volatile ("movw %w0, %%fs"::"q" (7)); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 168 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 169 | asm volatile ("movl %%fs:0, %0":"=r" (lo)); |
| 170 | tst_resm(TINFO, "a = %d", lo); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 171 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 172 | asm volatile ("pushl %%fs; popl %0":"=q" (lo)); |
| 173 | tst_resm(TINFO, "%%fs = %#06hx", lo); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 174 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 175 | asm volatile ("movl %0, %%fs:0"::"r" (99)); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 176 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 177 | pid = fork(); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 178 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 179 | if (pid == 0) { |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 180 | asm volatile ("pushl %%fs; popl %0":"=q" (lo)); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 181 | tst_resm(TINFO, "%%fs = %#06hx", lo); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 182 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 183 | asm volatile ("movl %%fs:0, %0":"=r" (lo)); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 184 | tst_resm(TINFO, "a = %d", lo); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 185 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 186 | if (lo != 99) |
| 187 | tst_resm(TFAIL, "Test failed"); |
| 188 | else |
| 189 | tst_resm(TPASS, "Test passed"); |
| 190 | exit(lo != 99); |
| 191 | } else { |
| 192 | waitpid(pid, &res, 0); |
| 193 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 194 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 195 | return WIFSIGNALED(res); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | #else /* if defined(linux) && defined(__i386__) */ |
| 199 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 200 | int main() |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 201 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 202 | tst_resm(TINFO, "%%fs test only for ix86"); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 203 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 204 | /* |
| 205 | * should be successful on all non-ix86 platforms. |
| 206 | */ |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 207 | tst_exit(); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 208 | } |
| 209 | |
Wanlong Gao | 1819069 | 2012-09-18 17:14:01 +0800 | [diff] [blame] | 210 | #endif /* if defined(linux) && defined(__i386__) */ |