diff -r 000000000000 -r a41df078684a kerneltest/e32test/secure/t_sserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/secure/t_sserver.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,1228 @@ +// 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_sserver.cpp +// Overview: +// Test the security aspects of server connect by handle. +// API Information: +// CSession2, CServer2 +// Details: +// - Test asynchronous server connect in various ways. Verify results +// are as expected. +// - Attempt to create a protected server without and without +// KCapabilityProtServ. Verify results are as expected. +// - Attempt to connect to a serve with different Secure IDs, Vendor IDs +// and capabilities. Verify results are as expected. +// - Test creating a sub-session, sending it messages and closing it. +// Verify the results. +// - Test TIpcArgs::Set and IPC argument passing. Verify results are +// as expected. +// - Test TIpcArgs:: Also checks the integrity of the server and Kernel if client passes bad descriptor +// for IPC transfer and the integrity of the client and Kernel if the server does the same. +// - Test CServer2::RunError and CSession2::ServiceError and session +// resource counting. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include +#include "../misc/prbs.h" + +LOCAL_D RTest test(_L("T_SSERVER")); + +_LIT_SECURE_ID(KTestSecureId,0x101f534d); +_LIT_SECURE_ID(KTestSecureId2,0x101f534e); +_LIT_VENDOR_ID(KTestVendorId,0x01234567); +_LIT_VENDOR_ID(KTestVendorId2,0x01234568); +const TInt KTestRunErrorModifier = 111; +const TInt KTestServiceErrorModifier = 222; +_LIT(KProtectedServerName,"!T_SSERVER-protected-server"); + + + +enum TTestProcessFunctions + { + ETestProcessServer, + ETestProcessCreateProtectedServer, + }; + +#include "testprocess.h" + + + +// +// RTestThread +// + +class RTestThread : public RThread + { +public: + void Create(TThreadFunction aFunction,TAny* aArg=0); + }; + +void RTestThread::Create(TThreadFunction aFunction,TAny* aArg) + { + TInt r=RThread::Create(_L(""),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,aArg); + test(r==KErrNone); + } + + + +// +// CTestSession +// + +enum TTestSessionFuntions + { + ETestShutdown,EPing, + ETestArgUnspecified,ETestArgDesC8,ETestArgDesC16,ETestArgDes8,ETestArgDes16, + ETestResourceCountPass=0x01234567,ETestResourceCountFail,ETestServiceLeave, + ETestCreateSubSession,ETestCloseSubSession,ETestCloseSubSessionHandle, + ETestEchoArgs,ETestEmptySubSessionMessage, ETestBadClientDescRead, ETestBadClientDescWrite, + ETestBadServerDescRead, ETestBadServerDescWrite + }; + +class CTestSession : public CSession2 + { +public: + CTestSession(); + virtual void ServiceL(const RMessage2& aMessage); + virtual void ServiceError(const RMessage2& aMessage,TInt aError); +private: + TInt CountResources(); +private: + TInt iResourceCount; + TInt iSubSessionCloseHandle; + RMessage2 iMessage; + }; + +class CTestSecureServer : public CServer2 + { +public: + CTestSecureServer(TInt aPriority); + virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; +private: + void CustomL(const RMessage2& aMessage); + void QueryL(const RMessage2& aMessage,HBufC8*& aQueryParams); + TInt RunError(TInt aError); +private: + friend class CTestSession; + }; + +CTestSession::CTestSession() + : CSession2() + {} + +void CTestSession::ServiceL(const RMessage2& aMessage) + { + TInt r = KErrNotSupported; + TBuf8<100> buf8; + buf8.Append(_L8("12345")); + TBuf16<100> buf16; + buf16.Append(_L16("12345")); + TInt testArg = ((TUint)aMessage.Function())>>28; + + TInt badDescriptorError = PlatSec::ConfigSetting(PlatSec::EPlatSecProcessIsolation)&&PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement) + ? KErrBadDescriptor : KErrNone; + + switch(aMessage.Function()&0x0fffffff) + { + case ETestShutdown: + CActiveScheduler::Stop(); + return; + + case EPing: + r=aMessage.Int0(); + break; + + case ETestArgUnspecified: + r = aMessage.GetDesLength(testArg); + if(r!=KErrBadDescriptor) + goto fail; + r = aMessage.GetDesMaxLength(testArg); + if(r!=KErrBadDescriptor) + goto fail; + r = aMessage.Read(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Read(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + goto pass; + + case ETestArgDesC8: + r = aMessage.GetDesLength(testArg); + if(r<0) + goto fail; + r = aMessage.GetDesMaxLength(testArg); + if(r<0) + goto fail; + r = aMessage.Read(testArg,buf8); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf8)); + if(r!=KErrNone) + goto fail; + r = aMessage.Read(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + goto pass; + + case ETestArgDesC16: + r = aMessage.GetDesLength(testArg); + if(r<0) + goto fail; + r = aMessage.GetDesMaxLength(testArg); + if(r<0) + goto fail; + r = aMessage.Read(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Read(testArg,buf16); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf16)); + if(r!=KErrNone) + goto fail; + r = aMessage.Write(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + goto pass; + + case ETestArgDes8: + r = aMessage.GetDesLength(testArg); + if(r<0) + goto fail; + r = aMessage.GetDesMaxLength(testArg); + if(r<0) + goto fail; + r = aMessage.Read(testArg,buf8); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf8)); + if(r!=KErrNone) + goto fail; + r = aMessage.Read(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf8); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf8)); + if(r!=KErrNone) + goto fail; + r = aMessage.Write(testArg,buf16); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf16)); + if(r!=badDescriptorError) + goto fail; + goto pass; + + case ETestArgDes16: + r = aMessage.GetDesLength(testArg); + if(r<0) + goto fail; + r = aMessage.GetDesMaxLength(testArg); + if(r<0) + goto fail; + r = aMessage.Read(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Read(testArg,buf16); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.ReadL(testArg,buf16)); + if(r!=KErrNone) + goto fail; + r = aMessage.Write(testArg,buf8); + if(r!=badDescriptorError) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf8)); + if(r!=badDescriptorError) + goto fail; + r = aMessage.Write(testArg,buf16); + if(r!=KErrNone) + goto fail; + TRAP(r,aMessage.WriteL(testArg,buf16)); + if(r!=KErrNone) + goto fail; + goto pass; + + case ETestBadClientDescRead: + //Testing the integrity of the server and Kernel if the client passes bad descriptor for IPC transfer + { + r = aMessage.GetDesLength(testArg); + TUint8* buff; + buff = (TUint8*)User::Alloc(r); + if (!buff) + { + r=KErrNoMemory; + break; + } + TPtr8 ptr8(buff, r, r); + r=aMessage.Read(testArg,ptr8); + User::Free(buff); + } + break; + + case ETestBadClientDescWrite: + //Testing the integrity of the server and Kernel if the client passes bad descriptor for IPC transfer + { + r = aMessage.GetDesLength(testArg); + TUint8* buff; + buff = (TUint8*)User::Alloc(r); + if (!buff) + { + r=KErrNoMemory; + break; + } + TPtr8 ptr8(buff, r, r); + r=aMessage.Write(testArg,ptr8); + User::Free(buff); + } + break; + + case ETestBadServerDescRead: + case ETestBadServerDescWrite: + //Testing the integrity of the client and Kernel if server passes bad descriptor for IPC transfer + { + //Create a chunk with a hole between addresses 0x1000 and 0x2000 + RChunk c; + r=c.CreateDisconnectedLocal(0,0,0x200000); + test(r==KErrNone); + r=c.Commit(0,0x1000); + test(r==KErrNone); + r=c.Commit(0x2000,0x1000); + test(r==KErrNone); + + TInt base,len; + switch(aMessage.Function()>>28) + { + case 0:base=0x1000;len=0x500;break; + case 1:base=0x1001;len=0x500;break; + case 2:base=0x1007;len=0x500;break; + case 3:base=0x1ff0;len=0x100;break; + case 4:base=0x1ff1;len=0x100;break; + case 5:base=0x1ff2;len=0x100;break; + case 6:base=0xff3;len=0x100;break; + default:base=0xfff;len=0x100;break; + } + + TPtr8 ptr (c.Base()+base,len,len); + if ((aMessage.Function()&0x0fffffff) == ETestBadServerDescRead) + aMessage.Read(0,ptr); //The server should panic here + else + aMessage.Write(0,ptr); //The server should panic here + } + break; + + case ETestResourceCountPass: + r=aMessage.Function(); + ResourceCountMarkStart(); + ResourceCountMarkEnd(aMessage); + break; + + case ETestResourceCountFail: + r=aMessage.Function(); + ResourceCountMarkStart(); + ++iResourceCount; + ResourceCountMarkEnd(aMessage); + break; + + case ETestServiceLeave: + iMessage = aMessage; + User::Leave(aMessage.Int0()); + break; + + case ETestCreateSubSession: + { + TInt reply = aMessage.Int0(); + r = aMessage.Write(3,TPtrC8((TUint8*)&reply,sizeof(reply))); + } + break; + + case ETestCloseSubSession: + iSubSessionCloseHandle = aMessage.Int3(); + r = KErrNone; + break; + + case ETestCloseSubSessionHandle: + r = iSubSessionCloseHandle; + iSubSessionCloseHandle = 0; + break; + + case ETestEchoArgs: + { + TInt reply[4]; + reply[0] = aMessage.Int0(); + reply[1] = aMessage.Int1(); + reply[2] = aMessage.Int2(); + reply[3] = aMessage.Int3(); + r = aMessage.Write(0,TPtrC8((TUint8*)&reply,sizeof(reply))); + } + break; + + case ETestEmptySubSessionMessage: + r = aMessage.Int3(); + break; + + default: + break; + } + if(aMessage.Handle()) + aMessage.Complete(r); + return; +fail: + aMessage.Complete(KErrGeneral); + return; +pass: + aMessage.Complete(KErrNone); + return; + } + +TInt CTestSession::CountResources() + { + return iResourceCount; + } + +void CTestSession::ServiceError(const RMessage2& aMessage,TInt aError) + { + if(aMessage!=iMessage) + aError = KErrGeneral; // We got given the right message + else + aError += KTestServiceErrorModifier; // Let test harnes know we came through this routine + CSession2::ServiceError(aMessage,aError); + } + +// +// CTestSecureServer +// + +CTestSecureServer::CTestSecureServer(TInt aPriority) + : CServer2(aPriority,EGlobalSharableSessions) + { + } + +CSession2* CTestSecureServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const + { + if(*(TInt*)&aVersion) + User::Leave(KErrNotSupported); // Only accept version 0.0.00 + return new (ELeave) CTestSession(); + } + +TInt CTestSecureServer::RunError(TInt aError) + { + return CServer2::RunError(aError+KTestRunErrorModifier); // Let test harnes know we came through this routine + } + + +// +// CTestActiveScheduler +// + +class CTestActiveScheduler : public CActiveScheduler + { +public: + virtual void Error(TInt anError) const; + }; + +void CTestActiveScheduler::Error(TInt anError) const + { + User::Panic(_L("TestServer Error"),anError); + } + + + +// +// Server thread +// + +_LIT(KServerName,"T_SSERVER-server"); +const TInt KServerRendezvous = KRequestPending+1; + +void DoStartServer() + { + CTestActiveScheduler* activeScheduler = new (ELeave) CTestActiveScheduler; + CActiveScheduler::Install(activeScheduler); + CleanupStack::PushL(activeScheduler); + + CTestSecureServer* server = new (ELeave) CTestSecureServer(0); + CleanupStack::PushL(server); + + User::LeaveIfError(server->Start(KServerName)); + + RProcess::Rendezvous(KServerRendezvous); + + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(2); + } + +TInt StartServer() + { + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if(!cleanupStack) + return KErrNoMemory; + TRAPD(leaveError,DoStartServer()) + delete cleanupStack; + return leaveError; + } + + + +// +// RTestSession +// + +class RTestSession : public RSessionBase + { +public: + inline TInt Connect() + { + TInt r=CreateSession(KServerName,TVersion()); + if(r) return r; + return ShareAuto(); + } + inline TInt Connect(const TSecurityPolicy* aPolicy) + { + return CreateSession(KServerName,TVersion(),-1,EIpcSession_Unsharable,aPolicy,0); + } + inline TInt Connect(TVersion aVersion,TRequestStatus* aStatus) + { + return CreateSession(KServerName,aVersion,-1,EIpcSession_Unsharable,0,aStatus); + } + inline TInt Send(TInt aFunction) + { return RSessionBase::SendReceive(aFunction); } + inline TInt Send(TInt aFunction,const TIpcArgs& aArgs) + { return RSessionBase::SendReceive(aFunction,aArgs); } + inline void Send(TInt aFunction,TRequestStatus& aStatus) + { RSessionBase::SendReceive(aFunction,aStatus); } + inline void Send(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) + { RSessionBase::SendReceive(aFunction,aArgs,aStatus); } + }; + + + +// +// RTestSubSession +// + +class RTestSubSession : public RSubSessionBase + { +public: + inline TInt CreateSubSession(RSessionBase& aSession,TInt aFunction,const TIpcArgs& aArgs) + { return RSubSessionBase::CreateSubSession(aSession,aFunction,aArgs); } + inline TInt CreateSubSession(RSessionBase& aSession,TInt aFunction) + { return RSubSessionBase::CreateSubSession(aSession,aFunction); } + inline void CloseSubSession(TInt aFunction) + { RSubSessionBase::CloseSubSession(aFunction); } + inline TInt Send(TInt aFunction) + { return RSubSessionBase::SendReceive(aFunction); } + inline TInt Send(TInt aFunction,const TIpcArgs& aArgs) + { return RSubSessionBase::SendReceive(aFunction,aArgs); } + inline void Send(TInt aFunction,TRequestStatus& aStatus) + { RSubSessionBase::SendReceive(aFunction,aStatus); } + inline void Send(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) + { RSubSessionBase::SendReceive(aFunction,aArgs,aStatus); } + }; + + + +RTestSession Session; +TInt TestParam = 0; + +TInt TestThreadFunction(TAny* aParam) + { + return Session.Send((TInt)aParam,TIpcArgs(TestParam)); + } + +void DoTest(TInt aFunction,TExitType aExitType,TInt aExitReason,TInt aParam=0) + { + TBuf<256> title; + title.AppendFormat(_L("Function %d"),aFunction); + test.Next(title); + + RTestThread thread; + thread.Create(TestThreadFunction,(TAny*)aFunction); + TRequestStatus logon; + thread.Logon(logon); + TestParam = aParam; + + User::SetJustInTime(EFalse); + thread.Resume(); + User::WaitForRequest(logon); + User::SetJustInTime(ETrue); + + TExitType exitType=thread.ExitType(); + TInt exitReason=thread.ExitReason(); + test(exitType==aExitType); + test(exitReason==aExitReason); + CLOSE_AND_WAIT(thread); + } + +// +// Anonymous server +// + +class RTestAnonymousSession : public RTestSession + { +public: + inline TInt Connect(RServer2 aServer) + { + TInt r=CreateSession(aServer,TVersion()); + if(r) return r; + return ShareProtected(); + } + inline TInt Connect() + { + return CreateSession(_L(""),TVersion()); + } + }; + +CTestSecureServer* AnonymousServer; + +void DoStartAnonymousServer() + { + CTestActiveScheduler* activeScheduler = new (ELeave) CTestActiveScheduler; + CActiveScheduler::Install(activeScheduler); + CleanupStack::PushL(activeScheduler); + + CTestSecureServer* server = new (ELeave) CTestSecureServer(0); + CleanupStack::PushL(server); + + User::LeaveIfError(server->Start(KNullDesC)); + + AnonymousServer = server; + RThread::Rendezvous(KServerRendezvous); + + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(2); + } + +TInt StartAnonymousServer(TAny* /*aPtr*/) + { + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if(!cleanupStack) + return KErrNoMemory; + TRAPD(leaveError,DoStartAnonymousServer()) + delete cleanupStack; + return leaveError; + } + +void TestConnectByHandle() + { + RTestAnonymousSession session; + TRequestStatus logon; + TInt r; + + test.Start(_L("Starting a local server")); + RTestThread thread; + thread.Create(StartAnonymousServer); + TRequestStatus rendezvous; + TRequestStatus svrstat; + thread.Rendezvous(rendezvous); + thread.Logon(logon); + thread.NotifyDestruction(svrstat); + thread.Resume(); + User::WaitForRequest(rendezvous); + test(rendezvous.Int()==KServerRendezvous); + thread.Close(); + + test.Next(_L("Check connect with null name fails")); + test((r=session.Connect())!=KErrNone); + + test.Next(_L("Connecting to local server")); + test((r=session.Connect(AnonymousServer->Server()))==KErrNone); + + test.Next(_L("Test the connection")); + test((r=session.Send(EPing,TIpcArgs(1234)))==1234); + test((r=session.Send(EPing,TIpcArgs(2345)))==2345); + + test.Next(_L("Shutting server down")); + test(logon.Int()==KRequestPending); + test((r=session.Send(ETestShutdown))==KErrServerTerminated); + test(r==KErrServerTerminated); + session.Close(); + User::WaitForRequest(logon); + test(logon.Int()==KErrNone); + User::WaitForRequest(svrstat); + + test.End(); + } + +TRequestStatus SvrStat; + +void RestartTestServer() + { + RTestProcess server; + TRequestStatus rendezvous; + server.Create(0,ETestProcessServer); + server.NotifyDestruction(SvrStat); + server.Rendezvous(rendezvous); + server.Resume(); + User::WaitForRequest(rendezvous); + test(rendezvous==KServerRendezvous); + server.Close(); + test(Session.Connect()==KErrNone); + } + +void TestIpc() + { + TBuf8<10> buf8((TUint8*)"abcdefghij"); + TBuf16<10> buf16((TUint16*)L"abcdefghij"); + TInt r; + + test.Start(_L("Testing TIpcArgs::Set")); + { + TIpcArgs a(TIpcArgs::ENothing,123,(TAny*)&buf8); + TIpcArgs b; + b.Set(0,TIpcArgs::ENothing); + b.Set(1,123); + b.Set(2,(TAny*)&buf8); + test(a.iFlags==b.iFlags); + // iArgs[0] is uninitialised so don't test + test(a.iArgs[1]==b.iArgs[1]); + test(a.iArgs[2]==b.iArgs[2]); + } + { + TIpcArgs a((TDesC8*)&buf8,(TDesC16*)&buf16,&buf8,&buf16); + TIpcArgs b; + b.Set(0,(TDesC8*)&buf8); + b.Set(1,(TDesC16*)&buf16); + b.Set(2,&buf8); + b.Set(3,&buf16); + test(a.iFlags==b.iFlags); + test(a.iArgs[0]==b.iArgs[0]); + test(a.iArgs[1]==b.iArgs[1]); + test(a.iArgs[2]==b.iArgs[2]); + test(a.iArgs[3]==b.iArgs[3]); + } + + test.Next(_L("Test Unspecified argument")); + r = Session.Send(ETestArgUnspecified,TIpcArgs((TAny*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgUnspecified+(1<<28),TIpcArgs(0,(TAny*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgUnspecified+(2<<28),TIpcArgs(0,0,(TAny*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgUnspecified+(3<<28),TIpcArgs(0,0,0,(TAny*)&buf8)); + test(r==KErrNone); + + test.Next(_L("Test DesC8 argument")); + r = Session.Send(ETestArgDesC8,TIpcArgs((TDesC8*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC8+(1<<28),TIpcArgs(0,(TDesC8*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC8+(2<<28),TIpcArgs(0,0,(TDesC8*)&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC8+(3<<28),TIpcArgs(0,0,0,(TDesC8*)&buf8)); + test(r==KErrNone); + + test.Next(_L("Test DesC16 argument")); + r = Session.Send(ETestArgDesC16,TIpcArgs((TDesC16*)&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC16+(1<<28),TIpcArgs(0,(TDesC16*)&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC16+(2<<28),TIpcArgs(0,0,(TDesC16*)&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDesC16+(3<<28),TIpcArgs(0,0,0,(TDesC16*)&buf16)); + test(r==KErrNone); + + test.Next(_L("Test Des8 argument")); + r = Session.Send(ETestArgDes8,TIpcArgs(&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDes8+(1<<28),TIpcArgs(0,&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDes8+(2<<28),TIpcArgs(0,0,&buf8)); + test(r==KErrNone); + r = Session.Send(ETestArgDes8+(3<<28),TIpcArgs(0,0,0,&buf8)); + test(r==KErrNone); + + test.Next(_L("Test Des16 argument")); + r = Session.Send(ETestArgDes16,TIpcArgs(&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDes16+(1<<28),TIpcArgs(0,&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDes16+(2<<28),TIpcArgs(0,0,&buf16)); + test(r==KErrNone); + r = Session.Send(ETestArgDes16+(3<<28),TIpcArgs(0,0,0,&buf16)); + test(r==KErrNone); + + + test.Next(_L("Test Bad Client Descriptor")); + //The test should ensure that both server and kernel are safe if client passes faulty descriptor to the server. + { + //Create a chunk with a hole between addresses 0x1000 & 0x2000 + RChunk c; + r=c.CreateDisconnectedLocal(0,0,0x200000); + test(r==KErrNone); + r=c.Commit(0,0x1000); + test(r==KErrNone); + r=c.Commit(0x2000,0x1000); + test(r==KErrNone); + + //Each of these steps will pass bad descriptor to the server for IPC transfer in both directions. + //KErrBadDescriptor should be returned. + { + TPtr8 ptr (c.Base()+0x1000,0x100,0x100); + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + } + { + TPtr8 ptr (c.Base()+0x1003,0x100,0x100); + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + } + { + TPtr8 ptr (c.Base()+0xe00,0x500,0x500); + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + } + { + TPtr8 ptr (c.Base()+0xdff,0x500,0x500); + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + } + { + TPtr8 ptr (c.Base()+0x1ff1,0x500,0x500); + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + test(KErrBadDescriptor == r); + } + + //The next step will send random descriptors for IPC transfer. Server should return either KErrNone or + //KErrBadDescriptor + { + TUint seed[2]; + seed[0]=User::TickCount(); + seed[1]=0; + test.Printf(_L("The initial seed for the random function is: S0=%xh S1=%xh\n"), seed[0], seed[1]); + + TInt i; + TPtr8 ptr (0,0,0); + TInt noErrors = 0; + TInt badDescriptors = 0; + + for (i=0;i<100;i++) + { + TInt descAddress = (TInt) (c.Base() + (Random(seed) % 0x1000)); + TInt descSize=Random(seed)%0x1000; + + TUint* descData = (TUint*)&ptr; + descData[0] = 0x20000000 + descSize; + descData[1] = descSize; + descData[2] = descAddress; + + r = Session.Send(ETestBadClientDescRead,TIpcArgs(&ptr)); + switch (r) + { + case KErrNone: noErrors++;break; + case KErrBadDescriptor: badDescriptors++;break; + default: test.Printf(_L("Error: %d returned"),r); + } + + r = Session.Send(ETestBadClientDescWrite,TIpcArgs(&ptr)); + switch (r) + { + case KErrNone: noErrors++;break; + case KErrBadDescriptor: badDescriptors++;break; + default: test.Printf(_L("Error: %d returned"),r); + } + } + test.Printf(_L("KErrNoError: %d KErrBadDescriptor: %d"),noErrors, badDescriptors); + } + + test.Next(_L("Test Bad Server Descriptor")); + //The test should ensure that kernel is safe if server passes faulty descriptor for IPC transfer + { + TPtr8 ptr (c.Base(),0x1000,0x1000); + TInt i; + for (i=0;i<=7;i++) + { + r = Session.Send(ETestBadServerDescRead | (i<<28),TIpcArgs(&ptr)); + test(r==KErrServerTerminated); + RestartTestServer(); + r = Session.Send(ETestBadServerDescWrite | (i<<28),TIpcArgs(&ptr)); + test(r==KErrServerTerminated); + User::WaitForRequest(SvrStat); + RestartTestServer(); + } + } + + c.Close(); + } + test.End(); + } + + + +void TestSubSessions() + { + const TInt KSubSessionHandle = 0x87654321; + RTestSubSession sub; + TInt r; + + test.Start(_L("Creating a subsession with no arguments")); + r = sub.CreateSubSession(Session,ETestCreateSubSession); + test(r==KErrNone); + test(((TInt*)&sub)[0] == (*(TInt*)&Session | CObjectIx::ENoClose)); // check sub.iSession + + test.Next(_L("Creating a subsession with arguments")); + r = sub.CreateSubSession(Session,ETestCreateSubSession,TIpcArgs(KSubSessionHandle)); + test(r==KErrNone); + test(((TInt*)&sub)[0] == (*(TInt*)&Session | CObjectIx::ENoClose)); // check sub.iSession + + test(((TInt*)&sub)[1]==KSubSessionHandle); // check sub.iSubSessionHandle + + test.Next(_L("Sending message with arguments")); + TInt reply[4] = {0}; + TPtr8 replyDes((TUint8*)&reply,sizeof(reply)); + r = sub.Send(ETestEchoArgs,TIpcArgs(&replyDes,123,456,789)); + test(r==KErrNone); + test(reply[0]==(TInt)&replyDes); + test(reply[1]==123); + test(reply[2]==456); + test(reply[3]==KSubSessionHandle); + + test.Next(_L("Sending empty message")); + r = sub.Send(ETestEmptySubSessionMessage); + test(r==KSubSessionHandle); + + test.Next(_L("Closing subsession")); + sub.CloseSubSession(ETestCloseSubSession); + test(((TInt*)&sub)[0]==0); // check sub.iSession + test(((TInt*)&sub)[1]==0); // check sub.iSubSessionHandle + r = Session.Send(ETestCloseSubSessionHandle); + test(r==KSubSessionHandle); + + test.End(); + } + + +void TestProtectedServers() + { + RTestProcess process; + TRequestStatus logonStatus; + + test.Start(_L("Trying to create a protected server without KCapabilityProtServ")); + process.Create(~(1u< + +TInt TestThreadAsyncConnect(TAny*) + { + RTestSession session; + TRequestStatus status; + TInt r=session.Connect(TVersion(1,1,1),&status); + if(r!=KErrNone) + return r; + if(status!=KRequestPending) // server can't have created session yet because we have higher priority + return status.Int(); + User::WaitForRequest(status); + if(status!=KErrNotSupported) + return status.Int(); + return session.Send(EPing,TIpcArgs(1234)); // Should panic us + } + +void TestAsynchronousConnect() + { + RTestSession session; + TRequestStatus status; + TInt r; + + test.Start(_L("Test successful asynchronous connect")); + r=session.Connect(TVersion(0,0,0),&status); + test(r==KErrNone); + test(status==KRequestPending); // server can't have created session yet because we have higher priority + User::WaitForRequest(status); + test(status==KErrNone); + test((r=session.Send(EPing,TIpcArgs(1234)))==1234); + session.Close(); + + test.Next(_L("Test unsuccessful asynchronous connect")); + r=session.Connect(TVersion(1,1,1),&status); + test(r==KErrNone); + test(status==KRequestPending); // server can't have created session yet because we have higher priority + User::WaitForRequest(status); + test(status==KErrNotSupported); + session.Close(); + + test.Next(_L("Test using unsuccessful asynchronous connect")); + RTestThread thread; + thread.Create(TestThreadAsyncConnect,0); + TRequestStatus logon; + thread.Logon(logon); + User::SetJustInTime(EFalse); + thread.Resume(); + User::WaitForRequest(logon); + User::SetJustInTime(ETrue); + TExitType exitType=thread.ExitType(); + TInt exitReason=thread.ExitReason(); + test(exitType==EExitPanic); + test(exitReason==CServer2::ESessionNotConnected); + thread.Close(); + + test.End(); + } + + + +TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2) + { + (void)aArg1; + (void)aArg2; + switch(aTestNum) + { + + case ETestProcessServer: + RProcess().SetPriority(EPriorityLow); + return StartServer(); + + case ETestProcessCreateProtectedServer: + { + test.Title(); + RServer2 server; + TInt r = server.CreateGlobal(KProtectedServerName); + server.Close(); + return r; + } + + default: + User::Panic(_L("T_SSERVER"),1); + } + + return KErrNone; + } + + + +GLDEF_C TInt E32Main() + { + TBuf16<512> 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); + } + + TInt r; + + test.Title(); + + test.Start(_L("Testing Server Connect by Handle")); + TestConnectByHandle(); + + test.Next(_L("Starting test server")); + RTestProcess server; + TRequestStatus rendezvous; + server.Create(0,ETestProcessServer); + server.Rendezvous(rendezvous); + server.Resume(); + User::WaitForRequest(rendezvous); + test(rendezvous==KServerRendezvous); + server.Close(); + + test.Next(_L("Conecting to test server")); + test((r=Session.Connect())==KErrNone); + + test.Next(_L("Test asynchronous server connect")); + TestAsynchronousConnect(); + + test.Next(_L("Test protected servers")); + TestProtectedServers(); + + test.Next(_L("Test connecting to identified servers")); + TestIdentifiedServers(); + + test.Next(_L("Testing SubSessions")); + TestSubSessions(); + + test.Next(_L("Testing IPC argument checking")); + TestIpc(); + + test.Next(_L("Testing CServer2::RunError and CSession2::ServiceError()")); + const TInt KTestServiceLeaveValue = 555; + r = Session.Send(ETestServiceLeave,TIpcArgs(KTestServiceLeaveValue)); + test(r==KTestServiceLeaveValue+KTestRunErrorModifier+KTestServiceErrorModifier); + + test.Next(_L("Testing session resource counting")); + test.Start(_L("")); + DoTest(ETestResourceCountPass,EExitKill,ETestResourceCountPass); + DoTest(ETestResourceCountFail,EExitPanic,CSession2::ESesFoundResCountHeaven); + test.End(); + + test.Next(_L("Shutting server down")); + { + Session.Send(ETestShutdown,TIpcArgs()); + Session.Close(); + } + User::WaitForRequest(SvrStat); + + test.End(); + return(0); + } +