|         |      1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). | 
|         |      2 // All rights reserved. | 
|         |      3 // This component and the accompanying materials are made available | 
|         |      4 // under the terms of the License "Eclipse Public License v1.0" | 
|         |      5 // which accompanies this distribution, and is available | 
|         |      6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      7 // | 
|         |      8 // Initial Contributors: | 
|         |      9 // Nokia Corporation - initial contribution. | 
|         |     10 // | 
|         |     11 // Contributors: | 
|         |     12 // | 
|         |     13 // Description: | 
|         |     14 // e32test\system\t_prot2.cpp | 
|         |     15 //  | 
|         |     16 // | 
|         |     17  | 
|         |     18 #include <e32test.h> | 
|         |     19 #include "u32std.h" | 
|         |     20  | 
|         |     21 const TInt KHeapSize=0x1000; | 
|         |     22  | 
|         |     23 _LIT(KSecondProcessName,"T_PROT2A"); | 
|         |     24 _LIT(KSecondProcessDataChunkName,"T_PROT2A*$DAT"); | 
|         |     25  | 
|         |     26 RTest test(_L("T_PROT2")); | 
|         |     27  | 
|         |     28 LOCAL_C TInt WatcherThread(TAny* aSemaphoreHandle) | 
|         |     29 	{ | 
|         |     30 	RTest wtest(_L("Watcher Thread")); | 
|         |     31 	wtest.Title(); | 
|         |     32 	RThread().SetPriority(EPriorityMuchMore); | 
|         |     33 	wtest.Start(_L("Create undertaker")); | 
|         |     34 	RUndertaker u; | 
|         |     35 	TInt r=u.Create(); | 
|         |     36 	if (r!=KErrNone) | 
|         |     37 		{ | 
|         |     38 		RProcess me; | 
|         |     39 		me.Panic(_L("UNDERTAKER"),r); | 
|         |     40 		} | 
|         |     41 	RSemaphore sem; | 
|         |     42 	sem.SetHandle((TInt)aSemaphoreHandle); | 
|         |     43 	sem.Signal(); | 
|         |     44 	FOREVER | 
|         |     45 		{ | 
|         |     46 		TRequestStatus s; | 
|         |     47 		TInt h; | 
|         |     48 		u.Logon(s,h); | 
|         |     49 		User::WaitForRequest(s); | 
|         |     50 		RThread t; | 
|         |     51 		t.SetHandle(h); | 
|         |     52 		const TDesC& fn=t.FullName(); | 
|         |     53 		wtest.Printf(_L("Thread %S exited\n"),&fn); | 
|         |     54 		const TDesC& cat=t.ExitCategory(); | 
|         |     55 		wtest.Printf(_L("Exit type %d,%d,%S\n"),t.ExitType(),t.ExitReason(),&cat); | 
|         |     56 		t.Close(); | 
|         |     57 		} | 
|         |     58 	} | 
|         |     59  | 
|         |     60 LOCAL_C void StartWatcherThread() | 
|         |     61 	{ | 
|         |     62 	test.Next(_L("Start watcher thread")); | 
|         |     63 	RSemaphore s; | 
|         |     64 	TInt r=s.CreateLocal(0); | 
|         |     65 	test(r==KErrNone); | 
|         |     66 	RThread t; | 
|         |     67 	r=t.Create(_L("WatcherThread"),WatcherThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)s.Handle()); | 
|         |     68 	test(r==KErrNone); | 
|         |     69 	t.Resume(); | 
|         |     70 	s.Wait(); | 
|         |     71 	s.Close(); | 
|         |     72 	} | 
|         |     73  | 
|         |     74 void ExceptionHandler(TExcType) | 
|         |     75 	{ | 
|         |     76 	User::Leave(KErrAbort); | 
|         |     77 	} | 
|         |     78  | 
|         |     79 LOCAL_C TInt RogueThread1(TAny*) | 
|         |     80 	{ | 
|         |     81 	TInt n; | 
|         |     82 	TInt m=0; | 
|         |     83 	TUint* p=NULL; | 
|         |     84 	RChunk c; | 
|         |     85 	User::SetExceptionHandler(ExceptionHandler,KExceptionFault); | 
|         |     86 	for (n=0; n<100; n++) | 
|         |     87 		{ | 
|         |     88 		User::AfterHighRes(1000);	// wait 1ms | 
|         |     89 		if (m==0 && !p) | 
|         |     90 			{ | 
|         |     91 			TFindChunk fc(KSecondProcessDataChunkName); | 
|         |     92 			TFullName fn; | 
|         |     93 			TInt r=fc.Next(fn); | 
|         |     94 			if (r!=KErrNone) | 
|         |     95 				continue; | 
|         |     96 			r=c.Open(fc); | 
|         |     97 			if (r!=KErrNone) | 
|         |     98 				continue; | 
|         |     99 			p=(TUint*)c.Base();	// second process is fixed | 
|         |    100 			continue; | 
|         |    101 			} | 
|         |    102 		if (m==0 && p) | 
|         |    103 			{ | 
|         |    104 			if (c.Size()==0) | 
|         |    105 				continue; | 
|         |    106 			m++; | 
|         |    107 			c.Close(); | 
|         |    108 			} | 
|         |    109 		TRAPD(r,Mem::Fill(p,0x1000,0xc9)); | 
|         |    110 		if (r==KErrNone) | 
|         |    111 			return KErrNone; | 
|         |    112 		} | 
|         |    113 	User::Panic(_L("NOTFOUND"),m); | 
|         |    114 	return KErrNone; | 
|         |    115 	} | 
|         |    116  | 
|         |    117 LOCAL_C void TestLoaderProtection() | 
|         |    118 	{ | 
|         |    119 	test.Next(_L("Create rogue thread")); | 
|         |    120 	RThread t; | 
|         |    121 	TInt r=t.Create(_L("RogueThread1"),RogueThread1,KDefaultStackSize,KHeapSize,KHeapSize,NULL); | 
|         |    122 	test(r==KErrNone); | 
|         |    123 	t.SetPriority(EPriorityRealTime);	// this should be above the loader | 
|         |    124 	TRequestStatus s; | 
|         |    125 	t.Logon(s); | 
|         |    126 	test(s==KRequestPending); | 
|         |    127 	test.Next(_L("Resume rogue thread")); | 
|         |    128 	t.Resume(); | 
|         |    129  | 
|         |    130 	test.Next(_L("Create second process")); | 
|         |    131 	RProcess p; | 
|         |    132 	r=p.Create(KSecondProcessName,KNullDesC); | 
|         |    133 	test(r==KErrNone); | 
|         |    134 	TRequestStatus s2; | 
|         |    135 	p.Logon(s2); | 
|         |    136 	test(s2==KRequestPending); | 
|         |    137 	test.Next(_L("Resume second process")); | 
|         |    138 	p.Resume(); | 
|         |    139 	 | 
|         |    140 	test.Next(_L("Wait for second process to exit")); | 
|         |    141 	User::WaitForRequest(s2); | 
|         |    142 	const TDesC& pcat=p.ExitCategory(); | 
|         |    143 	test.Printf(_L("Exit type %d,%d,%S\n"),p.ExitType(),p.ExitReason(),&pcat); | 
|         |    144 	test.Getch(); | 
|         |    145  | 
|         |    146 	test.Next(_L("Wait for rogue thread to exit")); | 
|         |    147 	User::WaitForRequest(s); | 
|         |    148 	const TDesC& tcat=t.ExitCategory(); | 
|         |    149 	test.Printf(_L("Exit type %d,%d,%S\n"),t.ExitType(),t.ExitReason(),&tcat); | 
|         |    150 	test.Getch(); | 
|         |    151 	} | 
|         |    152  | 
|         |    153 GLDEF_C TInt E32Main() | 
|         |    154 	{ | 
|         |    155 	test.Title(); | 
|         |    156 	test.Start(_L("Testing protection against errant user threads")); | 
|         |    157 	RProcess().SetPriority(EPriorityHigh); | 
|         |    158  | 
|         |    159 	StartWatcherThread(); | 
|         |    160 	TestLoaderProtection(); | 
|         |    161  | 
|         |    162 	test.End(); | 
|         |    163 	return KErrNone; | 
|         |    164 	} |