fork05.c revision 181906907072c2066184e64d9c4e8e75e62eb4d5
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., 59
22 * Temple Place - Suite 330, Boston MA 02111-1307, 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 "test.h"
108#include "usctest.h"
109
110char *TCID = "fork05";
111
112static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" };
113#define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *))
114int TST_TOTAL = NUMBER_OF_ENVIRON;
115
116#if defined(linux) && defined(__i386__)
117
118struct modify_ldt_ldt_s {
119	unsigned int entry_number;
120	unsigned long int base_addr;
121	unsigned int limit;
122	unsigned int seg_32bit:1;
123	unsigned int contents:2;
124	unsigned int read_exec_only:1;
125	unsigned int limit_in_pages:1;
126	unsigned int seg_not_present:1;
127	unsigned int useable:1;
128	unsigned int empty:25;
129};
130
131static int a = 42;
132
133static void modify_ldt(int, struct modify_ldt_ldt_s *, int);
134asm("	.text\n\
135	.type modify_ldt,@function \n\
136modify_ldt: \n\
137	push   %ebx \n\
138	mov    0x10(%esp,1),%edx \n\
139	mov    0xc(%esp,1),%ecx \n\
140	mov    0x8(%esp,1),%ebx \n\
141	mov    $0x7b,%eax \n\
142	int    $0x80 \n\
143	pop    %ebx \n\
144	ret");
145
146int main()
147{
148	struct modify_ldt_ldt_s ldt0;
149	int lo;
150	pid_t pid;
151	int res;
152
153	ldt0.entry_number = 0;
154	ldt0.base_addr = (long)&a;
155	ldt0.limit = 4;
156	ldt0.seg_32bit = 1;
157	ldt0.contents = 0;
158	ldt0.read_exec_only = 0;
159	ldt0.limit_in_pages = 0;
160	ldt0.seg_not_present = 0;
161	ldt0.useable = 1;
162	ldt0.empty = 0;
163
164	modify_ldt(1, &ldt0, sizeof(ldt0));
165
166	asm volatile ("movw %w0, %%fs"::"q" (7));
167
168	asm volatile ("movl %%fs:0, %0":"=r" (lo));
169	tst_resm(TINFO, "a = %d", lo);
170
171	asm volatile ("pushl %%fs; popl %0":"=q" (lo));
172	tst_resm(TINFO, "%%fs = %#06hx", lo);
173
174	asm volatile ("movl %0, %%fs:0"::"r" (99));
175
176	pid = fork();
177
178	if (pid == 0) {
179		asm volatile ("pushl %%fs; popl %0":"=q" (lo));
180		tst_resm(TINFO, "%%fs = %#06hx", lo);
181
182		asm volatile ("movl %%fs:0, %0":"=r" (lo));
183		tst_resm(TINFO, "a = %d", lo);
184
185		if (lo != 99)
186			tst_resm(TFAIL, "Test failed");
187		else
188			tst_resm(TPASS, "Test passed");
189		exit(lo != 99);
190	} else {
191		waitpid(pid, &res, 0);
192	}
193
194	return WIFSIGNALED(res);
195}
196
197#else /* if defined(linux) && defined(__i386__) */
198
199int main()
200{
201	tst_resm(TINFO, "%%fs test only for ix86");
202
203	/*
204	 * should be successful on all non-ix86 platforms.
205	 */
206	tst_exit();
207}
208
209#endif /* if defined(linux) && defined(__i386__) */
210