• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
110 char *TCID = "fork05";
111 
112 static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" };
113 
114 #define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *))
115 int TST_TOTAL = NUMBER_OF_ENVIRON;
116 
117 #if defined(linux) && defined(__i386__)
118 
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;
130 };
131 
132 static int a = 42;
133 
modify_ldt(int func,struct modify_ldt_ldt_s * ptr,int bytecount)134 static 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 
main(void)139 int 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 
main(void)192 int 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