1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/featuremgmt/featuremgr/test/rtest/src/t_fmgrbadclient.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,452 @@
1.4 +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32test.h>
1.20 +#include <e32math.h>
1.21 +#include <featmgr.h>
1.22 +#include <featureuids.h>
1.23 +#include "featurepanics.h"
1.24 +#include <featurecontrol.h>
1.25 +#include <featurenotifier.h>
1.26 +#include "../src/inc/featmgrconfiguration.h"
1.27 +#include "../src/inc/featmgrclientserver.h"
1.28 +
1.29 +using namespace NFeature;
1.30 +
1.31 +static RTest TheTest(_L("t_fmgrbadclient"));
1.32 +
1.33 +const TInt KTestIterCount = 5000;
1.34 +
1.35 +enum TArgType
1.36 + {
1.37 + EIntArgType,
1.38 + ETextArgType,
1.39 + EBinArgType,
1.40 + ELastArgType
1.41 + };
1.42 +
1.43 +const TInt KMaxDesArgLen = 1000;
1.44 +
1.45 +//If the FeatMgr server crashes and the test receives KErrServerTerminated error, then the
1.46 +//next set will contain the last:
1.47 +// - iteration number;
1.48 +// - handle type;
1.49 +// - function code;
1.50 +// - handle;
1.51 +// - IPC arguments values;
1.52 +struct TThreadData
1.53 + {
1.54 + TInt iIteration;
1.55 + TInt iFunction;
1.56 + TArgType iArgType[KMaxMessageArguments];
1.57 + TInt iIntArg[KMaxMessageArguments];
1.58 + TBuf<KMaxDesArgLen> iTextArg[KMaxMessageArguments];
1.59 + TBuf8<KMaxDesArgLen> iBinArg[KMaxMessageArguments];
1.60 + TInt64 iSeed;
1.61 + };
1.62 +
1.63 +_LIT(KPanicCategory, "SrvTerm");
1.64 +_LIT(KPanicCategory2, "InvArg");
1.65 +const TInt KPanicCode = 1111;
1.66 +const TInt KPanicCode2 = 2222;
1.67 +
1.68 +///////////////////////////////////////////////////////////////////////////////////////
1.69 +
1.70 +//Deletes all created test files.
1.71 +void DestroyTestEnv()
1.72 + {
1.73 + }
1.74 +
1.75 +///////////////////////////////////////////////////////////////////////////////////////
1.76 +///////////////////////////////////////////////////////////////////////////////////////
1.77 +//Test macros and functions
1.78 +void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse)
1.79 + {
1.80 + if(!aValue)
1.81 + {
1.82 + DestroyTestEnv();
1.83 + if(aPrintThreadName)
1.84 + {
1.85 + RThread th;
1.86 + TName name = th.Name();
1.87 + RDebug::Print(_L("*** Expression evaluated to false. Thread %S, Line %d\r\n"), &name, aLine);
1.88 + }
1.89 + else
1.90 + {
1.91 + TheTest.Printf(_L("*** Expression evaluated to false. Line %d\r\n"), aLine);
1.92 + }
1.93 + TheTest(EFalse, aLine);
1.94 + }
1.95 + }
1.96 +void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse)
1.97 + {
1.98 + if(aValue != aExpected)
1.99 + {
1.100 + DestroyTestEnv();
1.101 + if(aPrintThreadName)
1.102 + {
1.103 + RThread th;
1.104 + TName name = th.Name();
1.105 + RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue);
1.106 + }
1.107 + else
1.108 + {
1.109 + RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
1.110 + }
1.111 + TheTest(EFalse, aLine);
1.112 + }
1.113 + }
1.114 +#define TEST(arg) ::Check1((arg), __LINE__)
1.115 +#define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
1.116 +#define TTEST(arg) ::Check1((arg), __LINE__, ETrue)
1.117 +#define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue)
1.118 +
1.119 +//////////////////////////////////////////////////////////////////////////////////////////////////
1.120 +
1.121 +static TInt StartFeatMgrServer()
1.122 + {
1.123 + RProcess server;
1.124 + const TUidType serverUid( KNullUid, KServerUid2, KNullUid );
1.125 + TInt err = server.Create( KServerExeName, // FeatMgrServer.exe
1.126 + KNullDesC, // A descriptor containing data passed as
1.127 + // an argument to the thread function of
1.128 + // the new process's main thread, when it
1.129 + // is first scheduled.
1.130 + serverUid, // FeatMgr server UID
1.131 + EOwnerProcess ); // Ownership of this process handle
1.132 +
1.133 + // Return error code if we couldn't create a process
1.134 + if ( err == KErrNone )
1.135 + {
1.136 + // Rendezvous is used to detect server start
1.137 + TRequestStatus stat;
1.138 + server.Rendezvous( stat );
1.139 +
1.140 + if ( stat != KRequestPending )
1.141 + {
1.142 + server.Kill( KErrNone ); // Abort startup
1.143 + }
1.144 + else
1.145 + {
1.146 + server.Resume(); // Logon OK - start the server
1.147 + }
1.148 +
1.149 + User::WaitForRequest( stat ); // Wait for start or death
1.150 +
1.151 + // We can't use the 'exit reason' if the server paniced as this
1.152 + // is the panic 'reason' and may be '0' which cannot be distinguished
1.153 + // from KErrNone
1.154 + err = (server.ExitType() == EExitPanic)? KErrGeneral : stat.Int();
1.155 +
1.156 + // We can close the handle now
1.157 + server.Close();
1.158 + }
1.159 +
1.160 + return err;
1.161 + }
1.162 +
1.163 +//////////////////////////////////////////////////////////////////////////////////////////////////
1.164 +///////////////////////////// RTestFeatMgrSession ////////////////////////////////
1.165 +//////////////////////////////////////////////////////////////////////////////////////////////////
1.166 +
1.167 +class RTestFeatMgrSession : public RSessionBase
1.168 + {
1.169 +public:
1.170 + TInt Connect();
1.171 + void Close();
1.172 + TInt SendReceive(TInt aFunction);
1.173 + TInt SendReceive(TInt aFunction, const TIpcArgs& aArgs);
1.174 + void SendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus);
1.175 +
1.176 +private:
1.177 + TInt DoCreateSession();
1.178 + };
1.179 +
1.180 +TInt RTestFeatMgrSession::Connect()
1.181 + {
1.182 + TInt err = DoCreateSession();
1.183 + if(err != KErrNone && err != KErrAlreadyExists)
1.184 + {
1.185 + Close();
1.186 + }
1.187 + return err;
1.188 + }
1.189 +
1.190 +void RTestFeatMgrSession::Close()
1.191 + {
1.192 + RSessionBase::Close();
1.193 + }
1.194 +
1.195 +TInt RTestFeatMgrSession::SendReceive(TInt aFunction)
1.196 + {
1.197 + return RSessionBase::SendReceive(aFunction);
1.198 + }
1.199 +
1.200 +TInt RTestFeatMgrSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs)
1.201 + {
1.202 + return RSessionBase::SendReceive(aFunction, aArgs);
1.203 + }
1.204 +
1.205 +void RTestFeatMgrSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus)
1.206 + {
1.207 + RSessionBase::SendReceive(aFunction, aArgs, aStatus);
1.208 + }
1.209 +
1.210 +TInt RTestFeatMgrSession::DoCreateSession()
1.211 + {
1.212 + const TInt KRetry( 2 );
1.213 + // Try this twice
1.214 + TInt retry( KRetry );
1.215 + TInt err( KErrNone );
1.216 +
1.217 + while ( retry > 0 )
1.218 + {
1.219 + // Try to create a FeatMgr Server session
1.220 + err = CreateSession(KServerProcessName,
1.221 + TVersion(KServerVersionMajor, KServerVersionMinor, KServerVersionBuild),
1.222 + KDefaultAsyncSlots);
1.223 +
1.224 + if ( err != KErrNotFound && err != KErrServerTerminated )
1.225 + {
1.226 + // KErrNone or unrecoverable error
1.227 + retry = 0;
1.228 + }
1.229 + else
1.230 + {
1.231 + // Return code was KErrNotFound or KErrServerTerminated.
1.232 + // Try to start a new FeatMgr Server
1.233 + err = StartFeatMgrServer();
1.234 +
1.235 + if ( err != KErrNone && err != KErrAlreadyExists )
1.236 + {
1.237 + // Unrecoverable error
1.238 + retry = 0;
1.239 + }
1.240 + }
1.241 +
1.242 + retry--;
1.243 + }
1.244 +
1.245 + return err;
1.246 + }
1.247 +
1.248 +void PrintIterationCount(TInt aIteration, TBool aFromThread = EFalse)
1.249 + {
1.250 + if((aIteration % 100) == 0)
1.251 + {
1.252 + TTime time;
1.253 + time.HomeTime();
1.254 + TDateTime dt = time.DateTime();
1.255 + TBuf<16> tbuf;
1.256 + tbuf.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond());
1.257 + if(aFromThread)
1.258 + {
1.259 + RDebug::Print(_L("-----[%S] Test iterations: %d\r\n"), &tbuf, aIteration);
1.260 + }
1.261 + else
1.262 + {
1.263 + TheTest.Printf(_L("-----[%S] Test iterations: %d\r\n"), &tbuf, aIteration);
1.264 + }
1.265 + }
1.266 + }
1.267 +
1.268 +//Worker thread function.
1.269 +//It behaves as a malicious client. Connects to the FeatMgr server. In each test iteration generates some random values
1.270 +//for the function number, handle, IPC arguments. Then sends a command to the server using these
1.271 +//randomly generated values. If the server crashes and the thread function receives KErrServerTerminated error,
1.272 +//then the thread kills itself and the main thread will get KPanicCategory and KPanicCode as a reason for the
1.273 +//worker thread's death. The last set of randomly generated values will be stored in the memory, pointed by aData argument.
1.274 +TInt ThreadFunc1(void* aData)
1.275 + {
1.276 + __UHEAP_MARK;
1.277 +
1.278 + CTrapCleanup* tc = CTrapCleanup::New();
1.279 + TTEST(tc != NULL);
1.280 +
1.281 + TThreadData* p = static_cast <TThreadData*> (aData);
1.282 + TTEST(p != NULL);
1.283 + TThreadData& data = *p;
1.284 +
1.285 + RTestFeatMgrSession sess;
1.286 + TInt err = sess.Connect();
1.287 + TTEST2(err, KErrNone);
1.288 +
1.289 + while(++data.iIteration <= KTestIterCount)
1.290 + {
1.291 + PrintIterationCount(data.iIteration, ETrue);
1.292 + TIpcArgs args;
1.293 + data.iFunction = Math::Rand(data.iSeed) % (EFeatMgrSWIEnd + 1);//EFeatMgrSWIEnd - the last server message number (without resource checking IPCs))
1.294 + for(TInt i=0;i<KMaxMessageArguments;++i)
1.295 + {
1.296 + //Initialize arguments
1.297 + data.iArgType[i] = static_cast <TArgType> (Math::Rand(data.iSeed) % ELastArgType);
1.298 + switch(data.iArgType[i])
1.299 + {
1.300 + case EIntArgType:
1.301 + data.iIntArg[i] = Math::Rand(data.iSeed) % 9711;
1.302 + args.Set(i, data.iIntArg[i]);
1.303 + break;
1.304 + case ETextArgType:
1.305 + {
1.306 + TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;
1.307 + data.iTextArg[i].SetLength(len);
1.308 + args.Set(i, &data.iTextArg[i]);
1.309 + }
1.310 + break;
1.311 + case EBinArgType:
1.312 + {
1.313 + TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;
1.314 + data.iBinArg[i].SetLength(len);
1.315 + args.Set(i, &data.iBinArg[i]);
1.316 + }
1.317 + break;
1.318 + default:
1.319 + User::Panic(KPanicCategory2, KPanicCode2);
1.320 + break;
1.321 + }
1.322 + }
1.323 + //Send arguments
1.324 + User::SetJustInTime(EFalse);
1.325 + TInt err = KErrNone;
1.326 + if(data.iFunction == EFeatMgrReqNotify)
1.327 + {
1.328 + TRequestStatus status;
1.329 + sess.SendReceive(data.iFunction, args, status);
1.330 + if(status == KRequestPending)
1.331 + {
1.332 + err = sess.SendReceive(EFeatMgrReqNotifyCancelAll);
1.333 + }
1.334 + else
1.335 + {
1.336 + err = status.Int();
1.337 + }
1.338 + }
1.339 + else
1.340 + {
1.341 + err = sess.SendReceive(data.iFunction, args);
1.342 + }
1.343 + if(err == KErrServerTerminated)
1.344 + {
1.345 + User::Panic(KPanicCategory, KPanicCode);
1.346 + }
1.347 + User::SetJustInTime(ETrue);
1.348 + }
1.349 +
1.350 + sess.Close();
1.351 +
1.352 + delete tc;
1.353 +
1.354 + __UHEAP_MARKEND;
1.355 +
1.356 + return KErrNone;
1.357 + }
1.358 +
1.359 +////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.360 +
1.361 +/**
1.362 +@SYMTestCaseID PDS-EFM-CT-4065
1.363 +@SYMTestCaseDesc
1.364 +@SYMTestPriority High
1.365 +@SYMTestActions
1.366 +@SYMTestExpectedResults Test must not fail
1.367 +@SYMDEF DEF144262
1.368 +*/
1.369 +void BadClientTest()
1.370 + {
1.371 + TThreadData* p = new TThreadData;
1.372 + TEST(p != NULL);
1.373 + TThreadData& data = *p;
1.374 + data.iFunction = 0;
1.375 + TTime now;
1.376 + now.UniversalTime();
1.377 + data.iSeed = now.Int64();
1.378 +
1.379 + _LIT(KThreadName, "WorkThrd");
1.380 +
1.381 + for(data.iIteration=0;data.iIteration<KTestIterCount;++data.iIteration)
1.382 + {
1.383 + PrintIterationCount(data.iIteration);
1.384 + //Run the malicious client (one worker theread which will try to crash the FeatMgr server)
1.385 + RThread thread;
1.386 + TEST2(thread.Create(KThreadName, &ThreadFunc1, 0x2000, 0x1000, 0x10000, &data, EOwnerProcess), KErrNone);
1.387 + TRequestStatus status;
1.388 + thread.Logon(status);
1.389 + TEST2(status.Int(), KRequestPending);
1.390 + thread.Resume();
1.391 + User::WaitForRequest(status);
1.392 + User::SetJustInTime(ETrue); // enable debugger panic handling
1.393 + if(thread.ExitType() == EExitPanic)
1.394 + {
1.395 + if(thread.ExitReason() == KPanicCode)
1.396 + {
1.397 + TheTest.Printf(_L("##Server terminated!\r\n"));
1.398 + TheTest.Printf(_L("##Iteration=%d, Function(hex)=%X, Handle=%d\r\n"), data.iIteration, data.iFunction);
1.399 + for(TInt i=0;i<KMaxMessageArguments;++i)
1.400 + {
1.401 + switch(data.iArgType[i])
1.402 + {
1.403 + case EIntArgType:
1.404 + TheTest.Printf(_L("##Arg %d, Integer, value=%d\r\n"), i, data.iIntArg[i]);
1.405 + break;
1.406 + case ETextArgType:
1.407 + TheTest.Printf(_L("##Arg %d, Text, length=%d\r\n"), i, data.iTextArg[i].Length());
1.408 + break;
1.409 + case EBinArgType:
1.410 + TheTest.Printf(_L("##Arg %d, Binary, length=%d\r\n"), i, data.iBinArg[i].Length());
1.411 + break;
1.412 + default:
1.413 + TheTest.Printf(_L("##Arg %d, Invalid argument type: %d\r\n"), i, data.iArgType[i]);
1.414 + break;
1.415 + }
1.416 + }
1.417 + TEST(0);
1.418 + }
1.419 + }
1.420 + thread.Close();
1.421 + }
1.422 + User::SetJustInTime(ETrue); // enable debugger panic handling
1.423 + delete p;
1.424 + }
1.425 +
1.426 +void DoTestsL()
1.427 + {
1.428 + //This test won't pass
1.429 + TheTest.Start(_L("@SYMTestCaseID:PDS-EFM-CT-4065 Bad client test"));
1.430 + BadClientTest();
1.431 + }
1.432 +
1.433 +TInt E32Main()
1.434 + {
1.435 + TheTest.Title();
1.436 +
1.437 + CTrapCleanup* tc = CTrapCleanup::New();
1.438 + TheTest(tc != NULL);
1.439 +
1.440 + __UHEAP_MARK;
1.441 +
1.442 + TRAPD(err, DoTestsL());
1.443 + DestroyTestEnv();
1.444 + TEST2(err, KErrNone);
1.445 +
1.446 + __UHEAP_MARKEND;
1.447 +
1.448 + TheTest.End();
1.449 + TheTest.Close();
1.450 +
1.451 + delete tc;
1.452 +
1.453 + User::Heap().Check();
1.454 + return KErrNone;
1.455 + }