Issott_Common Design Patterns for Symbian OS-The Foundations of Smartphone Software_0470516356 (779879), страница 53
Текст из файла (страница 53)
This can be done in the same way thatQuarantine (see page 260) uses resource files to identify plug-ins.2.A standard ECom resource file that tells a cradle process how to loada plug-in using ECom.The reason that two resources are needed is that if the frameworkprocess were to call REComSession::ListImplementationsL()to discover what plug-ins are available on the device then the listreturned would be limited to just those that could be loaded into theframework process.
Since the framework and cradle processes havedifferent capabilities, the plug-in list returned might not include plugins that could be legitimately loaded by the cradle process in question.Once you have identified which plug-in to load and decided when todo so, you should load it as follows:1.If the required cradle process does not already exist it should bestarted in the same way plug-in processes are started in Quarantine(see page 260) so that each process has the opportunity to performsecurity checks on the other.2.Over IPC, request that the cradle process loads a plug-in by specifyingits ECom implementation UID.CRADLE2793.
The cradle process should load a plug-in via ECom as described inBuckle (see page 252).Symbian OS provides a number of mechanisms which you can use toprovide the necessary IPC:• Message Queues (described in the Symbian Developer Library)• Publish and Subscribe (see page 114)• Client–Server (see page 182)Of these, the preferred solution is Client–Server because MessageQueues doesn’t provide as much support for exceptional conditions. Forinstance, if a plug-in panics its process then, with Message Queues, theframework would only know about this because it wouldn’t get anyresponses to its service requests whereas Client–Server ensures that theframework is told as soon as a client ends a session with it for any reason.Since you’re hosting plug-ins in a separate process from the framework,you probably suspect that this is an increased possibility.
Publish andSubscribe could be made to work but, since it is not intended for extensivetwo-way communication, it is not immediately amenable to addressingyour needs here.The details of the implementation of IPC via Client–Server areexplained in detail on page 182 although the following points giveyou some guidelines for adapting it for this pattern:• The framework proxy implements the client-side interface by derivingfrom RSessionBase.• The server side should be implemented to execute within each of thecradle processes.
Assuming there’s no use for the plug-ins once theframework is no longer using them; the server should be implementedin a transient39 manner so that the cradle process is only runningwhen there are plug-ins loaded. Making the server transient helps toreduce the RAM used by this solution at the cost of increased timeto load a plug-in.• The cradle server should only allow clients with the framework’sSID to connect to it. This not only enforces this design constraintbut also simplifies the implementation since there’s unlikely to bea need for further security checks on individual IPC calls.
Henceusing the CPolicyServer class is probably not going to be necessary.• If you are hosting multiple plug-ins in a single cradle process then itwould make sense to implement the plug-in proxies as sub-sessionsrather than sessions.39 Formore details, see the transient server variant of Client–Server (page 182).280SECURITYOne drawback of using Client–Server (see page 182) is that to protect the server from being spoofed you need each cradle processto be assigned the system capability ProtServ which then forceseach plug-in to be assigned it too. This grants the right to the cradleserver to register within a protected name space. If ProtServ weren’tused then a piece of malware could register a server with the samename as the cradle server which would cause the cradle process tofail to start. Hence this spoofing would result in a denial-of-serviceattack.See the information on ECom in the Symbian Developer Library aswell as Writing Secure Servers in [Heath, 2006, Section 5].Plug-insIdeally, plug-in providers shouldn’t actually need to know how the IPCbetween the framework and cradle processes works.
Indeed the lessthey need to know about the cradle processes the better. Unfortunatelyplug-in providers do need to know about the various cradle processessince during development they have to choose which one they wouldlike to be loaded by according to which capabilities they need theirplug-in to have at run time. This should be done by installing the tworesource files needed by the framework along with the plug-in DLLas specified by the framework provider following the description givenabove.Having done this, a plug-in developer should assign to the plug-in DLLthe same capabilities as used by the cradle process it will be loaded by.This is done in the plug-in’s MMP file using the CAPABILITY keywordas described in Buckle (see page 252).Other than this, a plug-in should be implemented exactly as specifiedby the ECom service.ConsequencesPositives• This pattern allows the plug-ins to run with capabilities independent of the framework process.
This leads to both the frameworkand each plug-in running with the minimum capabilities that theyindividually and not collectively need. The main benefits of this arethat:• The security risk to the device is reduced.• It is easier for developers to provide a plug-in.• The security risk to the framework is reduced since the plug-ins runin a separate memory space.CRADLE281• The security risk to the plug-ins is reduced since they run in a separatememory space from the framework and potentially from the otherplug-ins as well.• The capabilities of the framework can be increased without impactingthe plug-ins, which makes maintenance easier.Negatives• An additional attack surface has been added which increases thesecurity risk although this is mitigated by the fact that the securitydefense against this risk only needs to be implemented once by theframework provider unlike in Quarantine (see page 260), where eachindividual plug-in provider has to implement these defenses.• If you host multiple plug-ins in the same cradle process then there isa risk that one plug-in will interfere with the other plug-ins whetherby accident or design.
For instance, if one plug-in panics then all theplug-ins in the same thread would be destroyed. Also, a plug-in wouldbe able to interfere with the memory used by another plug-in and sochange its behavior.• Plug-ins do not have complete freedom to choose their own capabilities as in Quarantine (see page 260) but instead can choose fromas many options as cradle EXEs are supplied by the framework provider.• There is an additional performance overhead incurred by the creationof each cradle process (approximately 10 milliseconds longer42 ) andby the use of IPC for each subsequent operation.
If a significantamount of data needs to be transferred, then there could also bea sizeable performance overhead due to copying the data betweenthe processes, although a data-sharing mechanism could be used toaddress this at the cost of further complicating the solution.• Using an inter-process communication mechanism is more complex than the intra-process communication needed in Buckle (seepage 252) which increases the development and maintenance costsof using this pattern.• There is a default minimum of at least 21–34 KB RAM overhead40incurred by each cradle process created.• Using Client–Server (see page 182) to implement this pattern wouldmean plug-ins also need to be assigned the ProtServ capability which increases the development costs of the plug-in providersslightly.40See Appendix A for more details.282SECURITYExample ResolvedFrameworkAs described in the problem Example section, the SyncML subsystemneeded to be extended to allow plug-ins to be provided that onlyneeded to be assigned user-grantable capabilities whilst allowing otherplug-ins to be provided that used additional system capabilities to execute their functionality.One way that plug-in providers were freed from the need to havetheir plug-ins signed with system capabilities was to allow data providerplug-ins to no longer run within the Sync Agent process and instead to behosted in a separate server process.
Two standard cradle processes wereadded:• Host Server 1 (smlhostserver1.exe) loads plug-ins which justneed to be assigned the user-grantable capabilities ReadUserDataand WriteUserData.• Host Server 2 (smlhostserver2.exe) loads plug-ins which justneed to be assigned the system capabilities ReadDeviceData andWriteDeviceData in addition to the user-grantable capabilitiesReadUserData, WriteUserData and NetworkServices.This is a good example of the Sync Agent process having capabilitiesindependent of its plug-ins since it is assigned the system capability ProtServ in addition to the user-grantable capabilities NetworkServices,LocalServices, ReadUserData and WriteUserData.This example chooses to implement the pattern using Client–Server(see page 182) for the IPC, which results in the structure shown inFigure 7.14, where just one of the host servers is shown.SmISyncAgent.exe ProcessSmIHostServer1.exe ProcessRSessionBaseCSmIDataSyncUsage[via someintermediaries]RSmICSDataProviderCSession2multipleIPC CallsData ProviderPlug-inCSMIDPSessionCSmIData Provider[via someintermediaries]Figure 7.14 Structure of SyncMLThe main components involved in this pattern are as follows:• CSmlDataSyncUsage, which represents a data synchronizationtask, is the plug-in client.CRADLE283• RSmlCSDataProvider is the framework proxy and implements theclient session object.• CSmlDPSession is the plug-in proxy and implements the serversession object.• CSmlDataProvider defines the plug-in interface that data providerplug-ins have to implement.Not shown in Figure 7.14 is the CSmlDPServer class that derivesfrom CPolicyServer rather than CServer2 to allow a cradle processto check that each IPC message has come from the Sync Agent processby checking the caller’s SID.The diagram has been simplified by not showing some intermediateclasses between CSmlDataSyncUsage and RSmlCSDataProviderand between CSmlDPSession and CSmlDataProvider; they areused to abstract away the details of whether a plug-in is loaded directlyinto the Sync Agent process or into a cradle process depending on whatcapabilities it requires.Note that ProtServ is not used by smlhostserver1.exe since thewhole point of this process is that it allows plug-ins to be loaded that onlyhave to be assigned user-grantable capabilities which wouldn’t be true ifthey also had to have ProtServ.