1/* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * Portions Copyright (c) 2000 Ulrich Drepper 4 * 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. 8 * 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. 12 * 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. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 * 24 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 25 * Mountain View, CA 94043, or: 26 * 27 * http://www.sgi.com$ 28 * 29 * For further information regarding this notice, see:$ 30 * 31 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 32 * 33 * 34 * Linux Test Project - Silicon Graphics, Inc. 35 * TEST IDENTIFIER : fork05 36 * EXECUTED BY : anyone 37 * TEST TITLE : Make sure LDT is propagated correctly 38 * TEST CASE TOTAL : 1 39 * CPU TYPES : i386 40 * AUTHORS : Ulrich Drepper 41 * Nate Straz 42 * 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 *> 56 *>- -- 57 *>- --------------. ,-. 444 Castro Street 58 *>Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA 59 *>Red Hat `--' drepper at redhat.com `--------------------------- 60 * 61 * 62 * 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. 70 *> 71 *> Anyway, this is what you should see and what you get with test5: 72 *> 73 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 74 *> a = 42 75 *> %gs = 0x0007 76 *> %gs = 0x0007 77 *> a = 99 78 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 *> 80 *> This is what you get with test6: 81 *> 82 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 *> a = 42 84 *> %gs = 0x0007 85 *> %gs = 0x0000 86 *> <SEGFAULT> 87 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 88 *> 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. 92 *> 93 *> - -- 94 *> - ---------------. ,-. 1325 Chesapeake Terrace 95 *> Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA 96 *> Red Hat `--' drepper at redhat.com `------------------------ 97 *> 98 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 * 100 */ 101 102#include <stdio.h> 103#include <fcntl.h> 104#include <unistd.h> 105#include <stdlib.h> 106#include <sys/wait.h> 107#include "lapi/syscalls.h" 108#include "test.h" 109 110char *TCID = "fork05"; 111 112static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" }; 113 114#define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *)) 115int TST_TOTAL = NUMBER_OF_ENVIRON; 116 117#if defined(linux) && defined(__i386__) 118 119struct 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; 130}; 131 132static int a = 42; 133 134static void modify_ldt(int func, struct modify_ldt_ldt_s *ptr, int bytecount) 135{ 136 tst_syscall(__NR_modify_ldt, func, ptr, bytecount); 137} 138 139int main(void) 140{ 141 struct modify_ldt_ldt_s ldt0; 142 int lo; 143 pid_t pid; 144 int res; 145 146 ldt0.entry_number = 0; 147 ldt0.base_addr = (long)&a; 148 ldt0.limit = 4; 149 ldt0.seg_32bit = 1; 150 ldt0.contents = 0; 151 ldt0.read_exec_only = 0; 152 ldt0.limit_in_pages = 0; 153 ldt0.seg_not_present = 0; 154 ldt0.useable = 1; 155 ldt0.empty = 0; 156 157 modify_ldt(1, &ldt0, sizeof(ldt0)); 158 159 asm volatile ("movw %w0, %%fs"::"q" (7)); 160 161 asm volatile ("movl %%fs:0, %0":"=r" (lo)); 162 tst_resm(TINFO, "a = %d", lo); 163 164 asm volatile ("pushl %%fs; popl %0":"=q" (lo)); 165 tst_resm(TINFO, "%%fs = %#06hx", lo); 166 167 asm volatile ("movl %0, %%fs:0"::"r" (99)); 168 169 pid = fork(); 170 171 if (pid == 0) { 172 asm volatile ("pushl %%fs; popl %0":"=q" (lo)); 173 tst_resm(TINFO, "%%fs = %#06hx", lo); 174 175 asm volatile ("movl %%fs:0, %0":"=r" (lo)); 176 tst_resm(TINFO, "a = %d", lo); 177 178 if (lo != 99) 179 tst_resm(TFAIL, "Test failed"); 180 else 181 tst_resm(TPASS, "Test passed"); 182 exit(lo != 99); 183 } else { 184 waitpid(pid, &res, 0); 185 } 186 187 return WIFSIGNALED(res); 188} 189 190#else /* if defined(linux) && defined(__i386__) */ 191 192int main(void) 193{ 194 tst_resm(TINFO, "%%fs test only for ix86"); 195 196 /* 197 * should be successful on all non-ix86 platforms. 198 */ 199 tst_exit(); 200} 201 202#endif /* if defined(linux) && defined(__i386__) */ 203