Mobile Application Security : SymbianOS Security - Interprocess Communication

2/23/2011 9:22:10 AM
SymbianOS supports kernel-mediated communication between running processes. Thanks to the protected memory model, a process cannot directly modify the memory space of another running process. Interprocess communication is still a desirable activity—for example, dividing a single executable into two executables that communicate to provide a separation of concerns.

Client/Server Sessions

A client/server IPC model is used pervasively throughout SymbianOS. A number of the OS-provided services are implemented in two components: a server process and a client DLL that creates a session with the server. The server is an independent, long-running process with its own SecureID. The client DLL is loaded by client processes and maintains a mapping between function names and ordinal function numbers. Note that the client DLL is not strictly necessary, but the developer must interact with the server in the same fashion.

Part of implementing a client/server interface includes the ability to enforce a particular security policy as to which clients can connect to a server and which servers a client will connect to. A security policy is defined using one of fifteen _LIT_SECURITY_POLICY macros. These macros can be grouped in three categories: Capability enforcement, SecureID enforcement, and VendorID enforcement. A listing of these macros can be seen in Table 1. A server can and should validate the capabilities of clients that connect to it in order to prevent capability leakage where a privileged server performs sensitive actions on behalf of an unprivileged client. A server can also enforce that only clients with a particular SecureID can connect to it. This can be useful when implementing an application model where sensitive actions are performed in a small second process. Finally, a server can enforce that only clients from a particular vendor can connect to it when the vendor factors out sensitive actions into a common process that each of its applications should be able to access.

Table 1. Security Policy Macros
_LIT_SECURITY_POLICY_C1Enforce one capability
_LIT_SECURITY_POLICY_C2Enforce two capabilities
_LIT_SECURITY_POLICY_C3Enforce three capabilities
_LIT_SECURITY_POLICY_C4Enforce four capabilities
_LIT_SECURITY_POLICY_C5Enforce five capabilities
_LIT_SECURITY_POLICY_C6Enforce six capabilities
_LIT_SECURITY_POLICY_C7Enforce seven capabilities
_LIT_SECURITY_POLICY_S1Enforce a SecureID and one capability
_LIT_SECURITY_POLICY_S2Enforce a SecureID and two capabilities
_LIT_SECURITY_POLICY_S3Enforce a SecureID and three capabilities
_LIT_SECURITY_POLICY_V1Enforce a VendorID and one capability
_LIT_SECURITY_POLICY_V2Enforce a VendorID and two capabilities
_LIT_SECURITY_POLICY_V3Enforce a VendorID and three capabilities

Each of these macros is used in the same general way. The first parameter specifies the name of a new policy object. For SecureID macros, the second parameter specifies the targeted SecureID. For VendorID macros, the second parameter specifies the targeted VendorID. The rest of the parameters are one of the enumerated capabilities, the number of which is specified in the macro name.

