| /* |
| * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. |
| * Portions Copyright (c) 2000 Ulrich Drepper |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of version 2 of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it would be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * |
| * Further, this software is distributed without any warranty that it is |
| * free of the rightful claim of any third person regarding infringement |
| * or the like. Any license provided herein, whether implied or |
| * otherwise, applies only to this software file. Patent licenses, if |
| * any, provided herein do not apply to combinations of this program with |
| * other software, or any other product whatsoever. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, |
| * Mountain View, CA 94043, or: |
| * |
| * http://www.sgi.com$ |
| * |
| * For further information regarding this notice, see:$ |
| * |
| * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ |
| * |
| * |
| * Linux Test Project - Silicon Graphics, Inc. |
| * TEST IDENTIFIER : fork05 |
| * EXECUTED BY : anyone |
| * TEST TITLE : Make sure LDT is propagated correctly |
| * TEST CASE TOTAL : 1 |
| * CPU TYPES : i386 |
| * AUTHORS : Ulrich Drepper |
| * Nate Straz |
| * |
| *On Friday, May 2, 2003 at 09:47:00AM MST, Ulrich Drepper wrote: |
| *>Robert Williamson wrote: |
| *> |
| *>> I'm getting a SIGSEGV with one of our tests, fork05.c, that apparently |
| *>> you wrote (attached below). The test passes on my 2.5.68 machine running |
| *>> SuSE 8.0 (glibc 2.2.5 and Linuxthreads), however it segmentation faults on |
| *>> RedHat 9 running 2.5.68. The test seems to "break" when it attempts to run |
| *>> the assembly code....could you take a look at it? |
| *> |
| *>There is no need to look at it, I know it cannot work anymore on recent |
| *>systems. Either change all uses of %gs to %fs or skip the entire patch |
| *>if %gs has a nonzero value. |
| *> |
| *>- -- |
| *>- --------------. ,-. 444 Castro Street |
| *>Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA |
| *>Red Hat `--' drepper at redhat.com `--------------------------- |
| * |
| * |
| * |
| *On Sat, Aug 12, 2000 at 12:47:31PM -0700, Ulrich Drepper wrote: |
| *> Ever since the %gs handling was fixed in the 2.3.99 series the |
| *> appended test program worked. Now with 2.4.0-test6 it's not working |
| *> again. Looking briefly over the patch from test5 to test6 I haven't |
| *> seen an immediate candidate for the breakage. It could be missing |
| *> propagation of the LDT to the new process (and therefore an invalid |
| *> segment descriptor) or simply clearing %gs. |
| *> |
| *> Anyway, this is what you should see and what you get with test5: |
| *> |
| *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| *> a = 42 |
| *> %gs = 0x0007 |
| *> %gs = 0x0007 |
| *> a = 99 |
| *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| *> |
| *> This is what you get with test6: |
| *> |
| *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| *> a = 42 |
| *> %gs = 0x0007 |
| *> %gs = 0x0000 |
| *> <SEGFAULT> |
| *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| *> |
| *> If somebody is actually creating a test suite for the kernel, please |
| *> add this program. It's mostly self-contained. The correct handling |
| *> of %gs is really important since glibc 2.2 will make heavy use of it. |
| *> |
| *> - -- |
| *> - ---------------. ,-. 1325 Chesapeake Terrace |
| *> Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA |
| *> Red Hat `--' drepper at redhat.com `------------------------ |
| *> |
| *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <sys/wait.h> |
| #include "test.h" |
| |
| char *TCID = "fork05"; |
| |
| static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" }; |
| |
| #define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *)) |
| int TST_TOTAL = NUMBER_OF_ENVIRON; |
| |
| #if defined(linux) && defined(__i386__) |
| |
| struct modify_ldt_ldt_s { |
| unsigned int entry_number; |
| unsigned long int base_addr; |
| unsigned int limit; |
| unsigned int seg_32bit:1; |
| unsigned int contents:2; |
| unsigned int read_exec_only:1; |
| unsigned int limit_in_pages:1; |
| unsigned int seg_not_present:1; |
| unsigned int useable:1; |
| unsigned int empty:25; |
| }; |
| |
| static int a = 42; |
| |
| static void modify_ldt(int, struct modify_ldt_ldt_s *, int); |
| asm(" .text\n\ |
| .type modify_ldt,@function \n\ |
| modify_ldt: \n\ |
| push %ebx \n\ |
| mov 0x10(%esp,1),%edx \n\ |
| mov 0xc(%esp,1),%ecx \n\ |
| mov 0x8(%esp,1),%ebx \n\ |
| mov $0x7b,%eax \n\ |
| int $0x80 \n\ |
| pop %ebx \n\ |
| ret"); |
| |
| int main(void) |
| { |
| struct modify_ldt_ldt_s ldt0; |
| int lo; |
| pid_t pid; |
| int res; |
| |
| ldt0.entry_number = 0; |
| ldt0.base_addr = (long)&a; |
| ldt0.limit = 4; |
| ldt0.seg_32bit = 1; |
| ldt0.contents = 0; |
| ldt0.read_exec_only = 0; |
| ldt0.limit_in_pages = 0; |
| ldt0.seg_not_present = 0; |
| ldt0.useable = 1; |
| ldt0.empty = 0; |
| |
| modify_ldt(1, &ldt0, sizeof(ldt0)); |
| |
| asm volatile ("movw %w0, %%fs"::"q" (7)); |
| |
| asm volatile ("movl %%fs:0, %0":"=r" (lo)); |
| tst_resm(TINFO, "a = %d", lo); |
| |
| asm volatile ("pushl %%fs; popl %0":"=q" (lo)); |
| tst_resm(TINFO, "%%fs = %#06hx", lo); |
| |
| asm volatile ("movl %0, %%fs:0"::"r" (99)); |
| |
| pid = fork(); |
| |
| if (pid == 0) { |
| asm volatile ("pushl %%fs; popl %0":"=q" (lo)); |
| tst_resm(TINFO, "%%fs = %#06hx", lo); |
| |
| asm volatile ("movl %%fs:0, %0":"=r" (lo)); |
| tst_resm(TINFO, "a = %d", lo); |
| |
| if (lo != 99) |
| tst_resm(TFAIL, "Test failed"); |
| else |
| tst_resm(TPASS, "Test passed"); |
| exit(lo != 99); |
| } else { |
| waitpid(pid, &res, 0); |
| } |
| |
| return WIFSIGNALED(res); |
| } |
| |
| #else /* if defined(linux) && defined(__i386__) */ |
| |
| int main(void) |
| { |
| tst_resm(TINFO, "%%fs test only for ix86"); |
| |
| /* |
| * should be successful on all non-ix86 platforms. |
| */ |
| tst_exit(); |
| } |
| |
| #endif /* if defined(linux) && defined(__i386__) */ |