diff -r 000000000000 -r a41df078684a kerneltest/e32test/secure/t_suser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/secure/t_suser.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,1279 @@ +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\secure\t_suser.cpp +// Overview: +// Test the platform security aspects of the User and UserSvr classes. +// API Information: +// User, UserSvr +// Details: +// - Attempt to get and set the machine configuration with and without +// the proper privileges. Verify results are as expected. +// - Test various critical threads and processes with different capabilities, +// verify results are as expected. +// - Verify that the SetPriorityControl and PriorityControl methods work as +// expected. +// - Verify that the UserSvr::CaptureEventHook, ReleaseEventHook, RequestEvent, +// and RequestEventCancel work as expected. +// - Test handled and unhandled exceptions work as expected. +// - Test ResetInactivityTime() with different capabilities. Verify results. +// - Test SetHomeTime() with different capabilities. Verify results. +// - Test SetMemoryThresholds() with different capabilities. Verify results. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#define __E32TEST_EXTENSION__ + +#include +#include +#include + +LOCAL_D RTest test(_L("T_SUSER")); + +_LIT(KSyncSemaphoreName,"T_SUSER-SyncSemaphore"); +RSemaphore SyncSemaphore; + + +void SlaveWait() + { + RSemaphore sem; + if(sem.OpenGlobal(KSyncSemaphoreName,EOwnerThread)!=KErrNone) + User::Invariant(); + sem.Wait(); + sem.Close(); + } + + +void SignalSlave() + { + RSemaphore sem; + if(sem.OpenGlobal(KSyncSemaphoreName,EOwnerThread)!=KErrNone) + User::Invariant(); + sem.Signal(); + sem.Close(); + } + + +class RTestThread : public RThread + { +public: + void Create(TThreadFunction aFunction,TInt aArg=0); + }; + +TInt GetCriticalValue(TAny* aArg) + { + TUint id = (TUint)aArg; + RThread thread; + TInt r = thread.Open(TThreadId(id)); + if (r == KErrNone) + r = (TInt)User::Critical(thread); + thread.Close(); + return r; + } + +void SetThreadCritical(User::TCritical aCritical) + { + // set thread critical as specified + if(User::SetCritical(aCritical)!=KErrNone) + User::Invariant(); + // check critical value was as we set + if(User::Critical()!=aCritical) + User::Invariant(); + // check from another thread + RTestThread thread; + thread.Create(GetCriticalValue, (TUint)thread.Id()); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + if (logonStatus!=(TInt)aCritical) + User::Invariant(); + } + +TInt TestThreadProcessCritical(TAny* aArg) + { + // check thread is not critical + if(User::Critical()!=User::ENotCritical) + User::Invariant(); + // set thread as process critical + SetThreadCritical(User::EProcessCritical); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + // Kill this thread which should also kill the process + switch((TExitType)(TInt)aArg) + { + case EExitKill: + RThread().Kill(999); + break; + case EExitTerminate: + RThread().Terminate(999); + break; + case EExitPanic: + User::Panic(_L("TestPanic"),999); + break; + default: + break; + } + return KErrNone; + } + +TInt TestThreadSystemCritical(TAny*) + { + User::TCritical critical = User::Critical(); + // check thread is not already system critical + if(User::Critical()==User::ESystemCritical) + User::Invariant(); + // set thread as system critical + SetThreadCritical(User::ESystemCritical); + // Can't test system critical thread dying so put back to normal and end + SetThreadCritical(critical); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + return KErrNone; + } + +TInt TestThreadSystemPermanent(TAny*) + { + User::TCritical critical = User::Critical(); + // check thread is not already system permanent + if(User::Critical()==User::ESystemPermanent) + User::Invariant(); + // set thread as system permanent + SetThreadCritical(User::ESystemPermanent); + // Can't test system permanent thread dying so put back to normal and end + SetThreadCritical(critical); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + return KErrNone; + } + +TInt TestThreadSystemProcessCritical(TAny*) + { + User::TCritical critical = User::ProcessCritical(); + // check thread is not already system critical + if(User::ProcessCritical()==User::ESystemCritical) + User::Invariant(); + // set thread as system critical + if(User::SetProcessCritical(User::ESystemCritical)!=KErrNone) + User::Invariant(); + // check critical value was as we set + if(User::ProcessCritical()!=User::ESystemCritical) + User::Invariant(); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + // wait for main test thread to tell us to continue... + SlaveWait(); + // Can't test system critical thread dying so put back to normal and end + if(User::SetProcessCritical(critical)!=KErrNone) + User::Invariant(); + if(User::ProcessCritical()!=critical) + User::Invariant(); + return KErrNone; + } + +TInt TestThreadSystemProcessPermanent(TAny*) + { + User::TCritical critical = User::ProcessCritical(); + // check thread is not already system permanent + if(User::ProcessCritical()==User::ESystemPermanent) + User::Invariant(); + // set thread as system permanent + if(User::SetProcessCritical(User::ESystemPermanent)!=KErrNone) + User::Invariant(); + // check critical value was as we set + if(User::ProcessCritical()!=User::ESystemPermanent) + User::Invariant(); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + // wait for main test thread to tell us to continue... + SlaveWait(); + // Can't test system permanent thread dying so put back to normal and end + if(User::SetProcessCritical(critical)!=KErrNone) + User::Invariant(); + if(User::ProcessCritical()!=critical) + User::Invariant(); + return KErrNone; + } + +TInt TestThreadTraceKallthreadssystem(TAny*) + { + TUint32 mask = UserSvr::DebugMask(DEBUGMASKWORD2); + // check thread does not already have KALLTHREADSSYSTEM bit set + if (mask & (1 << (KALLTHREADSSYSTEM%32))) + User::Invariant(); + // set KALLTHREADSSYSTEM bit + User::SetDebugMask(mask | (1 << (KALLTHREADSSYSTEM%32)), DEBUGMASKWORD2); + // check KALLTHREADSSYSTEM bit was as we set + if(!(UserSvr::DebugMask(DEBUGMASKWORD2) & (1 << (KALLTHREADSSYSTEM%32)))) + User::Invariant(); + // restore original mask + User::SetDebugMask(mask, DEBUGMASKWORD2); + if(UserSvr::DebugMask(DEBUGMASKWORD2) & (1 << (KALLTHREADSSYSTEM%32))) + User::Invariant(); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + return KErrNone; + } + +TInt TestThreadAllThreadsCritical(TAny* aArg) + { + // check that thread was created process critical + if(User::Critical()!=User::EProcessCritical) + User::Invariant(); + // complete rendezvous to let test code know we got this far ok + RProcess::Rendezvous(KErrNone); + // Kill this thread which should also kill the process + switch((TExitType)(TInt)aArg) + { + case EExitKill: + RThread().Kill(999); + break; + case EExitTerminate: + RThread().Terminate(999); + break; + case EExitPanic: + User::Panic(_L("TestPanic"),999); + break; + default: + break; + } + return KErrNone; + } + +TInt TestAllThreadsCritical(TExitType aExitType) + { + // check process does not already have all threads critical + if(User::ProcessCritical()==User::EAllThreadsCritical) + User::Panic(_L("TestAllThreadsCritical"),__LINE__); + // set process as all threads critical + if(User::SetProcessCritical(User::EAllThreadsCritical)!=KErrNone) + User::Panic(_L("TestAllThreadsCritical"),__LINE__); + // check critical value was as we set + if(User::ProcessCritical()!=User::EAllThreadsCritical) + User::Panic(_L("TestAllThreadsCritical"),__LINE__); + // spawn a thread that exits in the specifed way + RTestThread thread; + thread.Create(TestThreadAllThreadsCritical,aExitType); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + return KErrNone; + } + +void RTestThread::Create(TThreadFunction aFunction,TInt aArg) + { + TInt r=RThread::Create(_L(""),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,(TAny*)aArg); + test(r==KErrNone); + } + + + +enum TTestProcessFunctions + { + ETestProcessMachineConfigGet, + ETestProcessMachineConfigSet, + ETestProcessProcessCriticalNormalEnd, + ETestProcessProcessCriticalKill, + ETestProcessProcessCriticalTerminate, + ETestProcessProcessCriticalPanic, + ETestProcessAllThreadsCriticalNormalEnd, + ETestProcessAllThreadsCriticalKill, + ETestProcessAllThreadsCriticalTerminate, + ETestProcessAllThreadsCriticalPanic, + ETestProcessSystemCritical, + ETestProcessSystemPermanent, + ETestProcessSystemProcessCritical, + ETestProcessSystemProcessPermanent, + ETestProcessCaptureEventHook, + ETestProcessReleaseEventHook, + ETestProcessRequestEvent, + ETestProcessRequestEventCancel, + ETestProcessSetHomeTime, + ETestProcessSetMemoryThresholds, + ETestProcessSetUTCOffset, + ETestProcessSetUTCTime, + ETestProcessSetUTCTimeAndOffset, + ETestProcessTraceKallthreadssystem, + ETestProcessLocaleSet, + ETestProcessUserSetCurrencySymbol, + ETestProcessChangeLocale, + ETestProcessSaveSystemSettings, + ETestProcessSetCurrencySymbol, + ETestProcessAddEventESwitchOff, + ETestProcessAddEventECaseOpen, + ETestProcessAddEventECaseClose + }; + +#include "testprocess.h" + +const TInt KMachineConfigSize = 1024; +TBuf8 MachineConfig; + +TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2) + { + (void)aArg1; + (void)aArg2; + + RThread me; + me.SetPriority(EPriorityLess); + + switch(aTestNum) + { + + case ETestProcessMachineConfigGet: + { + TInt size=0; + TInt r=User::MachineConfiguration(MachineConfig,size); + if(r!=KErrNone) + User::Invariant(); + MachineConfig.SetLength(size); + return KErrNone; + } + + case ETestProcessMachineConfigSet: + { + TInt size=0; + TInt r=User::MachineConfiguration(MachineConfig,size); + if(r!=KErrNone) + User::Invariant(); + MachineConfig.SetLength(size); + + r=User::SetMachineConfiguration(MachineConfig); + if(r!=KErrNone) + User::Invariant(); + return KErrNone; + } + + case ETestProcessProcessCriticalNormalEnd: + { + RTestThread thread; + thread.Create(TestThreadProcessCritical,-1); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + return KErrNone; + } + + case ETestProcessProcessCriticalKill: + { + RTestThread thread; + thread.Create(TestThreadProcessCritical,EExitKill); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + return KErrNone; + } + + case ETestProcessProcessCriticalTerminate: + { + RTestThread thread; + thread.Create(TestThreadProcessCritical,EExitTerminate); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + return KErrNone; + } + + case ETestProcessProcessCriticalPanic: + { + RTestThread thread; + thread.Create(TestThreadProcessCritical,EExitPanic); + TRequestStatus logonStatus; + thread.Logon(logonStatus); + thread.Resume(); + User::WaitForRequest(logonStatus); + return KErrNone; + } + + case ETestProcessAllThreadsCriticalNormalEnd: + return TestAllThreadsCritical((TExitType)-1); + + case ETestProcessAllThreadsCriticalKill: + return TestAllThreadsCritical(EExitKill); + + case ETestProcessAllThreadsCriticalTerminate: + return TestAllThreadsCritical(EExitTerminate); + + case ETestProcessAllThreadsCriticalPanic: + return TestAllThreadsCritical(EExitPanic); + + case ETestProcessSystemCritical: + return TestThreadSystemCritical(NULL); + + case ETestProcessSystemPermanent: + return TestThreadSystemPermanent(NULL); + + case ETestProcessSystemProcessCritical: + return TestThreadSystemProcessCritical(NULL); + + case ETestProcessSystemProcessPermanent: + return TestThreadSystemProcessPermanent(NULL); + + case ETestProcessCaptureEventHook: + UserSvr::CaptureEventHook(); + break; + + case ETestProcessReleaseEventHook: + UserSvr::ReleaseEventHook(); + break; + + case ETestProcessRequestEvent: + { + TRawEventBuf event; + TRequestStatus status; + UserSvr::RequestEvent(event,status); + } + break; + + case ETestProcessRequestEventCancel: + UserSvr::RequestEventCancel(); + break; + + case ETestProcessSetHomeTime: + { + TTime time; + time.HomeTime(); + User::SetHomeTime(time); + } + break; + + case ETestProcessSetUTCOffset: + { + User::SetUTCOffset(0); + } + break; + + case ETestProcessSetUTCTime: + { + TTime time; + time.UniversalTime(); + User::SetUTCTime(time); + } + break; + + case ETestProcessSetUTCTimeAndOffset: + { + TTime time; + time.UniversalTime(); + User::SetUTCTimeAndOffset(time,0); + } + break; + + case ETestProcessSetMemoryThresholds: + { + return UserSvr::SetMemoryThresholds(0,KMaxTInt); + } + + case ETestProcessTraceKallthreadssystem: + return TestThreadTraceKallthreadssystem(NULL); + + case ETestProcessLocaleSet: + return TLocale().Set(); + + case ETestProcessUserSetCurrencySymbol: + return User::SetCurrencySymbol(TCurrencySymbol()); + + case ETestProcessChangeLocale: + return UserSvr::ChangeLocale(KNullDesC); + + case ETestProcessSaveSystemSettings: + { + TExtendedLocale locale; + locale.LoadSystemSettings(); + return locale.SaveSystemSettings(); + } + + case ETestProcessSetCurrencySymbol: + { + TExtendedLocale locale; + locale.LoadSystemSettings(); + return locale.SetCurrencySymbol(TCurrencySymbol()); + } + + case ETestProcessAddEventESwitchOff: + { + TRawEvent event; + event.Set(TRawEvent::ESwitchOff); + return UserSvr::AddEvent(event); + } + + case ETestProcessAddEventECaseOpen: + { + TRawEvent event; + event.Set(TRawEvent::ECaseOpen); + return UserSvr::AddEvent(event); + } + + case ETestProcessAddEventECaseClose: + { + TRawEvent event; + event.Set(TRawEvent::ECaseClose); + return UserSvr::AddEvent(event); + } + + default: + User::Panic(_L("T_SUSER"),1); + } + + return KErrNone; + } + + + +void TestMachineConfiguration() + { + RTestProcess process; + TRequestStatus logonStatus; + + test.Start(_L("Try getting machine-config without ECapabilityReadDeviceData")); + process.Create(~(1u< cmd; + User::CommandLine(cmd); + if(cmd.Length() && TChar(cmd[0]).IsDigit()) + { + TInt function = -1; + TInt arg1 = -1; + TInt arg2 = -1; + TLex lex(cmd); + + lex.Val(function); + lex.SkipSpace(); + lex.Val(arg1); + lex.SkipSpace(); + lex.Val(arg2); + return DoTestProcess(function,arg1,arg2); + } + + test.Title(); + + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)) + { + test.Start(_L("TESTS NOT RUN - EPlatSecEnforcement is OFF")); + test.End(); + return 0; + } + + test_KErrNone(SyncSemaphore.CreateGlobal(KSyncSemaphoreName,0)); + + test.Start(_L("Test MachineConfiguration()")); + TestMachineConfiguration(); + + test.Next(_L("Test SetCritical()")); + TestSetCritical(); + + test.Next(_L("Test Set/PriorityControl()")); + User::SetPriorityControl(ETrue); + test(User::PriorityControl()); + User::SetPriorityControl(EFalse); + test(!User::PriorityControl()); + + test.Next(_L("Test Event functions")); + TestEvents(); + + test.Next(_L("Test Exception functions")); + TestException(); + + test.Next(_L("Test SetHomeTime()")); + TestSetHomeTime(); + + test.Next(_L("Test SetUTCOffset()")); + TestSetUTCOffset(); + + test.Next(_L("Test SetUTCTime()")); + TestSetUTCTime(); + + test.Next(_L("Test SetUTCTimeAndOffset()")); + TestSetUTCTimeAndOffset(); + + test.Next(_L("Test SetMemoryThresholds")); + TestSetMemoryThresholds(); + + test.Next(_L("Test Locale::Set")); + TestWithWriteDeviceData(ETestProcessLocaleSet); + + test.Next(_L("Test User::SetCurrencySymbol")); + TestWithWriteDeviceData(ETestProcessUserSetCurrencySymbol); + + test.Next(_L("Test UserSvr::ChangeLocale")); + TestWithWriteDeviceData(ETestProcessChangeLocale); + + test.Next(_L("Test TExtendedLocale::SaveSystemSettings")); + TestWithWriteDeviceData(ETestProcessSaveSystemSettings); + + test.Next(_L("Test TExtendedLocale::SetCurrencySymbol")); + TestWithWriteDeviceData(ETestProcessSetCurrencySymbol); + + SyncSemaphore.Close(); + test.End(); + return(0); + } +