-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
General code cleanup and a new ascii doc description. user_desc struct is now imported from the kernel headers. Reviewed-by: Cyril Hrubis <[email protected]> Signed-off-by: Andrea Cervesato <[email protected]>
- Loading branch information
Showing
1 changed file
with
72 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,202 +1,120 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* 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. | ||
* Author: Ulrich Drepper / Nate Straz , Red Hat | ||
* Copyright (C) 2023 SUSE LLC Andrea Cervesato <[email protected]> | ||
*/ | ||
|
||
/*\ | ||
* [Description] | ||
* | ||
* 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. | ||
* This test verifies that LDT is propagated correctly from parent process to | ||
* the child process. | ||
* | ||
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, | ||
* Mountain View, CA 94043, or: | ||
* On Friday, May 2, 2003 at 09:47:00AM MST, Ulrich Drepper wrote: | ||
* | ||
* http://www.sgi.com$ | ||
* Robert Williamson wrote: | ||
* | ||
* For further information regarding this notice, see:$ | ||
* 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? | ||
* | ||
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/ | ||
* 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. | ||
* | ||
* On Sat, Aug 12, 2000 at 12:47:31PM -0700, Ulrich Drepper wrote: | ||
* | ||
* 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 | ||
* 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. | ||
* | ||
*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 `--------------------------- | ||
* 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: | ||
* | ||
*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 `------------------------ | ||
*> | ||
*> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
* 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. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <sys/wait.h> | ||
#include "lapi/syscalls.h" | ||
#include "test.h" | ||
|
||
char *TCID = "fork05"; | ||
#include "tst_test.h" | ||
|
||
static char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" }; | ||
#if defined(__i386__) | ||
|
||
#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 func, struct modify_ldt_ldt_s *ptr, int bytecount) | ||
{ | ||
tst_syscall(__NR_modify_ldt, func, ptr, bytecount); | ||
} | ||
#include "lapi/syscalls.h" | ||
#include <asm/ldt.h> | ||
|
||
int main(void) | ||
static void run(void) | ||
{ | ||
struct modify_ldt_ldt_s ldt0; | ||
int lo; | ||
struct user_desc ldt0; | ||
int base_addr = 42; | ||
int status; | ||
pid_t pid; | ||
int res; | ||
int lo; | ||
|
||
ldt0.entry_number = 0; | ||
ldt0.base_addr = (long)&a; | ||
ldt0.base_addr = (long)&base_addr; | ||
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)); | ||
tst_syscall(__NR_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); | ||
tst_res(TINFO, "a = %d", lo); | ||
|
||
asm volatile ("pushl %%fs; popl %0":"=q" (lo)); | ||
tst_resm(TINFO, "%%fs = %#06hx", lo); | ||
tst_res(TINFO, "%%fs = %#06hx", lo); | ||
|
||
asm volatile ("movl %0, %%fs:0"::"r" (99)); | ||
|
||
pid = fork(); | ||
|
||
if (pid == 0) { | ||
pid = SAFE_FORK(); | ||
if (!pid) { | ||
asm volatile ("pushl %%fs; popl %0":"=q" (lo)); | ||
tst_resm(TINFO, "%%fs = %#06hx", lo); | ||
tst_res(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); | ||
} | ||
tst_res(TINFO, "a = %d", lo); | ||
|
||
return WIFSIGNALED(res); | ||
} | ||
TST_EXP_EQ_LI(lo, 99); | ||
|
||
#else /* if defined(linux) && defined(__i386__) */ | ||
exit(0); | ||
} | ||
|
||
int main(void) | ||
{ | ||
tst_resm(TINFO, "%%fs test only for ix86"); | ||
SAFE_WAITPID(pid, &status, 0); | ||
|
||
/* | ||
* should be successful on all non-ix86 platforms. | ||
*/ | ||
tst_exit(); | ||
if (WIFEXITED(status) && !WEXITSTATUS(status)) | ||
tst_res(TPASS, "Child did exit with 0"); | ||
else | ||
tst_res(TFAIL, "Child %s", tst_strstatus(status)); | ||
} | ||
|
||
#endif /* if defined(linux) && defined(__i386__) */ | ||
static struct tst_test test = { | ||
.test_all = run, | ||
.forks_child = 1, | ||
}; | ||
|
||
#else | ||
TST_TEST_TCONF("Test only supports Intel 32 bits"); | ||
#endif |