_LIT_SECURITY_POLICY_S0(KCustomServerSID, 0xE0000001);
_LIT_SECURITY_POLICY_V1(KClientVIDOneCap, 0xE0000001, ECapabilityDiskAdmin);
_LIT_SECURITY_POLICY_C2(KEnforceTwoCaps, ECapabilityReadUserData,

Client sessions are created via an RSessionBase object and a call to the CreateSession() method. Most client DLLs will derive their own subclass that calls this method with the appropriate parameters. During the 9.x series, another overload of CreateSession() was added that takes a pointer to a TSecurityPolicy object. This allows a client to validate the SecureID or VendorID of the named server. Messages to the server are delivered and responses obtained through the SendReceive() method. Most client DLLs will provide wrapper functions for calls to SendReceive() to provide a more natural interface. The code below shows the basic pattern behind writing a client proxy object. This class will reside within a client DLL and hide the interprocess communication details.

_LIT(KCustomServerName, "com_isecpartners_custom");

enum TCustomServerMessages {

class RCustomSession : public RSessionBase {
IMPORT_C TInt Connect();
IMPORT_C TInt DoStuff(const LString& str);

EXPORT_C TInt RCustomSession::Connect() {
return CreateSession(KCustomServerName,

EXPORT_C TInt RCustomSession::DoStuff(const LString& str) {
return SendReceive(EDoStuff, TIpcArgs(&str));

Servers are created by deriving two of three classes: CSession2 and either CServer2 or CPolicyServer. CServer2 works well in many cases—namely, where the security policy to be enforced is straightforward (for example, restricting potential clients to those with a particular SecureID upon session connection or requiring a particular capability to call a certain method). In order to enforce a policy with a CSession2 or CServer2 class, call the CheckPolicy() method of a SecurityPolicy object with RMessage& as the first parameter. The result of this method is a boolean indicating whether the message was delivered by a process that conforms to the policy. Wrapping calls to this method in an if statement allows for corrective action to be taken. In the following example, the corrective action is to “leave” with a permission-denied error:

class CCustomSession : public CSession2 {
void ServiceL(const RMessage2& msg);
TInt doStuff(const LString& str);
TInt getStuff (LString& str);

void CCustomSession::ServiceL(const RMessage2& msg) {
TInt status = KErrNotSupported;
switch (aMessage.Function()) {
case EDoStuff: {
LString param(msg.GetDesLengthL(0));
msg.ReadL(0, param);
status = doStuff(param);
case EGetStuff :{
if(!KEnforceTwoCaps().CheckPolicy (msg,
__PLATSEC_DIAGNOSTIC_STRING("CCustomSession::ServiceL"))) {

LString result;
status = getStuff(result);

__ASSERT_ALWAYS(result.Length() <= msg.GetDesMaxLengthL(0),
msg.WriteL(0, result);
default: {
_LIT(KErrMsg, "Unknown function call!");
msg.Panic(KErrMsg, KErrNotSupported);

class CCustomServer : public CServer2 {
CCustomServer(TInt priority = EPriorityNormal);

CSession2* NewSessionL(const TVersion& version,
const RMessage2& msg) const;

CCustomServer::CCustomServer(TInt priority) : CServer2(priority,
ESharableSessions) {
CSession2* CCustomServer::NewSessionL(const TVersion&,
const RMessage2&) const {
__PLATSEC_DIAGNOSTIC_STRING("CCustomServer::NewSessionL"))) {
return new (ELeave) CCustomSession();

CPolicyServer should be chosen when the policy to be enforced is very complex. Although substantially more complex in simple cases, it can be much simpler in complex cases. The framework automatically handles checking a prospective client’s policy conformance upon session initiation and for each message. The first step is to create an array of message numbers in sorted increasing order. Each number need not be represented, just the lower bound of a range that shares the same policy. That is, if functions 0 through 3 share a policy and function 4 has its own policy, then the array should have two elements: 0 and 4. Next, a second array is created that must be the same size as the previous one to contain indices into a third array. This third array contains the separate policy-enforcement objects. When a message is sent to the server, its function number (or the closest number less than it) is found in the first array and the index is noted. This index is used to reference into the second array in order to obtain the index into the third array, where the actual policy object is found. Conceptually this can be imagined as a dictionary that maps a function ordinal to the policy to be applied, where the first array holds the dictionary key and the second array holds a reference to the policy. The code below demonstrates the basics behind using the CPolicyServer class to reduce the developer effort required to enforce complex security policies.

const TUInt rangesCount = 3;

const TInt msgNumRanges[rangesCount] = {
0, // EDoStuff
1, // EGetStuff
2 // Non-existent functions

const TUInt8 msgPolicyIndices[] = {
CPolicyServer::EAlwaysPass, // EDoStuff
1, // EGetStuff
CPolicyServer::EBadMessageNumber // Non-existent functions

const CPolicyServer::TPolicyElement msgPolicies[] = {
_INIT_SECURITY_POLICY_V1(0xE0000001, ECapabilityDiskAdmin),

const CPolicyServer::TPolicy customPolicy = {

class CCustomPolicyServer : public CPolicyServer {
CCustomPolicyServer(TInt priority = EPriorityNormal);

CSession2* NewSessionL(const TVersion& version,
const RMessage2& msg) const;

CCustomPolicyServer::CCustomServer(TInt priority) :
CPolicyServer(priority, CustomPolicy, ESharableSessions) {

CSession2* CCustomPolicyServer::NewSessionL(const TVersion&,
const RMessage2&) const {
return new (ELeave) CCustomSession();

Shared Sessions

Sessions can be created as unsharable, sharable between threads within the same process, or sharable between processes. This is defined on both the client and server sides. When CreateSession() is called on the client, one of the parameters specifies the desired session sharing. The CServer2() constructor specifies the type of sessions that can be created.

Use caution when allowing globally sharable sessions and implementing a policy where clients are checked at session initialization. A client that does not meet the policy could obtain a session handle from a process that did. This is especially true when implementing subsessions. Subsessions maintain a reference to the parent session (which maintains a list of open subsessions). When sharing a subsession, be aware that all of the other active subsessions are also exposed.

Shared Handles

Another form of IPC available to SymbianOS processes involves sharing handles to kernel-side objects. A number of these objects share a common interface because they derive from the same base class: RHandleBase. Examples of these objects include RChunk, RSemaphore, RMutex, and RSessionBase.

RChunk references a chunk of memory and is useful for transferring large amounts of data between processes. In previous versions of SymbianOS, this could not be used securely. An RChunk object could either be created locally, accessible only to the current process, or created as a named global object, accessible to any process that knew the name. With the introduction of 9.x, anonymous global chunks were introduced. These objects were accessible between processes, but the creating process had to pass the handle to the consuming process through the client/server interface. This greatly limited the possibility of unintentionally leaking data through a global handle; however, one still needs to take care because a shared handle can be shared further to other processes.

This same interface is exposed for the other RHandleBase-derived classes. They can be created locally, named globally, or anonymous globally. This allows a process to carefully control access to these kernel-side handles. In fact, it is this interface exposed by the RSessionBase that allows for separate processes to share file handles. A session handle to the file server is shared between two processes.

  •  Mobile Application Security : SymbianOS Security - Permissions and User Controls
  •  Windows Phone 7 Development : Building a Trial Application (part 3) - Verifying Trial and Full Mode & Adding Finishing Touches
  •  Windows Phone 7 Development : Building a Trial Application (part 2) - Connecting to a Web Service & Adding Page-to-Page Navigation
  •  Windows Phone 7 Development : Building a Trial Application (part 1) - Building the User Interface
  •  jQuery 1.3 : Table Manipulation - Sorting and paging (part 2) : Server-side pagination & JavaScript pagination
  •  jQuery 1.3 : Table Manipulation - Sorting and paging (part 1) : Server-side sorting & JavaScript sorting
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 3) - Simulating Application Trial and Full Modes
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 2) - Using the Marketplace APIs
  •  Windows Phone 7 Development : Understanding Trial and Full Modes (part 1) - Using the IsTrial Method
  •  Mobile Application Security : SymbianOS Security - Application Packaging
    PS4 game trailer XBox One game trailer
    WiiU game trailer 3ds game trailer
    Top 10 Video Game
    -   Minecraft Mods - MAD PACK #10 'NETHER DOOM!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
    -   Minecraft Mods - MAD PACK #9 'KING SLIME!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
    -   Minecraft Mods - MAD PACK #2 'LAVA LOBBERS!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
    -   Minecraft Mods - MAD PACK #3 'OBSIDIAN LONGSWORD!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
    -   Total War: Warhammer [PC] Demigryph Trailer
    -   Minecraft | MINIONS MOVIE MOD! (Despicable Me, Minions Movie)
    -   Minecraft | Crazy Craft 3.0 - Ep 3! "TITANS ATTACK"
    -   Minecraft | Crazy Craft 3.0 - Ep 2! "THIEVING FROM THE CRAZIES"
    -   Minecraft | MORPH HIDE AND SEEK - Minions Despicable Me Mod
    -   Minecraft | Dream Craft - Star Wars Modded Survival Ep 92 "IS JOE DEAD?!"
    -   Minecraft | Dream Craft - Star Wars Modded Survival Ep 93 "JEDI STRIKE BACK"
    -   Minecraft | Dream Craft - Star Wars Modded Survival Ep 94 "TATOOINE PLANET DESTRUCTION"
    -   Minecraft | Dream Craft - Star Wars Modded Survival Ep 95 "TATOOINE CAPTIVES"
    -   Hitman [PS4/XOne/PC] Alpha Gameplay Trailer
    -   Satellite Reign [PC] Release Date Trailer