diff -r 000000000000 -r bde4ae8d615e os/ossrv/lowlevellibsandfws/pluginfw/Framework/SimpleTests/t_rogueplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/lowlevellibsandfws/pluginfw/Framework/SimpleTests/t_rogueplugin.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,236 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// + +#include +#include +#include "Interface.h" // ECOM CExampleInterface class +#include "exampleNine.h" // CRoguePlugin class + + +//Test utils for copying plugin to C +#include "EcomTestUtils.h" + +_LIT(KTestTitle, "DEF094656 Rogue plugin should not override build-in"); + +LOCAL_D RTest TheTest(_L("Rogue plugin with duplicated Impl. UID")); + +LOCAL_D TBool correctTypeCastPassed = EFalse; + +_LIT(KRoguePluginDllOnZ, "Z:\\RAMOnly\\exampleNine.dll"); +_LIT(KRoguePluginDllOnC, "C:\\sys\\bin\\exampleNine.dll"); +_LIT(KRoguePluginRscOnZ, "Z:\\RAMOnly\\exampleNine.rsc"); +_LIT(KRoguePluginRscOnC, "C:\\resource\\plugins\\exampleNine.rsc"); + +/** Copy the rogue plugin to C: drive +*/ +LOCAL_C void CopyPluginsL() + { + // Copy the dlls and .rsc files on to RAM + EComTestUtils::FileManCopyFileL(KRoguePluginDllOnZ, KRoguePluginDllOnC); + EComTestUtils::FileManCopyFileL(KRoguePluginRscOnZ, KRoguePluginRscOnC); + // Pause in case ECOM server is already up and running and needs + // time to activate the scanning timer active object. + User::After(3000000); + } + +/** Remove resource file and dll copied to C: drive +*/ +LOCAL_C void DeleteTestPlugin() + { + TRAPD(ignoreErr, EComTestUtils::FileManDeleteFileL(KRoguePluginRscOnC)); + TRAP(ignoreErr, EComTestUtils::RLoaderDeleteFileL(KRoguePluginDllOnC)); + } + +/** +Test rogue plugin trying to override a ROM based plugin by +duplicating the legitimate DLL's implementation UID (different +interface UID so that ECOM not treat it as an update). + +@SYMTestCaseID SYSLIB-ECOM-CIT-3161 +@SYMTestCaseDesc Copy a rogue plugin to C drive. This plugin duplicates the + implementation UID of a built-in dll. Test if the rogue + plugin will over shadow the built-in dll. +@SYMTestPriority High +@SYMTestActions 1. copy the rsc and dll of the rogue plugin to C: + 2. Use the CreateImplementation API which does not specify + the i/f UID to instantiate the built-in implementation. + Test the instance works normally. + 3. Repeat 2 but instantiate the pointer as the rogue plugin + class. Pass NULL as the initialising param in the call + to CreateImplementationL. Because the actual plugin returned by + ECOM needs this initParam, KERN-EXEC 3 panic occurs. +@SYMTestExpectedResults The test must not fail. +@SYMDEF DEF094656 +*/ +LOCAL_C void DEF094656_TestCaseL() + { + // DuplicateImplUidTestL SYSLIB-ECOM-CT-3157 is similar to this testcase. + // CT-3157 tests higher driver letter > lower driver letter, + // and lower i/f UID > higher i/f UID. + + // Note that this function is expected to panic. Hence not bother + // with __UHEAP_MARK. + + //Check if the rogue plugin is in the registry. + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CIT-3161 ")); + RImplInfoPtrArray ifArray; + REComSession::ListImplementationsL(KRogueInterfaceUid, ifArray); + + TInt count = ifArray.Count(); + TheTest.Printf(_L("Found %d implementations of I/f 0x%X"), count, KRogueInterfaceUid.iUid); + + TheTest(count == 1); + TheTest(KRogueImplUid == ifArray[0]->ImplementationUid()); + + ifArray.ResetAndDestroy(); + + TUid dtor_key; + // Initialisation parameter needed by CImplementationClassOne + CExampleInterface::TExampleInterfaceInitParams initParams; + initParams.integer = 0; + initParams.descriptor = NULL; + + // First test creating the correct class. + CExampleInterface* correctDll = reinterpret_cast( + REComSession::CreateImplementationL(KRogueImplUid, + dtor_key, + &initParams) ); + TheTest(correctDll != NULL); + + TUid testUid = correctDll->ImplId(); + // the example plugins should return the value 10009DC3. + TheTest(testUid == KRogueImplUid); + + REComSession::DestroyedImplementation(dtor_key); + delete correctDll; + + // Indicate to thread creator that first stage test passed. + correctTypeCastPassed = ETrue; + + // This create should crash because the plugin returned by + // ECOM is really CImplementationClassOne which needs a properly + // constructed initParam. + CRoguePlugin* wrongDll = reinterpret_cast( + REComSession::CreateImplementationL(KRogueImplUid, + dtor_key, + NULL) ); + + // If gets here then someone has changed CImplementationClassOne::NewL + // or 10009DC3 has been updated by another implementation. + if (wrongDll) + { + REComSession::DestroyedImplementation(dtor_key); + delete wrongDll; + } + + REComSession::FinalClose(); + + TheTest(EFalse); + } + +LOCAL_C void ThreadMainL() + { + CConsoleBase* newConsole = Console::NewL(KTestTitle, + TSize(KConsFullScreen, KConsFullScreen)); + + // Thread creator needs to save the original console because this + // thread is expected to crash, hence cannot cleanup. + TheTest.SetConsole(newConsole); + DEF094656_TestCaseL(); + TheTest.SetConsole(NULL); + + delete newConsole; + } + +LOCAL_C TInt ThreadFunc(TAny*) + { + __UHEAP_MARK; + CTrapCleanup* threadcleanup = CTrapCleanup::New(); + TRAPD(err, ThreadMainL()); + delete threadcleanup; + __UHEAP_MARKEND; + return err; + } + +LOCAL_C void RunTestThreadL() + { + __UHEAP_MARK; + + CopyPluginsL(); + + _LIT(KThreadName, "RoguePluginTest"); + + TBool jit = User::JustInTime(); + User::SetJustInTime(EFalse); + + TheTest.Start(KTestTitle); + + // Save the console because the created thread must use its own + // console. + CConsoleBase* savedConsole = TheTest.Console(); + + RThread tt; + TInt err = tt.Create(KThreadName, &ThreadFunc, KDefaultStackSize, + KMinHeapSize, 0x100000, 0); + User::LeaveIfError(err); + + TRequestStatus status; + tt.Logon(status); + tt.Resume(); + + User::WaitForRequest(status); + + // restore console + TheTest.SetConsole(savedConsole); + + TExitCategoryName exitcategory = tt.ExitCategory(); + TExitType exittype = tt.ExitType(); + TInt exitReason = tt.ExitReason(); + tt.Close(); + + TheTest.Printf(_L("Thread exit type %d, reason %d, category %S"), exittype, exitReason, &exitcategory); + + User::SetJustInTime(jit); + DeleteTestPlugin(); + + // Check if tt thread passes this checkpoint + TheTest(correctTypeCastPassed); + + // Check if tt thread die of KERN-EXEC. + _LIT(KKernExec, "KERN-EXEC"); + TheTest(exitcategory.CompareF(KKernExec) == 0); + + TheTest.End(); + TheTest.Close(); + + __UHEAP_MARKEND; + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + + CTrapCleanup* cleanup = CTrapCleanup::New(); + CActiveScheduler* scheduler = new(ELeave)CActiveScheduler; + CActiveScheduler::Install(scheduler); + + TRAP_IGNORE( RunTestThreadL() ); + + delete scheduler; + delete cleanup; + + __UHEAP_MARKEND; + return KErrNone; + }