A Nested Transaction Model for Multilevel Secure Database Management Systems ELISA BERTINO University of Milano and BARBARA CATANIA University of Genova and ELENA FERRARI University of Insubria
This article presents an approach to concurrency control for transactions in a Multilevel Secure Database Management System (MLS/DBMS). The major problem is that concurrency control mechanisms used in traditional DBMSs are not adequate in a MLS/DBMS, since they may be exploited to establish covert channels. The approach presented in this article, which uses single-version data items, is based on the use of nested transactions, application-level recovery, and notification-based locking protocols. All these features allow us to develop a concurrency control mechanism that is free of timing channels and avoids many of the shortcomings of the concurrency control mechanisms so far developed for conventional (i.e., flat) transactions, such as transaction starvation and resource wastage. Categories and Subject Descriptors: H.2.4 [Systems]: Transaction processing; H.2.4 [Systems]: Concurrency control; D.4.6 [Security and Protection]: Information flow controls General Terms: Security Additional Key Words and Phrases: Nested transactions, multilevel secure database management systems, concurrency control, covert channels
1. INTRODUCTION Transactions represent an important data management functionality in both centralized and distributed environments. Due to the relevance of the Authors’ addresses: Elisa Bertino, Dipartimento di Scienze dell’Informazione, University of Milano, Via Comelico 39/41, 20135 Milano, Italy, email:
[email protected]; Barbara Catania, Dipartimento di Informatica e Scienze dell’Informazione, University of Genova, Via Dodecaneso 35, 16146 Genova, Italy, email:
[email protected]; Elena Ferrari, Dipartimento di Scienze Chimiche, Fisiche e Matematiche, University of Insubria, Como, Via Valleggio, 11, 22100 Como, Italy, email:
[email protected]. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or direct commercial advantage and that copies show this notice on the first page or initial screen of a display along with the full citation. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of this work in other works, requires prior specific permission and/or a fee. Permissions may be requested from Publications Dept, ACM Inc., 1515 Broadway, New York, NY 10036 USA, fax +1 (212) 869-0481, or
[email protected]. ° C 2001 ACM 1094-9224/01/1100–0321 $5.00 ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001, Pages 321–370.
322
•
E. Bertino et al.
transaction paradigm, transaction models and mechanisms have been widely investigated [Gray and Reuter 1993], and extensions to this paradigm have been proposed to deal with different application environments and different operational requirements. A particularly crucial case is represented by Multilevel Secure Database Management Systems (MLS/DBMSs), whose goal is to support highly secure data stores. In such systems, data and processes, accessing data on behalf of users, are classified into different security levels. Access is usually governed by the following rules [Bell and LaPadula 1976; Sandhu 1993]. Let P be a user process and let d be a data item. P can read d only if the security level of P is greater than or equal to the security level of d ; whereas P can write d only if its security level is equal to that of d . The second rule is a restriction of the rule first proposed in Bell and LaPadula [1976] that allows P to write d only if the security level of d is equal or greater than the security level of P . The reason for such restriction is that write-up operations may cause integrity problems. For instance, an unclassified user process can write secret data, and thus destroy or damage its content. A well-known problem in MLS/DBMSs is that of preventing covert channels [DOD 1985]. A covert channel allows a transfer of information that violates the security policy. Covert channels can be classified into two broad categories: storage and timing channels. The distinguishing feature between the two is that in timing channels the information is conveyed by the timings of events or processes; whereas storage channels do not require any temporal synchronization, in that information is conveyed by accessing system information. When transactions are concurrently executed, the transaction management mechanism must be properly designed to prevent its exploitation in order to establish a covert channel, as illustrated by the following example, where we consider a conventional locking scheme based on the 2-phase locking (2PL) protocol [Gray and Reuter 1993]. Example 1. Consider a multilevel database storing information at two different security levels: high and low. According to the multilevel security principles, a low transaction is only able to read and write low-level data, whereas a high transaction can read and write high data as well as read low data. Consider two transactions Tl and Th of level low and high, respectively. Suppose that d 1 is a data item classified at level low. Suppose that Tl and Th are the only transactions in the system and that Th requires a read lock on d 1 . The lock is granted because no other transaction has a lock on d 1 . Suppose now that transaction Tl wishes to write the same data item d 1 . It thus requires a write lock on d 1 . Since transaction Th holds a read lock on d 1 , transaction Tl is forced to wait until Th releases its lock. Thus, by selectively issuing requests to read low-level data, transaction Th can modulate the delay experienced by transaction Tl . Since, Th has full access to high-level data, this delay can be used to transfer high-level information to transaction Tl . Thus, a timing channel is established between the two transactions. Moreover, other form of covert channels can be established if system resources and/or system information are not properly managed and protected. This happens, for instance, when a low-level subject can access information on the resource usage made by ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
323
high-level subjects, or when information on data locks (i.e., lock bits) is visible to low subjects. Concurrency control mechanisms for a MLS/DBMS must therefore be secure, that is, they must not be exploited to establish covert channels, such as those in the example above. One of the most challenging issues is that of closing the covert timing channels due to lock-based transaction synchronization. To deal with this problem, several extensions to locking protocols have been proposed, which we discuss in detail in Section 2. The majority of such extensions are based on the principle that transactions cannot be delayed or aborted due to a lock conflict with a higher-level transaction. Hence low-level transactions have higher priority on low-level data than higher-level transactions. The consequence is that even though a transaction may have acquired a read lock on a lower-level data item, it may be forced to release this lock if a lower-level transaction requires a write lock on it. Due to such priority, transaction execution histories may not be always serializable. Several approaches have been proposed to address the issue of how to synchronize transactions so that timing channels do not occur and, at the same time, serializability is achieved. However, they suffer from several shortcomings, such as starvation of high-level transactions that can be repeatedly aborted, or require multiple versions of data, or force high-level transactions to read stale data. A different approach has recently been proposed by Bertino et al. [1998], which is based on the idea that whenever a lock held by a transaction on a lower-level data item is “broken” by a lower-level transaction, an applicationlevel recovery is executed by the higher-level transaction. By application-level recovery we mean that the higher-level transaction is notified that a lowerlevel lock is broken, and thus that the data item may have been modified. The higher-level transaction may then execute application code to deal with this situation. It may, for example, abort, or read the data item again, or continue its execution. Note that, unlike other approaches, application-level recovery does not necessarily force the abort and restart of the transaction, and thus it offers more flexibility than other approaches because it allows us to trade among different requirements. The main shortcoming of such an approach, however, is that it uses a rather primitive transaction model, based on flat transactions with savepoints. Such a model does not support well the idea that a transaction should be organized into different components that may be selectively aborted or committed. The possibility of selectively aborting, or committing different components of a given transaction is, however, crucial in effectively supporting application-level recovery. Such a possibility would allow us to isolate specific components of the transaction that are dependent on read operations on lower-level data. A wellknown transaction model supporting such an articulated transaction structuring is the nested transaction model, first proposed by Moss [1985]. The definition of such a transaction model can be considered a milestone since, starting from it, several other advanced transaction models have been developed; and also adopted in transaction-processing monitors and distributed systems. We believe that a nested transaction model, combined with notification lock protocols ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
324
•
E. Bertino et al.
and primitives for application-level recovery, represents a solution to the problem of secure concurrency control in multilevel systems that could be adequate for many applications. To the best of our knowledge, however, no nested transaction model for multilevel secure systems has been proposed so far. The goal of the work presented here is to develop such a model. More specifically, the goals of our work are: (i) the definition of a multilevel secure nested transaction model equipped with primitives for application-level recovery; (ii) the definition of a locking protocol scheme free of timing channels and able to support notification mechanisms; (iii) the development of a formal definition of the proposed concepts; (iv) the identification of sufficient conditions on the nested transaction structure ensuring serializable execution histories; and (v) the design of an architecture and an execution model supporting secure transaction processing according to the proposed locking scheme. We would like to remark that even though our work is primarily addressed to multilevel secure systems, it also has some relevance for systems using notification protocols, such as design and cooperation environments and real-time systems. In all these environments, transactions may be forced to release locks, often have articulated structures, and need to handle exceptions. Hence it is relevant to understand how notification locks or lock preemption can be handled within nested transactions, which is exactly one of the contributions of our work. Organization. The article is organized as follows: Related work is surveyed in the next section. Section 3 introduces the nested transaction model and the concept of nested transaction in a multilevel environment. The secure locking protocol for nested transactions in a multilevel environment is then presented in Section 4. Primitives for generating nested transactions and a formal model for secure nested transactions are introduced in Sections 5 and 6, respectively. Serializability results for the proposed protocol are presented in Section 7, whereas Section 8 presents security results, showing that the proposed protocol is secure against timing channels. In Section 9, we present an architecture supporting the proposed approach and introduce the execution model for the proposed protocol. A discussion of the flexibility and the efficiency of the proposed approach is then presented in Section 10. Finally, Section 11 concludes and outlines future work. 2. RELATED WORK Several approaches have been proposed for concurrency control in MLS/DBMSs, most are either extensions of the 2PL protocol or of timestamp-based protocols. However, unlike our work, all of these proposals deal with the conventional (i.e., flat) transaction models. In the locking-based approaches, in order to prevent timing channels, the execution of a transaction is never delayed by a lock held by a higher-level transaction. McDermott and Jajodia [1992] propose a locking protocol in which, as in the conventional 2PL protocol, when a transaction wishes to read a data item, it first acquires a read lock on it. However, if a lower-level transaction wishes to write that data item, the higher-level transaction is forced to release the lock. To reduce starvation, the higher-level transaction is not ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
325
aborted, but tries to read the modified data item again by entering a queue of transactions waiting for reading that data. Such an approach, however, does not always ensure serializability [Jajodia et al. 1996]. To address this problem, Jajodia et al. propose two secure locking protocols [Jajodia et al. 1996]. The first protocol ensures pairwise serializability, that is, a weaker notion of serializability that ensures the correct execution of transactions at any two security levels [Jajodia and Atluri 1992], whereas the second protocol ensures serializability if the security levels are totally ordered. In case the security levels form a partial order, the second protocol ensures a weaker notion of serializability, called MLS-serializability, which was introduced in Jajodia et al. [1996]. Among the proposals extending conventional timestamp-based concurrency control algorithms, Ammann and Jajodia [1991] proposed two protocols that avoid timing channels but are prone to starvation. A solution for avoiding starvation is to maintain multiple versions of the same data. For these multiversion approaches, the serializability criteria, called one-copy serializability [Bernstein et al. 1987], requires that the effects of the concurrent execution of a set of transactions is equivalent to that of a serial execution of the same transactions on a one-copy database. The most relevant proposals in this area are due to Maimone and Greenberg [1990], Keefe and Tsai [1990], and Jajodia and Atluri [1992]. All such protocols avoid timing channels. However, Maimone and Greenberg’s protocol does not generate one-copy serializable histories. The protocol proposed by Keefe and Tsai guarantees one-copy serializability and avoids starvation, but it is based on a multilevel scheduler, and hence needs to be trusted. By contrast, the protocol proposed by Jajodia and Atluri uses singlelevel schedulers, and can thus be implemented with untrusted code. However, under such a protocol, a transaction may be forced to read the same lower-level data several times. Moreover, a transaction cannot commit until all lower-level transactions with timestamps lower than its timestamp have completed. Other multiversion approaches are the snapshot algorithms proposed by Ammann et al. [1992], Ammann and Jajodia [1992], and Pal [1995]. From the commercial solutions side, Sybase Secure SQL Server [Sybase, Inc. 1993] uses the standard 2PL protocol, which, as we pointed out in the Introduction, is prone to timing channels. In Informix-OnLine/Secure [Informix Software, Inc. 1993a, 1993b], a transaction can acquire a write lock on a data item, even if a higher-level transaction holds a read lock on such a data item, thus avoiding formation of a timing channel. When the lower-level transaction acquires the lock, the higher-level transaction is simply notified of this acquisition, but it still commits—unless the programmer has added some code to roll back the transaction. The major drawback of the Informix solution is that, when a transaction has several read locks on lower-level data items, the transaction is notified when some lower-level transactions acquire a write lock on such items, but no information is provided to the higher-level transaction specifying which data items have acquired the locks. Thus, only a very primitive conflict-handling approach is possible. Moreover, since Informix supports a flat transaction model, it is not possible to partially roll back the transaction, in order to read the modified data again. Finally, Trusted Oracle [Oracle Corp. 1992] ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
326
•
E. Bertino et al.
uses a combination of locking and multiversioning techniques that, although they avoid timing channels, do not ensure one-copy serializability. In all the approaches mentioned above, if a data conflict arises between two transactions at different security levels, the conflict is always solved in favor of the lower-level transaction that should not be influenced (that is, delayed) by such conflict. Implementing such an approach may cause the higher-level transaction to be delayed or rolled back several times, and thus may cause waste of resources and transaction starvation. The main reason is that all the above proposals are based on the flat transaction model that does not allow the selective commit or abort of parts of a transaction. Such a drawback is avoided by our approach, which is based on a nested transaction model rather than on a flat one. In our protocol, as in the other proposals, conflicts are always solved in favor of the lower-level transaction; however, due to the properties of the nested transaction model, our approach does not require the delay of the whole higher-level transaction or its total rollback. Furthermore, we provide the programmer with a powerful set of primitives for managing data conflicts among transactions that allow him/her to choose among a wide range of possibilities for handling the conflict (ranging from the abortion of the subtransaction involved in the conflict to the execution of compensating subtransactions). Moreover, we provide a set of guidelines for coding transactions that always ensure their serializability. Our work is inspired by that of Bertino et al. [1998], which was the first to address secure concurrency control for nonconventional transaction models. The work by Bertino et al. proposes a locking protocol for transactions with savepoints, and is the first to introduce a set of primitives that programmers can use to manage conflicting situations. The current work extends that presented in Bertino et al. [1998] to deal with nested transactions. This is a major extension for both the practical relevance of nested transactions and for the theoretical issues related to the development of suitable locking mechanisms and serializability theories for nested transactions. In particular, the interactions between parent and child transactions in the same nested transaction and the fact that, in our nested transaction model, parent and child transactions can be executed concurrently requires us to substantially revise and extend both the primitives and the locking protocol in Bertino et al. [1998], as well as the related implementation mechanisms. Moreover, serializability theory for nested transactions is substantially more complex than theories for transactions with savepoints. Other related work by Moss [1985] and by Harder and Rothermel [1993], proposes locking schemes for nested transactions, extending the standard 2PL protocol. However, none of these proposals deals with the execution of nested transactions in a MLS/DBMS. Our work is inspired by the above-mentioned proposals. In particular, we extend the locking scheme proposed by Moss as suitable for a MLS/DBMS. Finally, our work is influenced by that of Beeri et al. [1989] and Halici et al. [1997], which develop a model for nested transaction processing and a serializability theory for proving the correctness of concurrency control algorithms for nested transactions. In particular, in this article we use the general framework ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
327
proposed in Halici et al. [1997] for proving correctness of nested transaction executions, and cast this framework in the context of MLS/DBMSs. We then use it as the basis for proving serializability results. 3. MULTILEVEL NESTED TRANSACTIONS In the following, we first review and motivate the nested transaction model, present the multilevel security model, and introduce the concept of nested transaction in a multilevel environment. 3.1 An Introduction to the Nested Transaction Model A large number of transaction models has been proposed and implemented. Most of them are extensions of a basic transaction model, known as the flat transaction model [Gray and Reuter 1993]. Flat transactions have been used in all commercially available DBMSs, and have also been introduced in operating and communication systems. A flat transaction has a single-level control structure only, and satisfies the well-known ACID (atomicity, consistency, isolation, and durability) properties [Gray and Reuter 1993], representing unifying concepts for fault-tolerant and correct computations in both centralized and distributed settings. ACID properties are defined as follows: (1) Atomicity (also called an all-or-nothing property): all the operations executed by a transaction must be treated as a single unit; therefore, either all operations are executed or none are. (2) Consistency deals with the correctness of concurrently executed transactions. If executed alone, a transaction transforms a database from a consistent state into another consistent state. When transactions are concurrently executed, the DBMS must ensure that database consistency is preserved as if each transaction was executed alone. (3) Isolation requires each transaction to observe a consistent database; that is, a transaction cannot read intermediate results generated by other transactions. (4) Durability requires that the results of a committed transaction be permanently installed in the database, in spite of possible system failures. The major drawback of flat transactions is that there is no way to either commit or abort parts of these transactions, or of committing results in several steps. For simple state transformations, such as debiting or crediting an account, an atomic unit of work is certainly appropriate. These are the applications for which flat transactions were designed originally. However, many other applications exist for which this model is too restrictive. The following example illustrates a fairly simple application structure that is not well supported by flat transactions. Example 2. Suppose that Mr. Money wants to go from Pittsburgh, USA to Finale Ligure, Italy. Since there are no direct flights between the two places, a number of connecting flights must be booked, perhaps some trains, and so on. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
328
•
E. Bertino et al.
The travel agent, using a transaction system, tries to find a good travel plan for Mr. Money. Suppose that the first operations performed by the transaction are the following: —Begin work; —book flight from Pittsburgh to London; —book flight from London to Milan on the next day of the flight from Pittsburgh to London; —book flight from Milan to Genoa on the same day of the flight from London to Milan. Now suppose that, after the above steps are executed, a problem arises: there is no way to reach Finale Ligure from Genoa on the same day, except by renting a car. However, Mr. Money prefers to travel at a lower cost. What can the travel agent do in that situation? One solution might be to have Mr. Money going from Milan to Nice (France) and then going by train from Nice to Finale Ligure. Another option might require Mr. Money to fly from Milan to Turin, or perhaps somewhere else. The point is that, given a flat transaction model, the travel agent has only two options: —Issue a rollback operation. This nullifies much more of the previous work than needed. In particular, there is no need to undo the reservation for the flight to London. —Explicitly cancel all reservations that are no longer useful. This solution might be very expensive if the amount of work is greater than in our example. What is needed in the above scenario is a selective rollback. Rather than aborting the whole transaction, it should be possible to roll back only the last two reservations, maintaining the first. If such a feature is not available, the application designer is forced to use a programming style requiring that the effects of unneeded updates be removed by the application. In addition to the lack of support for selective rollback operations, the flat transaction model has other limitations (we refer the reader to Gray and Reuter [1993] for further details). To overcome the limitations of the flat transaction model, several extensions have been proposed expanding the scope of the flat transaction model, generalizing its semantics, and making it more powerful. One of the most important extensions is represented by nested transactions. A nested transaction consists of a top-level transaction, controlling the activity of low-level transactions, called subtransactions. Each of these subtransactions can be completed or rolled back individually. Nesting has as many levels as the abstract layers in the application, without limitations. The most popular definition of nested transaction is the one proposed by Moss [1985], which is based on the following principles: (1) A nested transaction is a tree of transactions; the subtrees are either nested or flat transactions. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
329
(2) Leaf transactions perform the actual work. Only these transactions can access data and acquire resources. The distance from the root to the leaves is arbitrary. (3) Nonleaf transactions associated with internal nodes (also called internal transactions) just organize the execution flow, determine when subtransactions must be invoked, but cannot read and write data. (4) The transaction at the root of the tree is called the top-level transaction; all the other transactions are called subtransactions. A (sub) transaction predecessor in the tree is called a parent; a subtransaction at the next lower level is called a child.1 (5) The children of a transaction can be executed either sequentially or concurrently. (6) The execution of a transaction has to terminate before the execution of its parent terminates. However, the parent can continue its execution after the creation of a child transaction. The behavior of nested transactions is governed by the following rules: (1) Commit rule. The commit of a subtransaction makes the transaction results accessible to the parent transaction. A parent transaction cannot commit until all its children commit or abort. The subtransaction releases its results to the outside world only if it has committed and all its ancestors up to the root have committed too. (2) Rollback rule. If a transaction is rolled back, all its subtransactions are rolled back too, regardless of what they have done till that point. This rule is recursively applied down in the nesting. The immediate consequence is that if the root transaction is rolled back, the whole nested transaction is also rolled back. By contrast, the abort of a child transaction does not necessarily cause the abortion of its ancestors. When a subtransaction aborts, the parent transaction has several alternative options for handling the child abort. For instance, it can simply ignore the abort and continue its computation, it can abort as a consequence of the child abort, or it can re-execute the aborted subtransaction. Alternatively, it can execute a new subtransaction, which performs an alternative (or repairing) action, with respect to the one performed by the aborted subtransaction. (3) Visibility rule. All changes made by a subtransaction become visible to the parent transaction when the subtransaction commits. Subtransactions can view the partial results of their ancestors and the results of sibling transactions that completed their execution before the transaction termination. By contrast, changes made by a subtransaction are not visible to its siblings, in case they execute concurrently. Based on the previous rules, when a subtransaction terminates successfully, it notifies its termination to the parent transaction and waits for definitely 1 In
the following, to simplify notation, we use the term transaction to identify both the overall nested transaction and its nodes. We use the term subtransaction when we want to emphasize the fact that the transaction is generated by another transaction in the tree. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
330
•
E. Bertino et al.
committing or aborting, depending on the decisions of its parent. This implies that subtransactions are not exactly equivalent to flat transactions with respect to satisfying the ACID properties. Indeed, subtransactions are atomic from the point of view of the parent transaction; they are consistency-preserving with respect to the local function they implement; they are isolated from all other activities inside and outside the parent transaction; but they are not durable due to the commit rule. Only top-level transactions fully fulfill ACID properties. In this case, atomicity is defined with respect to the environment invoking the transaction execution. The top-level transaction is therefore atomic, since, from the point of view of the external environment, no intermediate state is visible. It is also consistency-preserving with respect to the function it implements and it is isolated. Differently from subtransactions, it is also durable, since, if it commits, results are made persistent in the system. Since leaf transactions do not exactly coincide with flat transactions, we call them weak flat transactions. On the other hand, since internal transactions can create new subtransactions, force the abort, or grant the commit to subtransactions, we call them generating transactions. Subtransactions can be generated according to two different modes: blocking and nonblocking. Under the blocking mode, the creation of a child transaction blocks the execution of the parent transaction. Thus the parent transaction has to wait for the termination of the child transaction before continuing its execution. The parent transaction and the subtransaction are therefore sequentially executed. Under the nonblocking mode, the parent continues its execution without waiting for the termination of the subtransaction. In this case, the parent transaction and the subtransactions are concurrently executed. In the following, we refer to subtransactions created under the blocking (resp. nonblocking) mode as blocking (resp. nonblocking) transactions. To support concurrency between blocking subtransactions, we also assume that sets of concurrent blocking subtransactions can be created atomically. The same approach is applied to nonblocking subtransactions. Example 3. Figure 1 gives a graphical representation, which we will use throughout the article, of a set of nested transactions {T0 , T1 , T2 }.2 Circles denote transactions, and may be connected by four different types of arcs, representing different relationships that may occur between the connected transactions. An arrow from one circle to another means that the first transaction is executed before the second one (sequential execution). For instance, with reference to Figure 1, the arrow connecting T1 with T2 denotes that transaction T1 is executed before transaction T2 . Sequential execution from left to right is also assumed by default when no line connects two sibling transactions. A pair of lines between two transactions denotes the concurrent execution of such transactions (see, for instance, transactions T0 and T1 in Figure 1). A line between a parent transaction and one of its children denotes the blocking creation of the child, and the consequent sequential execution of parent and child transactions. 2 Note
that in Figure 1 we label only nodes representing top-level transactions.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
331
Fig. 1. Graphical representation of a set of nested transactions.
Finally, three lines between a parent transaction and one of its children denote the nonblocking creation of the child and the consequent concurrent execution of child and parent transactions. Note that, according to our transaction model, no cycle can arise in the graph representing a set of nested transactions and no node is child of more than one parent transaction. Thus the structure of a set of nested transactions is a forest of trees rather than a graph. In the following, a generic nested transaction is denoted by Ti , i = 1, 2, . . . , whereas generic data items are denoted by a, b, c, . . . . Example 4. As an example of application of nested transactions, consider once again Example 2. The computation described in the example can be organized as a nested transaction. For instance, a distinct subtransaction can be created for managing each different part of the travel. With this organization, when the travel agent verifies that there is no way to reach Finale Ligure from Genoa except by renting a car, only the subtransaction that has booked the flight from Milan to Genoa can be rolled back, without rolling back the reservations made by the other subtransactions (e.g., booking flights from Pittsburgh to London and from London to Milan). Then, a compensating subtransaction can be generated by the parent of the rolled-back transaction which, for instance, tries to book a flight from Milan to Nice and then to make a reservation on a train going from Nice to Finale Ligure. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
332
•
E. Bertino et al.
3.2 Nested Transactions in a Multilevel Environment In this article, we deal with nested transactions in a multilevel environment, that is, nested transactions executed according to a multilevel security model. The multilevel security model we refer to consists of a set D of data items, representing the resources to be protected, and a set of transactions T R requiring accesses to elements in D. Data accesses are regulated by the Bell and LaPadula policy [1976]. In the Bell and LaPadula policy, both subjects (i.e., transactions) and objects (i.e., data items) are assigned a fixed security level. The set of security levels forms a partially ordered lattice, ordered by the dominance relation ≤. If two security levels l i and l j are ordered in the lattice such that l i ≤ l j , then we say that l j dominates l i . A security level l j is said to strictly dominate a security level l i (denoted l i < l j ) if l i ≤ l j and i 6= j . A total function L is defined with domain D ∪ T R. Given a data item d ∈ D, L(d ) denotes the security level assigned to d . Similarly, given a transaction T ∈ T R, L(T ) denotes the security level T . Data accesses are governed by the following rules: (1) a transaction T is allowed to read a data item d only if the security level of T dominates the security level of d , that is, L(d ) ≤ L(T ); (2) a transaction T is allowed to write a data item d if the security level of T is equal to the security level of d , that is, L(T ) = L(d ). As we already pointed out in the Introduction, the second rule is a restricted version of the *-property proposed in Bell and LaPadula [1976], which allows transactions to write data at higher levels. In the following, given two transactions T1 and T2 , we say that T1 is a highlevel (resp. low-level) transaction with respect to T2 if L(T2 ) < L(T1 ) (resp. L(T1 ) < L(T2 )). When considering the execution of nested transactions in a multilevel environment, we assume that all subtransactions constituting a single nested transaction have the same security level. A transaction cannot generate lowlevel subtransactions because the create operation can be seen as a form of write operation. Therefore, such a generation could be exploited as a covert channel. Moreover, it does not make sense for a transaction to be able to generate high-level subtransactions, since, under the restricted version of the *-property we adopt, subtransactions cannot perform write operations on data at higher levels. Note that generating high-level subtransactions makes sense under the nonrestricted version of the *-property. However, locking protocols for such nested transactions would result in covert channels or in nonatomic executions, thereby losing all the advantages of nested transactions. Example 5. Consider the nested transaction, say T1 , introduced in Example 4. Suppose that data concerning flights is classified at level low. Since the transaction has to both read such data, to know which flights are available, and to write it, to book some of the flights, the transaction (and all its subtransactions) has to be classified at level low. Now suppose that there exists another transaction, say T2 , that is in charge of generating customer ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
333
profiles, based on the reservation they have made. Transaction T2 has to read information about the reservations (which are classified at level low, since they are generated by transactions like T1 ) and to manage personal information about the customers (which, we suppose, is classified at level high, low < high, since it has a higher degree of sensitivity). Thus, T2 and all its subtransactions are classified at level high. 4. A SECURE LOCKING PROTOCOL FOR NESTED TRANSACTIONS IN A MULTILEVEL ENVIRONMENT Concurrency control in almost all commercially available DBMSs is based on the 2PL protocol [Gray and Reuter 1993]. According to this protocol, a transaction, before performing read or write operations on a data item, must acquire an appropriate lock on that data item. Locking mechanisms for standard (flat) transactions distinguish between two types of locks: read locks, to be acquired before reading a data item, and write locks, to be acquired before writing a data item. A transaction may acquire a read lock on a data item if no other transaction has a write lock on that data item, otherwise the transaction is forced to wait until the transaction owning the write lock releases it. Thus, multiple transactions may simultaneously hold a read lock on the same data item. By contrast, a write lock can be acquired by a transaction only if no other transaction holds a lock (either read or write) on that data item, otherwise the transaction is forced to wait. Under 2PL, a transaction must go through two distinct phases with respect to the acquisition/release of locks: a growing phase, during which the transaction acquires all the locks it needs to perform its activity, and a shrinking phase, during which the transaction releases its locks. In order to ensure transaction serializability, the constraint is imposed that, once a transaction enters the shrinking phase, it cannot acquire any more locks. The 2PL protocol has been extended by Moss to deal with nested transactions [Moss 1985]. Unfortunately, the 2PL protocol does not guarantee secure concurrent executions of nested transactions in a multilevel environment, since, as we discussed in the Introduction, it is not secure against timing channels. Starting with this limitation, in the following we present a new protocol for nested transactions, which combines the approach in Moss [1985], defined for nested transactions but not secure against timing channels, with the protocol in Bertino et al. [1998], which is defined for flat transactions with savepoints and is secure against timing channels. In defining the protocol, locking rules proposed for flat transactions in Bertino et al. [1998] must be modified to take the hierarchical structure of nested transactions into account. This means that the relationships between the locks of a transaction and those of its ancestors must be clearly specified. Another important concern is the characterization of the growing and shrinking phases for both leaf and internal transactions. In the following, in order to illustrate the proposed protocol, we first introduce the lock types. We then present locking rules, specifying how a lock of a certain type can be acquired and/or released. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
334
•
E. Bertino et al.
4.1 Lock Types To avoid timing channels, the basic idea is to allow a transaction to read a lowerlevel data item, without acquiring a read lock on it. To this purpose, besides the traditional read and write locks, an additional lock, called signal lock, is introduced. The semantics of these three types of locks is therefore as follows: —Read lock. This lock must be acquired by a transaction before reading a data item at its own security level. —Signal lock. This lock must be acquired by a transaction before reading a data item at a lower security level. —Write lock. A write lock must be acquired by a transaction before writing a data item at its own security level. Like the standard locking approach, a nested transaction must acquire a lock according to the appropriate mode (e.g., read, signal, or write) before performing any operation on that data item. However, differently from the standard approach and due to the more complex structure of nested transactions, an explicit shrinking phase, during which the transaction releases the locks to the external environment, does not exist. Internal and leaf transactions can only acquire locks. Such locks will be automatically released to the upper levels of the nested transaction (to the external environment in the case of the root transaction) at the end of transaction execution. When a transaction acquires a lock, it holds the lock until its termination. Moreover, when a transaction commits, all its locks are inherited by its parent transaction which retains them. Retaining a lock is not the same as holding it. However, retaining a lock on a data item prevents transactions outside the subtree of the transaction retaining the lock from acquiring an incompatible lock on the same data item. By contrast, if a transaction holds a lock on a data item, it can access the data item in a mode compatible with that lock. Due to the operations that leaf and internal transactions can execute, a leaf transaction can hold a lock but not retain it, whereas an internal transaction can retain a lock but not hold it. 4.2 Locking Rules Locking rules for nested transactions in a multilevel environment can be summarized as follows: —A transaction T may acquire a write lock on a data item d if both the following conditions hold: —no other transaction holds a read or write lock on d ; —all the transactions that retain either a read or write lock on d are ancestors of T . —A transaction T may acquire a read lock on a data item d if both the following conditions hold: —no other transaction holds a write lock on d ; —all transactions retaining a write lock on d are ancestors of T . ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
335
Table I. Lock Compatibility Rules Non ancestors
Locks that can be granted
Held W Held R Held S Retained W Retained R Retained S
RS RS RS WRS Legend: W = write lock. R = read lock. S = signal lock.
—A transaction T may acquire a signal lock on a data item d if no other transaction holds or retains a write lock on d . —When a transaction commits, its parent retains all the locks (signal locks included) held or retained by the committed transaction. —When a transaction aborts, it releases all the locks it retains or holds. Such locks are not inherited by the transaction parent. According to the above rules, signal locks held by a transaction do not prevent the acquisition of a write lock on the same data item by a low-level transaction. This prevents timing channels, that is, it prevents a transaction from being delayed by read operations performed by high-level transactions. By contrast, the acquisition of a signal lock on a data item is delayed if some other transaction holds or retains a write lock on that item. Indeed, if a transaction is writing a data item a, we can delay a high transaction wishing to read a without establishing a timing channel. Such delay prevents a transaction from reading hold versions of a data, since when the high transaction is able to read data item a, it will read the new updated version of such data. Remark. Note that when a transaction T requires a signal lock on a data item d , the only condition that must be verified to grant the lock is that there does not exist a transaction that holds or retains a write lock on d . The reason is that transactions that are ancestors of T cannot retain a write lock on d . Indeed, if T is requesting a signal lock on d, it means that d has a security level lower than the security level of T . Thus, according to the Bell and LaPadula rules, the ancestors of T (that have the same security level as T ) cannot retain a write lock on d . Locking rules are summarized in Table I. The first column summarizes the locks held or retained by subtransactions that are not ancestors of the transaction Ti requesting the lock. The second column lists the locks that can be granted to the transaction Ti . Note that the information included in the first column is sufficient to determine which locks can be granted to Ti . Indeed, the ancestors of Ti can only retain locks, since, by definition, they are internal transactions, and hence cannot directly read and write data items. From the locking ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
336
•
E. Bertino et al.
rules, it follows that they cannot prevent their subtransactions from acquiring a lock. If the nonancestor transactions retain (resp. hold) different types of locks, the table indicates only the merge of all these locks, that is, the more restrictive lock. The merging operation, given a set of locks on a given data item a, returns the highest lock, according to the following ordering: write > read > signal. From the locking rules presented above, it follows that only upwards inheritance of locks is allowed, that is, transactions can only inherit their children locks but not vice versa. In order to exemplify the principles of upward inheritance, we introduce the notions of W-, R-, and S-spheres.3 Such notions extend those presented in Harder and Rothermel [1993] to take signal locks into account.4 The W-sphere (resp. R-sphere, S-sphere) of a data item a is defined as the set of transactions that can potentially lock data item a in write mode (resp. read and signal mode). In Figures 2, 3, and 4, we consider a nested transaction rooted at T1 and having transaction T2 as one of its descendants. Here, and in the remainder of the article, we use notation mode:lock(data item), where mode ∈ {h, r}, lock ∈ {R, W, S}, and data item is a data item, to denote that a given transaction holds (mode = h), or retains (mode = r), a write (lock = W ), read (lock = R), or signal (lock = S) lock on the specified data item. Figure 2 illustrates the evolution of the W-, R-, and S-sphere for data item a, with respect to the acquisition of write locks. Thus we assume that L(a) = L(T1 ). Note that, since we assume that transaction T1 retains a write lock, no S-spheres for a are present. Moreover, the W-sphere and R-sphere of a disappear when transaction T2 acquires a write lock on this data item. This means that no transaction may acquire a write or read lock on a until T2 releases the lock. After the commit of T2 , a new W-sphere and R-sphere is established, which consists of the descendants of T2 ’s parent transaction. If T2 aborts, the write lock on a is not inherited by any transaction, and therefore the W-sphere and the R-sphere coincide with all the transactions of the subtree being considered. Figure 3 illustrates the evolution of the W-, R-, and S-sphere for data item a, with respect to the acquisition of read locks. We still assume that L(a) = L(T1 ). Also in this case, no S-spheres for a are present. Moreover, the W-sphere disappears when T2 acquires a read lock, whereas the R-sphere remains unchanged. When T2 commits, a new W-sphere is established consisting of all the transactions rooted at T2 ’s parent. Also in this case, if T2 aborts, W-sphere and the R-sphere coincide with all the transactions of the subtree being considered. The behavior of signal locks is illustrated in Figure 4. In this case, we assume that L(a) < L(T1 ). Therefore, W- and R-spheres are always empty, whereas the S-sphere coincides with transaction T1 .
3 Here
and in the following we use symbol S to denote signal locks. [Harder and Rothermel 1993], W-sphere is denoted by X-sphere whereas R-sphere is denoted by S-sphere.
4 In
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
337
Fig. 2. Upward inheritance of W-locks for nested transactions in a multilevel environment (from top to bottom, from left to right).
From the previous discussion, it follows that a transaction acquiring a lock on a data item may cause the spheres of the data item to shrink, while the successful termination of a transaction may cause them to grow.
5. PRIMITIVE FOR NESTED TRANSACTIONS IN A MULTILEVEL ENVIRONMENT Primitives provide the basic capabilities for supporting the locking rules in Section 4. In the following, we first present a general overview of nested transaction primitives, and then focus on the Raise Signal and Get Signal primitives, specifically introduced to ensure the correct execution of nested transactions in a multilevel environment. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
338
•
E. Bertino et al.
Fig. 3. Upward inheritance of R-locks for nested transactions in a multilevel environment (from top to bottom, from left to right).
5.1 Overview of Transaction Primitives Primitives for nested transactions in a multilevel environment can be classified into two groups: primitives that can be invoked by both leaf and internal transactions (reported in Table II), and primitives that can be invoked by internal transactions only (illustrated in Table III). Primitives reported in Table II provide the standard basic operations to start and end a transaction, read and write a data item, and commit and abort a transaction. Furthermore, since we deal with nested transactions, an additional primitive is introduced, i.e., Request Commit, which is used by a transaction to communicate to its parent its intent to commit. Additionally, to ensure the correct execution of concurrent transactions in a multilevel environment, we introduce two primitives, namely, Get Signal and Raise Signal, which are ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
339
Fig. 4. Upward inheritance of S-locks for nested transactions in a multilevel environment (from top to bottom, from left to right).
required to securely manage the interactions between transactions at different security levels. The behavior of these primitives, described in Sections 5.2 and 5.3, follows from the behavior of similar primitives introduced in Bertino et al. [1998], extended to deal with nested transactions. As we see in Section 7, the correct use of these primitives guarantees the serializability of the proposed locking protocol. The first four primitives reported in Table III are used for transaction generation. We support four different kinds of transaction-generation primitives, which allows a transaction T to create either blocking or nonblocking subtransactions that can be either concurrently executed with some of the other children of T or be executed after the executions of a set of child transactions explicitly specified in the generation command. The last two primitives allow a transaction to grant the commit or force the abort to one of its children. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
340
•
E. Bertino et al. Table II. Primitive Invoked by Leaf and Internal Transactions Primitive
Meaning
Begin Transaction
Identifies the beginning of a transaction.
End Transaction
Identifies the end of a transaction.
Read[a]
Is a request to read a data item a. The request will be satisfied according to the chosen locking policy.
Write[a]
Is a request to write a data item a. The request will be satisfied according to the chosen locking policy.
Request Commit
Is invoked by a subtransaction as soon as it successfully terminates its execution. Its purpose is to communicate to the parent transaction the intention to commit. Such primitive can be followed only by a Commit or by an Abort operation.
Commit
Is invoked by a subtransaction as soon as it successfully terminates its execution and the parent transaction has already granted the requested commit.
Abort
Is invoked by a subtransaction to roll back the effects of its execution.
Get Signal
Allows a transaction to activate specific actions when lower-level data items previously read by the transaction have been modified by some low-level transactions.
Raise Signal
Allows a transaction to signal high-level transactions that a certain data item has been modified.
5.2 The Primitive Raise Signal A Raise Signal primitive invoked by a transaction has the aim of signaling to high-level transactions that some data items have been modified. Thus, when a transaction invokes the Raise Signal primitive, it must be determined which data items have been modified by the transaction, and this information be communicated to high-level transactions, holding or retaining a signal lock on those data, when these transactions invoke the Get Signal primitive.5 By suitably using the Get Signal primitive, such transactions can then execute appropriate actions to recover from the situation. Information about notified data items is inherited by the parent transaction when a subtransaction commits. In order to determine all the data items that have been modified by the transaction invoking the Raise Signal primitive, we use the following approach. If the subtransaction executing the Raise Signal is a leaf transaction, then it has directly written data items. Thus, written data items can be determined by examining the write locks held by that leaf. In contrast, if the subtransaction is 5 The
system components in charge of performing such operations, as well as those related to the execution of the Get Signal primitive, are described in Section 9.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
341
Table III. Primitives Invoked by Internal Transactions Only Primitive
Meaning
Blocking Par Create[Tset]
Invoked by a transaction to create a blocking subtransaction Ti for each Ti ∈ Tset. All transactions in Tset are executed concurrently.
Blocking Seq Create[Ti ,Tset]
Invoked by a transaction to create a blocking subtransaction Ti , to be executed after the executions of the subtransactions belonging to Tset.
NonBlocking Par Create[Tset]
Invoked by a transaction to create a nonblocking subtransaction Ti , for each Ti ∈ Tset. All transactions in Tset are executed concurrently.
NonBlocking Seq Create[Ti ,Tset]
Invoked by a transaction to create a nonblocking subtransaction Ti , to be executed after the executions of the subtransactions belonging to Tset.
Grant Commit[Ti ]
Invoked by a transaction to grant the commit to a child transaction Ti .
Force Abort[Ti ]
Invoked by a transaction to force the abort of a child transaction Ti .
Fig. 5. An example of Raise Signal invocation, where transactions T5 , T6 , T7 , and T8 have terminated their execution.
internal, it does not directly write data items. In this case, we consider all data items that have been modified by committed subtransactions belonging to the subtree rooted at the transaction executing the Raise Signal. Since, when a subtransaction commits, the parent retains all the locks it held or retained, to determine such data items it is sufficient to consider all the write locks retained by the transaction executing the Raise Signal. Example 6. Consider transactions T1 and T2 in Figure 5. Suppose that L(T1 ) = high, L(T2 ) = low, and low < high. The figure represents the following ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
342
•
E. Bertino et al.
situation. Transaction T1 has created two blocking subtransactions, T3 and T4 , concurrently executed, whereas T3 has created two additional blocking subtransactions, T5 and T6 , sequentially executed. T5 has acquired a write lock on data item c, T6 has acquired a signal lock on data item b, and T4 has acquired a signal lock on data item a. Moreover, T5 and T6 have already requested the commit (in the figure this is indicated by dashed circles). Therefore, transaction T3 has inherited a write lock on c and a signal lock on b. Transaction T2 has created two nonblocking subtransactions, T7 and T8 , concurrently executed. T7 has acquired a write lock on a, whereas T8 has acquired a write lock on b. Both subtransactions have already terminated their execution. Therefore, transaction T2 has inherited a write lock on both a and b. In this situation, suppose now that T2 executes Raise Signal. The data items modified by the transactions in the subtree rooted at T2 must be detected and high-level transactions holding or retaining signal locks on these data items must be notified. Since at the time of the Raise Signal invocation, T2 retains a write lock on both a and b, all high-level transactions holding or retaining a signal lock on such data are notified. In this example, subtransactions T3 and T4 are notified of the modification. 5.3 The Primitive Get Signal Primitive Get Signal allows a transaction to perform specific actions when lower-level data on which it holds or retains a signal lock is modified. Examples of actions are the abort of (some) of its children, or the creation of a new transaction to read the overwritten data again. When a transaction invokes a Get Signal call, it must be verified whether the data items on which the transaction has a signal lock have been modified by a low-level transaction (such a check is equivalent to verifying which data item a modification was notified for as a consequence of a Raise Signal execution). If the transaction invoking the Get Signal primitive is a leaf transaction, the task is easy, and corresponds to determining the signal locks held by the transaction for which a modification of the corresponding data item was notified. By contrast, when the transaction is internal, the task is more difficult, since an internal transaction does not directly execute read operations. In this case, we need to consider the signal locks that are retained by the transaction. We assume that when a lock is released to the parent, the identifier of the transaction releasing the lock is maintained by the parent, together with the lock mode (i.e., write, read, signal). Therefore, when a Get Signal primitive is executed, the subtransactions that have read the modified data can be easily determined. At this point, the parent can decide to abort these subtransactions, and/or to create new transactions, or to perform other actions in response to the Get Signal result. To support this, we associate each Get Signal call with two exit points: —a default, which is the next instruction in the transaction code after the Get Signal instruction; —an exceptional continuation, which allows specific actions to be performed against the child transactions. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
343
Fig. 6. An example of Get Signal invocation where transactions T3 , T4 , T5 , and T6 have terminated their execution.
The default exit point is activated when no read data items have been modified by low-level transactions. The exceptional exit point is activated in the opposite case. In order to activate the exceptional exit point, each nonleaf transaction Ti is associated with an handler list htr idi1 → handleri1 , . . . , tr idin → handlerin i, where tr idi j is the identifier of a child of Ti , and handleri j is a piece of code to be executed when some of the modified data items have been read by transaction tr id i j , j = 1, . . . , n. Note that the list associated with a transaction may not contain the identifiers of all its children or may contain an identifier with an empty handler. In the first case, the default action is to roll back the transaction that does not appear in the list. By contrast, if the list contains a transaction identifier tr id in with an empty handler, no action is executed against tr id in . In case of a leaf transaction, the Get Signal call has two exit points: a default one, which is similar to the one for nonleaf transactions, and an exceptional continuation, which relies on the definition of a handler list. For leaf transactions, the list can either be empty, meaning that the transaction must be rolled back, or it must have the form htr idi →), meaning that no action has to be executed. The following example clarifies Get Signal behavior. Example 7. Consider transaction T1 presented in Figure 6. Such transaction coincides with transaction T1 presented in Figure 5 by assuming that transactions T3 and T4 have already successfully terminated their execution, and thus their locks have been inherited by T1 . Suppose that the modification of data items a and b has been notified to T1 . In this situation, suppose that T1 invokes the Get Signal primitive. Since both a and b have been modified, an exceptional continuation is activated. This means that, since subtransaction T3 has previously read data item b and subtransaction T4 has previously read data item a, the handlers associated with such transactions in the handler list associated with T1 are executed. The handler associated with T4 requires forcing the abort of this transaction and re-executing it as a blocking child. On the other hand, no code is associated with transaction T3 . Hence, no action is executed against it. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
344
•
E. Bertino et al.
5.4 Raise Signal and Get Signal Usage The Raise Signal and the Get Signal primitives are not sufficient to avoid non-serializable executions. The problem of nonserializability is twofold. On the one hand, there is the problem of write operations performed by nonblocking child transactions that have not yet committed at the time their parent invokes the Raise Signal primitive. This implies that some transactions may have read data items that were then modified by some low-level transactions without being informed by the system that such data items were modified. On the other hand, in case of concurrent executions of parent and child transactions, some broken signal locks associated with some noncommitted subtransactions may not be identified. This happens when the parent transaction executes the Get Signal primitive before all child transactions have completed their execution. In this case, some child transactions may have read modified data, but the parent transaction cannot apply any action to them because it is not yet notified of this read operation. Example 8. Consider the transactions in Figure 5, but suppose that subtransaction T8 has not terminated its execution when transaction T2 invokes the Raise Signal primitive. In this case, when the Raise Signal primitive is executed by T2 , T2 does not retain any lock on b. Therefore, only subtransaction T4 is notified. However, if subtransaction T8 commits, the value of b read by T3 may not coincide with the value of b at the time of the Raise Signal execution, and this may generate some serializability problems. Example 9. Consider again the transaction represented in Figure 6, but suppose that transactions T3 and T4 are nonblocking, and only the execution of subtransaction T3 is terminated when transaction T1 invokes the Get Signal primitive. In this case, T1 only retains a signal lock on data item b. Therefore, only the handler associated with T3 is executed. However, T4 has also read data item a that has been modified, but no action is executed against T4 since its execution has not been terminated yet, and therefore T1 has no knowledge about the data items T4 read. This situation may lead to some nonserializable executions. Situations like the ones in Examples 8 and 9 can be avoided by carefully programming the transactions. For instance, a possible solution to the problem illustrated by Example 8 could be that of invoking the Raise Signal primitive after all child transactions terminate their execution. In this way, for each data item modified by a committed subtransaction, the parent transaction retains a write lock, and therefore the notification considers all modified data. Similarly, the problem in Example 9 can be solved by moving the Get Signal call in T1 after the termination of the execution of all its child transactions. In the following sections, we provide formal solutions to such problems by presenting a serializability theory for nested transactions. This theory relies on the formal model for nested transactions introduced in the next section. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
345
6. A FORMAL MODEL FOR NESTED TRANSACTIONS IN A MULTILEVEL ENVIRONMENT As informally introduced in Section 3, a nested transaction is a tree of transactions, which can be either nested or weak flat transactions. Primitives invoked by transactions belonging to a nested transaction must obey a set of rules, imposing a partial order on these operations. Therefore, we formally introduce nested transactions as a partially ordered set. Such a definition can be given in three steps. First, we formally introduce the definition of weak flat transactions (that is, the leaves of the tree), we then give the formal definition of generating transactions. Finally, based on these two definitions, we formally define a nested transaction. A weak flat transaction is defined as follows. Definition 1 (Weak flat transaction). A weak flat transaction Ti is a partial order with ordering relation ¿i , where: (1) Ti ⊆ Ii ∪ {Aborti ,Commiti , Request Commiti } ∪ {Begin Transactioni , End Transactioni }, where Ii belongs to the powerset of {Readi [a], Writei [a] | a is a data item} ∪ {Raise Signali ,Get Signali }; (2) Begin Transactioni ∈ Ti and ∀ p ∈ Ti , p 6= Begin Transactioni , Begin Transactioni ¿i p holds; (3) End Transactioni ∈ Ti and ∀ p ∈ Ti , p 6= End Transactioni , p ¿i End Transactioni holds; (4) Aborti ∈ Ti iff Commiti 6∈ Ti ; (5) if p ∈ Ti , with p = Aborti or p = Commiti , then ∀ p0 ∈ Ti , p0 6= p, p0 6= End Transactioni , p0 ¿i p holds; (6) if Request Commiti ∈ Ti and p ∈ Ti , where p = Aborti or p = Commiti , then 6 ∃ p0 ∈ Ti such that Request Commiti ¿i p0 ¿i p. The first condition in Definition 1 specifies the set of operations composing a weak flat transaction. Conditions 2 and 3 state that a transaction must always start with a Begin Transaction primitive and end with an End Transaction primitive. Condition 4 states that commit and abort are mutually exclusive operations, whereas Condition 5 states that a weak flat transaction must always terminate either with an abort or a commit. Finally, the last condition in Definition 1 imposes that no operation can be executed by a weak flat transaction after a request to commit and before the abort or the commit. Generating transactions differ from weak flat transactions in that they can create new transactions (either blocking or nonblocking) and grant the commit or force the abort of their children. Child transactions can be executed either sequentially or concurrently. Generating transactions can be inductively defined as follows.6 In the definition we make use of the following notation. Let T I be
6 For
convenience, we use Ti to denote both a generic transaction name and the set of operations composing the corresponding transaction.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
346
•
E. Bertino et al.
a set of transaction identifiers, and T1 , . . . , Tn ∈ T I . Then SET TI ({T1 , . . . , Tn }) denotes all the sets of transactions that can be generated from TI \{T1 , . . . , Tn }. Definition 2 (Generating transaction). tifiers. Let
Let TI be a set of transaction iden-
Ei (TI ) = {Grant Commiti [T j ], Force Aborti [T j ], Blocking Par Createi [T set1], Blocking Seq Createi [T j , T set], NonBlocking Par Createi [T set1], NonBlocking Seq Createi [T j , T set] | T j , Ti ∈ TI and T set ∈ SET TI ({T j , Ti }), T set1 ∈ SET TI ({Ti })}. Let W F T be a set of weak flat transaction identifiers. A generating transaction Ti of level n on WFT, n ≥ 1, is a partially ordered set with ordering relation ¿i , such that Ti ⊆ Ji ∪ {Aborti ,Commiti , Request Commiti } ∪ {Begin Transactioni , End Transactioni }, where: —if n = 1, Ji belongs to the powerset of Ei (WFT) ∪ {Raise Signali , Get Signali }; —if n > 1, Ji belongs to the powerset of Ei (WFT ∪ GT n−1 ) ∪ {Raise Signali , Get Signali }, where GT n−1 is the set of generating transactions of level n − 1. From the previous definition it follows that all the children of a generating transaction of level n have at most level n − 1. The execution of a generating transaction must obey a set of rules. In addition to rules 2, . . . , 5 stated for weak flat transactions (cf., Definition 1), other rules are defined, regulating the operations that a generating transaction may perform on its children. These rules are as follows. Rules for generating transactions —a generating transaction, before aborting, has to force the abort of all its children; —each generating transaction has to either force the abort or grant the commit to each child transaction that has not autonomously aborted. Moreover, the creation of a child transaction has to precede the forcing of the abort or the granting of the commit to that transaction; —when a generating transaction issues a commit request, the only operations that can perform before its termination are to grant the commit or force the abort of its children. All these conditions are summarized by the notion of well-formed generating transaction, formally defined as follows. In the following, Tk ∈ chil dren(T j ) is shorthand for T j ∩ {Blocking Par Create j [{T1 , ..., Tk , ..., Tn }], Blocking Seq Create j [Tk , T set], NonBlocking Par Create j [{T1 ,..., Tk , ..., Tn }], NonBlocking Seq Create j [Tk , T set]} 6= ∅. Definition 3 (Well-formed generating transaction). A generating transaction Ti is said to be well-formed if the following conditions hold: ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
347
(1) Begin Transactioni ∈ Ti and ∀ p ∈ Ti , p 6= Begin Transactioni , Begin Transactioni ¿i p holds; (2) End Transactioni ∈ Ti and ∀ p ∈ Ti , p 6= End Transactioni , p ¿i End Transactioni holds; (3) Aborti ∈ Ti iff Commiti 6∈ Ti ; (4) if p ∈ Ti , with p = Aborti or p = Commiti , then ∀ p0 ∈ Ti , p0 6= p, p0 6= End Transactioni , p0 ¿i p holds; (5) if Aborti ∈ Ti , then ∀Tk ∈ children(Ti ), the following conditions hold: Force Aborti [Tk ] ∈ Ti and Force Aborti [Tk ] ¿i Aborti . (6) ∀Tk ∈ children(Ti ), such that opi [Tk ] is the operation creating Tk in Ti , one of the following conditions hold: —Force Aborti [Tk ] ∈ Ti and opi [Tk ] ¿i Force Aborti [Tk ]; —Grant Commiti [Tk ] ∈ Ti and opi [Tk ] ¿i Grant Commiti [Tk ]; —Force Aborti [Tk ] 6∈ Ti , Grant Commiti [Tk ] 6∈ Ti ; (7) if Request Commiti ∈ Ti and ∃ p ∈ Ti such that Request Commiti ¿i p ¿i p0 , where either p0 = Aborti or p0 = Commiti , then p = Grant Commiti [Tk ] or p = Force Aborti [Tk ], where Tk ∈ children(Ti ). We are now ready to introduce the definition of nested transaction as a partial order among operations belonging to the same and different transactions in the nesting. Definition 4 (Nested transaction). Let F be a set of weak flat transactions and let G be a set of generating transactions on F such that ∀Ti ∈ G, ∀T j ∈ children(Ti ), T j ∈ G ∪ F. A nested transaction T on F and G is a partially ordered set, with ordering ¿, such that: T = {op|∃T 0 ∈ F ∪G such that op ∈ T 0 }, and ∀Ti ⊆ F ∪ G, ¿i ⊆ ¿ holds. A nested transaction is well-formed if it is built upon a set of well-formed generating transactions and, additionally, satisfies a set of conditions regulating the interactions between the primitives executed by a subtransaction and those executed by its children. Such rules are as follows: Rules for nested transactions —each nested transaction must contain one and only one generating transaction that is not created by any other transaction (i.e., the root transaction). Root transactions must not execute the Request Commit primitive; —a create operation must always precede the starting of the execution of each generated transaction, and each generated transaction must terminate its execution before the termination of its parent; —if a generating transaction Ti creates a new transaction T , using either the Blocking Seq Createi [T, T set] or the NonBlocking Seq Createi [T, T set] primitive, the execution of each transaction belonging to the T set must terminate before the starting of transaction T ; —a generating transaction before committing must wait for the termination of its children. If a child commits, this implies that it has issued a commit ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
348
•
E. Bertino et al.
request to its parent and such a request has been allowed. By contrast, children can abort either spontaneously or can be forced by their parent; —if a generating transaction aborts, all its children must abort too. The above conditions are summarized by the notion of well-formed nested transaction, formally defined as follows. Definition 5 (Well-formed nested transaction). Let F be a set of weak flat transactions and let G be a set of generating transactions on F. Let T be a nested transaction on F and G. T is well formed if each generating transaction in G is well formed and the following conditions are satisfied: (1) ∃ one and only one Ti ∈ F ∪ G such that ∀Tk ∈ F ∪ G, Ti 6∈ children(Tk ) and Request Commiti 6∈ Ti ; (2) ∀T j ∈ F ∪ G such that ∃Tk ∈ F ∪ G, ∃ p ∈ T j with p ∈ {Blocking Par Create j [{T1 , . . . , Tk , . . . , Tn }], Blocking Seq Create j [Tk , T set], NonBlocking Par Create j [{T1 , . . . , Tk , . . . , Tn }], NonBlocking Seq Create j [Tk , T set]}, the following conditions must be verified: — p ¿ Begin Transactionk ; —∀Th ∈ T set, either Request Commith ¿ Begin Transactionk or Aborth ¿ Begin Transactionk ; (3) if Request Commiti ∈ Ti , Ti ∈ G, then, ∀Tk ∈ children(Ti ), ∃ p ∈ Tk such that p = Request Commitk or p = Abortk and p ¿ Request Commiti . (4) if Aborti ∈ Ti , Ti ∈ G, then ∀Tk ∈ children(Ti ), Abortk ∈ Tk and Abortk ¿ Aborti ; (5) if Commiti ∈ Ti , Ti ∈ G, then ∀Tk ∈ children(Ti ) one of the following conditions hold: —Force Aborti [Tk ] ∈ Ti , Abortk ∈ Tk and Force Aborti [Tk ] ¿ Abortk ¿ Commiti ; —Grant Commiti [Tk ] ∈ Ti , Request Commitk ∈ Tk and Request Commitk ¿ Grant Commiti [Tk ] ¿ Commitk ¿ Commiti ; —Force Aborti [Tk ] 6∈ Ti , Grant Commiti [Tk ] 6∈ Ti , Abortk ∈ Tk , and Abortk ¿ Request Commiti . In the following, we only deal with well-formed generating and nested transactions and, for the sake of simplicity, we simply call them generating and nested transactions. Moreover, we consider nested transactions in a multilevel environment, that is, we assume that each nested transaction has an associated security level. The security level of a transaction is equal to the security level of all its children. A nested transaction can also be seen as a tree, called a transaction tree, where each internal node is a generating transaction, each leaf is a weak flat transaction, and an edge connects a generating transaction Ti with a transaction created by Ti . Therefore, there are as many edges from Ti as there are transactions that have been created by Ti . Definition 6 (Transaction tree). Let T be a nested transaction. The transaction tree associated with T , denoted tree(T ), is a tree whose internal nodes ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
349
are generating transactions created by T and whose leaves are weak flat transactions created by T . An edge connects a generating transaction Ti with a transaction created by Ti . The nodes of the tree are denoted by nodes(T ) and the leaves by leaves(T ). We use notation parentT (Ti ) to denote the parent transaction of Ti in T , and ancestorsT (Ti ) to denote the set of ancestors of Ti in T (parent and Ti included).7 7. SERIALIZABILITY THEORY FOR NESTED TRANSACTIONS IN A MULTILEVEL ENVIRONMENT In this section we present a serializability theory for nested transactions in a multilevel environment. Our theory extends the serializability theories developed for flat [Gray and Reuter 1993] and nested transactions [Moss 1985], to take into account the interactions among operations executed at different security levels, and is based on the formal model for nested transactions introduced in Section 6. In the following, we consider the general framework for proving serializability of nested transactions proposed in Halici et al. [1997], and we cast this framework in the context of multilevel security. Then, on this basis, we present our serializability results. The framework proposed in Halici et al. [1997] is based on the notion of ordered hierarchy. The idea is the following. When a nested transaction is executed, the subtransactions that conflict on the same data item must be ordered in such a way that the order of their conflicting operations is preserved. Moreover, when two subtransactions are ordered, they impose an order between their parents. The use of ordered hierarchies provides an elegant way to model an order within a tree. The important result in Halici et al. [1997] is that if the order used to build the hierarchy is a partial order, then the hierarchy is serializable. In the following, we first summarize the framework proposed in Halici et al. [1997]. We then prove serializability of the locking protocol introduced in Section 4, first for nested transactions all having the same security level and then for nested transactions with different security levels. It is important to note that, differently from the nested transaction model in Halici et al. [1997], we allow concurrent execution between parent and child transactions. In presenting such results, we assume an imaginary root dummy transaction for all submitted transactions, with no associated security level. Thus, a set of nested transactions can always be seen as a single transaction, and thus a single tree. Note that, from a formal point of view, the dummy transaction must create each transaction belonging to the set, and each Commit executed by a child transaction must be transformed into an invocation of the Request Commit primitive. The dummy transaction always commits after all its children have terminated, thus confirming the results (abort or commit) generated by each single transaction. As usual in concurrency control theory, we consider only executions of committed transactions. This means that, in the context of a committed nested 7 The
last condition simplifies the following discussion. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
350
•
E. Bertino et al.
transaction, we do not consider the execution of the subtransactions that have aborted. 7.1 Ordered Hierarchies and Serializability An ordered hierarchy is defined as follows. Definition 7 (Ordered hierarchy) [Halici et al. 1997]. Let T be a nested transaction. An ordered hierarchy for T is a pair (T , →), where T = nodes(T ) and → is a nonreflexive and antisymmetric relation on nodes(T ), satisfying the following axioms:8 Axiom 1. parent-child order: ∀Ti ∈ T , Ti → parentT (Ti ) holds; Axiom 2. transitivity: ∀Ti , T j , Tk ∈ T such that Ti → T j and T j → Tk , Ti → Tk holds; Axiom 3. delegation: if T j → Ti , the following conditions hold: (a) if parentT (T j ) 6∈ ancestorsT (Ti ), then parentT (T j ) → Ti ; (b) if parentT (Ti ) 6∈ ancestorsT (T j ), then T j → parentT (Ti ). An ordered hierarchy H = (T , →) is said to be partially (resp. totally) ordered iff the relationship obtained from → by considering reflexivity, denoted →, is a partial (resp. total) order on T . The first axiom in Definition 7 above imposes an order on the execution of transactions related by the parent-child relation, that is, it requires that children always terminate before their parents. Axiom 2 states that termination relation is transitive, whereas axiom 3 propagates the effect of the termination order between two nodes up in the hierarchy. Example 10. Figure 7 presents an example to clarify the delegation axiom. In the figure, ordering relationships implied by the delegation axiom are represented as dashed lines. Suppose that T4 → T6 . According to axiom 3, such ordering is propagated upwards as follows. By condition (a) of the delegation axiom, T2 → T6 , since T2 is the parent of T4 and it is not an ancestor of T6 . Additionally, by condition (b) of the delegation axiom, T4 → T3 , since T2 is not an ancestor of T6 . Furthermore, the relation T2 → T6 implies, by condition (b) of the delegation axiom, that T2 → T3 , since T3 , i.e., the parent of T6 is not an ancestor of T3 . By contrast, condition (a) of the delegation axiom does not generate any upwards relation since T1 ; i.e., the parent of T2 is an ancestor of T6 . No new relations are implied by T4 → T3 . Therefore, the resulting hierarchy is the one in Figure 7. To define serializability, it is useful to introduce the concept of hierarchy restriction. Given an ordered hierarchy, a hierarchy restriction is a portion of the hierarchy containing part of a subtree rooted at a given node. Definition 8 (Hierarchy restriction) [Halici et al. 1997]. Let T be a nested transaction and let (T , →) be an ordered hierarchy for T . Let Ti ∈ nodes(T ). 8 Note that we have reversed the order of relation → with respect to that in Halici et al. [1997], to be
consistent with the graphical notation used in representing nested transactions (see Example 3). ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
351
Fig. 7. An example of application of the delegation axiom.
Let treer (Ti ) be a subtree of tree(Ti ) rooted at Ti and such that leaves(treer (Ti )) ⊆ leaves(tree(Ti )). A restriction Hir of the ordered hierarchy H with respect to transaction Ti is a pair (S, →ri ), where S is the set of transactions (nodes) composing treer (Ti ), and →ri is the restriction of → to S. If S is equal to the set of transactions composing Ti , then the restriction is denoted (Ti , →i ), Ti being the set of transactions (nodes) composing Ti , and is called a subhierarchy of (T , →) with respect to Ti . For instance, with reference to Figure 7, the subtree rooted at transaction T2 is a subhierarchy with respect to T2 . It is easy to prove that a restriction of an ordered hierarchy satisfies the conditions stated in Definition 7. PROPOSITION 1 [Halici et al. 1997]. tion of H is also a hierarchy.
Given an ordered hierarchy H, a restric-
The following definition introduces the concept of isolated subhierarchy as a subhierarchy in which the → relations that may occur between transactions belonging to two distinct subtrees must always have the same direction. This means that all transactions contained in a given subtree have always to be executed before or after the execution of all the transactions belonging to the other subtree. Definition 9 (Isolated subhierarchy). Let Hi = (Ti , →i ) be a subhierarchy of an ordered hierarchy H = (T , →) with respect to transaction Ti . Hi is said to be isolated in H iff ∀Ti1 , Ti2 ∈ Ti and ∀Tl 1 , Tl 2 ∈ T \Ti \ancestorsT (Ti ) at least one relationship between Ti1 → Tl 1 Tl 2 → Ti2 does not hold. It is easy to see, with reference to Figure 7, that the tree rooted at T2 is an isolated subhierarchy. The notion of isolated subhierarchy can be extended as follows. Definition 10 (Hierarchically isolated subhierarchy) [Halici et al. 1997]. Let Hi be an isolated subhierarchy in an ordered hierarchy H. Hi is said to be hierarchically isolated in H iff every subhierarchy of Hi is isolated in H. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
352
•
E. Bertino et al.
Fig. 8. Examples of isolated and hierarchically isolated subhierarchies.
Example 11. Consider Figure 8.9 The subhierarchy rooted at T2 is isolated, but not hierarchically isolated, since the subhierarchy rooted at T4 is not isolated. By contrast, the subhierarchy rooted at T3 is an example of hierarchically isolated subhierarchy. A serial hierarchy is a totally ordered hierarchy in which each subhierarchy is isolated. Thus, all nodes of the tree are ordered and each subtree satisfies the isolation condition. Definition 11 (Serial hierarchy) [Halici et al. 1997]. An ordered hierarchy H = (T , →) is said to be serial if H is hierarchically isolated and → is a total order. Serial hierarchies are the key notion for defining serializability. Definition 12 (Serializable hierarchy) [Halici et al. 1997]. An ordered hierarchy H = (T , →) is said to be serializable if there exists a serial hierarchy H + = (T , →+ ) such that →⊆→+ . From the previous definitions, it is quite immediate to prove the following result. THEOREM 1 [Halici et al. 1997]. is a partial order.
An ordered hierarchy H is serializable iff →
By using ordered hierarchies, it is possible to prove the serializability of nested transactions. The proof is based on the following considerations. We first define an ordering between the nodes of the nested transaction and 9 For
the sake of simplicity, in the figure, we do not report relations derived by axioms 2 and 3 of Definition 7.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
353
prove that this ordering makes the tree an ordered hierarchy. This ordering is based on the order of the execution of conflicting operations. Theorem 1 can then be used to check serializability. Conflicting operations are defined as follows. Definition 13 (Conflicting operations). Two operations conflict if one of them is a write operation, they operate on the same data item, and they belong to different nodes of the tree (hence they are executed by different subtransactions). The ordering between transaction nodes can be formalized by introducing the concept of execution history [Halici et al. 1997]. Such history describes the order in which different subtransactions have to be executed in a serial scheduler in the context of the same nested transaction execution. With respect to Halici et al. [1997], where the execution ordering is not formally specified, the ordering we introduce is defined by taking into account the execution of conflicting operations, the parent-child order, the ordering existing between subtransactions sequentially executed, and the ordering induced by locking rules. The aim is to check whether the execution histories for nested transactions following the locking protocol in Section 4 are always partially ordered. This fact, due to Theorem 1, guarantees that the protocol is serializable. Note that the execution histories introduced in Halici et al. [1997] do not explicitly consider locking rules, since they deal with a general theory of serializability and not with the proof of serializability of a given locking protocol. Before presenting the notion of execution history, we introduce a particular ordering for the nodes of a given nested transaction tree, which keeps in account all the aspects mentioned above; we use such ordering to define the execution history. Execution ordering is formally defined in what follows. In the definition, the symbol ∗ is used to denote the closure with respect to the ordered hierarchy axioms (cf., Definition 7). Definition 14 (Execution ordering). Let F be a set of weak flat transactions and let G be a set of generating transactions on F. Let T be a nested transaction on F and G. An execution ordering on T, denoted by →, is defined as (→op ∪ →pol )∗ , where →op is the ordering relation defined by the ordering of the execution of conflicting operations, and →pol is the ordering defined by the execution strategy; that is, →pol = →child ∪ →seq ∪ →lock . Relations →op , →child , →seq , and →lock are defined as follows: (1) ∀Ti , T j ∈ F ∪ G such that Ti , T j are weak flat transactions, Ti →op T j holds if Ti accesses a data item before T j , and either Ti or T j execute a write operation on that data item. (2) ∀Ti ∈ F ∪ G, ∀Tk ∈ children(Ti ), Tk →child Ti holds. (3) ∀Ti , T j , Tk ∈ F ∪ G such that {Blocking Seq Createk (T j , {...Ti ...}), NonBlocking Seq Createk (T j , {...Ti ...})} ∩ Tk 6= ∅, ∀Tm ∈ tree(Ti ), ∀Tn ∈ tree(T j ), Tm →seq Tn holds. (4) Let Ti →op T j . If the operations executed by Ti and T j are not compatible with respect to the locking protocol (that is, they require the acquisition of ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
354
•
E. Bertino et al.
incompatible locks), then ∀Tk ∈ ancestorsT (Ti )\ancestorsT (T j ), and ∀Tl ∈ ancestorsT (T j )\ancestorsT (Ti ), Tk →lock Tl holds. From the above definition, it follows that Ti →pol T j holds if Ti and T j are either weak flat or generating transactions and, due to the execution policy, Ti has to be executed before T j in the context of the nested execution. Moreover: →child specifies that a parent has to wait for the termination of its children before terminating; →seq specifies the ordering between sequentially executed transactions; →lock specifies the ordering between transactions imposed by the locking protocol. From the previous definition, it is simple to prove that →lock is redundant in defining →. A similar consideration holds for →child . Thus, the following proposition holds. PROPOSITION 2.
(→op ∪ →pol )∗ = (→op ∪ →seq )∗ .
PROOF. Let F be a set of weak flat transactions and let G be a set of generating transactions on F. Let T be a nested transaction on F and G. Consider first the →child relation. We have to prove that ∀Ti , T j ∈ F ∪ G, if Ti →child T j , then Ti → T j , where → = (→op ∪ →seq )∗ . By Definition 14, if Ti →child T j , then Ti is a child of T j . Thus, by applying the first axiom of Definition 7 to (→op ∪ →seq ), we have Ti → T j ; and this proves the thesis. Now consider the →lock relation. By Definition 14, if Ti →lock T j , then there exists a descendant Tk of Ti and a descendant Th of T j such that Tk →op Th . Thus, by repeatedly applying axiom 3 of Definition 7 to (→op ∪ →seq ), we have Ti → T j ; and this proves the thesis. The next definition introduces the concept of execution history. Definition 15 (Execution history). Let T be a nested transaction. An execution history over T is an ordered hierarchy H = (T , →), where → is an execution ordering on T . Finally, to present serializability results, we need to introduce the concept of serialization graph. Definition 16 (Serialization graph). Let T be a nested transaction. Let H = (T , →) be an execution history over T . The serialization graph for H is a direct graph with nodes(T ) as nodes and whose edges are all the pairs (Ti , T j ) such that Ti → T j . 7.2 Serializability of Nested Transactions with the Same Security Level The locking protocol introduced in Section 4 guarantees serializability for nested transactions all with the same security level (from now on we call these transactions single-level nested transactions). We recall that a set of nested transactions can always be seen as a single transaction, by using a root dummy transaction connecting all the transactions in the set. In this case, ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
355
we obtain a unique transaction that we call single-level, since all the transactions composing it (except for the root) have the same security level. To show that the locking protocol is serializable, we have to prove that given →= (→op ∪ →seq )∗ , → is a partial order for any execution history over a singlelevel transaction. In order to prove serializability, it is also important to point out that, for single-level nested transactions, Ti →op T j holds if and only if a conflict occurs between Ti and T j , and T j cannot acquire a lock until Ti releases its lock. Indeed, if Ti →op T j holds, then either Ti reads a data item and T j wants to write the same data item, or Ti writes a data item and T j wants to read it. In both cases, T j cannot acquire the lock. This means that, for single-level nested transactions, the serializability graph coincides with a waiting graph [Gray and Reuter 1993]. Starting from this consideration, serializability can be proved, as follows: THEOREM 2. Let F be a set of weak flat transactions and G be a set of generating transactions on F. Let T be a single-level nested transaction on F and G. Let H = (T , →) be an execution history over T . H is serializable. PROOF. Suppose that H is not serializable. This means that there exists Ti ∈ F ∪ G such that Ti → Ti , and therefore the serialization graph for H contains a cycle. Since, for single-level transactions, the serialization graph corresponds to a waiting graph [Gray and Reuter 1993], and since the graph is cyclic, a deadlock occurs. But this leads to a contradiction, since it means that T does not terminate, and thus it does not commit. Hence H is serializable. 7.3 Serializability of Nested Transactions with Different Security Levels The locking protocol introduced in Section 4 does not guarantee the serialization of nested transactions with different security levels (denoted multilevel transactions in the following), as the following example shows. Example 12. Let T1 and T2 be two concurrently executed nested transactions such that L(T1 ) = high, L(T2 ) = low, and low < high (see Figure 9(a)). Transaction T1 consists of two subtransactions T3 and T4 , concurrently executed. On the other hand, transaction T2 consists of a single subtransaction T5 . All the subtransactions are assumed to be nonblocking. Now suppose that T3 reads data item a such that L(a) = low. Before reading a, T3 acquires a signal lock on it. After the read operation, suppose that T5 wants to write the same data item a. The two operations do not conflict, therefore T5 can write the data item. Now suppose that T4 wants to read data item a. This operation is in conflict with the write operation performed by T5 , and therefore it will be executed only when T5 releases the lock. These relationships between conflicting operations correspond to relation →op . By repeatedly applying all the axioms of an ordered hierarchy, we obtain the execution ordering represented in Figure 9(b) (the lines representing concurrent executions have been removed for the sake of clarity). A cycle arises, and hence the execution is not serializable. The problem is that, during the same execution, two subtransactions created by the same transaction T1 read different values for the same data item a (transaction T4 ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
356
•
E. Bertino et al.
Fig. 9. An example of nonserializable execution.
must wait for the commit of T2 before reading the data item). A possible solution to this problem is notifying the modification of a by invoking the Raise Signal primitive by transaction T2 or T5 , and to roll back transaction T3 by invoking the Get Signal primitive by transaction T3 or T1 . As Example 12 shows, nonserializability of multilevel nested transactions is due to conflicts between transactions having different security levels (the write operation executed by T5 in the example cannot be delayed, otherwise a timing channel may arise). However, we can devise a set of conditions on the structure of multilevel nested transactions that ensure their serializability. Such rules follow: Rules for multilevel nested transactions —Each modification of a data item performed by a transaction must be followed by the invocation of the primitive Raise Signal, so that high-level transactions having a signal lock on that data item are notified of the modification. The Raise Signal can be invoked either by the transaction that has modified the data item or by one of its ancestors. In the latter case, it is required that the write operation that caused the modification of the data item belongs to a subtree rooted at one of the children of the transaction that invokes the Raise Signal, and that such a child has already committed when ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
357
the Raise Signal is invoked. In this way we are sure that the modifications performed on the data item is made known to high-level transactions. —A transaction that has read a modified data must be rolled back. This can be achieved by requiring that each read operation on a lower-level data item executed by a leaf transaction is followed by the execution of the Get Signal primitive by one of its ancestors. At that point, the rollback of the transaction that has performed the read operation is obtained by requiring that the handlers (if any) in the handler list of the transaction calling the Get Signal primitive contain an abort operation. These conditions are formalized by the notion of correct multilevel nested transaction, defined as follows: Definition 17 (Correct multilevel nested transaction). Let F be a set of weak flat transaction and let G be a set of generating transactions on F. Let T be a multilevel nested transaction on F and G. T is correct if the following conditions hold: (1) ∀Ti ∈ F ∪ G, ∀ data item a such that Writei [a]∈ T , ∃T j ∈ F ∪ G such that T j ∈ ancestorsT (Ti ), Raise Signal j ∈ T and Writei [a] ¿ Raise Signal j . Moreover, one of the following conditions must be satisfied: T j = Ti ; ∃Tk ∈ F ∪ G such that T j = parentT (Tk ), Tk ∈ ancestorsT (Ti ) and Tk has committed. (2) ∀Ti ∈ F, ∀ data item a such that Readi [a]∈ T , ∃T j ∈ F ∪ G such that T j ∈ ancestorsT (Ti ), Get Signal j ∈ T j and Readi [a] ¿ Get Signal j . (3) ∀Ti ∈ F ∪ G such that Get Signali ∈ Ti , each handler contained in the list (if any) associated with Ti must contain at least an abort operation for the transaction to which it is associated. (4) Let T ∗ be the root of tree(T ). The last instruction of T ∗ before executing the commit must be the invocation of Get Signal. The last condition in Definition 17 above ensures that a transaction that has read a modified data is always rolled back. To understand why this condition is required consider once again the transactions in Example 12, and suppose that transaction T1 invokes the Get Signal primitive after T3 has read data item a and before T5 modifies a. In this case the Get Signal invocation by T1 does not produce any effect, since no signal lock has been broken at the time T1 invokes the Get Signal primitive. Now suppose that, after the Get Signal invocation by T1 , T5 modifies a and invokes the Raise Signal primitive. In this case, conditions 1, 2, and 3 of Definition 17 are satisfied, but the concurrent execution of T5 and T1 is not serializable (cf., Figure 9). The problem is that the modification of a by T5 does not cause the rollback of T3 , since the notification of the modification of a is lost because the Get Signal primitive is invoked by T1 before the execution of the Raise Signal primitive by T5 . Condition 4 in Definition 17 avoids this problem by requiring that the last instruction of the root transaction be an invocation of Get Signal. In this way no notification of broken signal locks can be lost. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
358
•
E. Bertino et al.
The following theorem guarantees serializability for correct multilevel nested transactions. THEOREM 3. Let F be a set of weak flat transactions and let G be a set of generating transactions on F. Let T be a correct multilevel nested transaction on F and G. Let H = (T , →) be an execution history over T . H is serializable. PROOF. If the transactions in T all have the same security level, by Theorem 2, H is serializable, which proves the thesis. By contrast, suppose that transactions in T have different security levels and suppose, by contradiction, that H is not serializable. This means that there exists Ti ∈ F ∪ G such that Ti → Ti , and thus the serialization graph for H contains a cycle. Two cases may arise: (1) If all the transactions involved in the cycle have the same security level, using the same reasoning we used for the proof of Theorem 2, we can conclude that this implies that a deadlock occurs. Thus, transaction T does not commit, which leads to a contradiction. (2) If the transactions belonging to the cycle have different security levels, additional cycles (with respect to the single-level case) can be caused only by signal locks (which, unlike read locks, do not prevent write operations). We have seen that, in the case of single-level transactions, Tk →op Th always implies a lock conflict between Tk and Th . Therefore, additional cycles, with respect to the single-level case, exist only if there exist two transactions Tk ,Th ∈ F ∪ G with different security levels, such that Tk →op Th holds, but no conflict exists between Tk and Th from a locking point of view (that is, neither of the two transactions must wait for the other to release a lock to proceed in the computation). Due to the chosen locking protocol, this is only possible if Tk and Th access the same data item a, Tk accesses the data item before Th , Tk has a signal lock on a, and Th has a write lock on a. This also means that L(a) = L(Th ) < L(Tk ). Since, by hypothesis, transaction T is correct, upon the modification of data item a by transaction Th , Th , or one of its ancestors, invokes the Raise Signal primitive. Moreover, by Definition 17, there exists an ancestor of Tk that executes the Get Signal primitive after both the Raise Signal invocation by Th (or by one of its ancestors) and transaction Tk commit (by point 4 of Definition 17 such ancestor is, in the “worst case”, the root). This implies, by point 3 of Definition 17, that transaction Th is rolled back. Thus, the edge Tk →op Th is removed from the serialization graph, and this deletion removes the cycle. Thus, a contradiction arises, which proves the thesis. From the previous result, it follows that the correctness properties are sufficient to guarantee serializability for nested transactions in a multilevel environment. 8. SECURITY ANALYSIS In this section we analyze the security of the locking protocol in this article. Proving the security of this protocol means proving that the concurrent ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
359
execution of transactions according to such a protocol does not introduce any covert channels. Such requirements can be restated in a simpler and intuitive way, according to the notion of noninterference [Goguen and Meseguer 1982]: the execution of high-level transactions should not introduce (observable) interference from a higher-level to a lower-level subject or between subjects at incomparable security levels. This means that, if we denote by p a sequence of actions from several subjects, and with pl the sequence obtained from p by removing all the actions performed by subjects whose security level is not dominated by the security level l , then a subject classified at level l must not be able to distinguish the behavior of the system in response to p from the behavior of the system in response to pl . In our nested transaction model, the above principle can be formulated in terms of execution histories by requiring that any execution that satisfies the execution ordering associated with an execution history will not lead to interference between higher and lower levels or between incomparable levels. This requirement is formalized by the concept of secure execution histories, defined as follows: Definition 18 (Secure execution history). Let T be a nested transaction and let H = (T , →) be an execution history over T . H is secure if ∀l 1 , l 2 ∈ L, such that l 1 6≺ l 2 , any execution of T satisfying the execution ordering → does not introduce (observable) interferences from subjects at level l 2 to subjects at level l 1 . We are now ready to prove the security of multilevel transaction executions according to our locking protocol. THEOREM 4. Let F be a set of weak flat transactions and let G be a set of generating transactions on F. Let T be a multilevel nested transaction on F and G. Let H = (T , →) be an execution history over T . H is secure. PROOF. To prove the theorem, we use the theoretical framework for analyzing the security of concurrency control protocols proposed by Thomas and Sandhu [1993]. They showed that noninterference from high to low transactions (or from transactions at incomparable security levels) can be proved by analyzing the commit dependencies among such transactions; that is, proving the absence of commit dependencies establishes that the concurrency control protocol does not compromise security. A commit dependency [Thomas and Sandhu 1993] between a transaction T1 and a transaction T2 holds, if T1 cannot commit until T2 terminates (i.e., either aborts or commits). Thus, proving the thesis is equivalent to proving that any execution of T satisfying the execution ordering → is low-dependency-free [Thomas and Sandhu 1993]; that is, ∀Tk ,Th ∈ F ∪ G, L(Th ) 6≺ L(Tk ), no commit dependencies between Tk and Th can develop. We suppose that the thesis does not hold and derive a contradiction. Hence, we suppose that there exists an execution of T satisfying the execution ordering → and a pair of transactions Tk ,Th ∈ F ∪ G such that L(Th ) 6≺ L(Tk ) and Tk is commit-dependent from Th . We assume that L(Tk ) ≺ L(Th ), since the proof for incomparable levels is analogous. In Thomas and Sandhu [1993], it is proved that commit dependencies between Tk and Th can be established only if there exists a data item a with the same level as Tk such that Th requires a read ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
360
•
E. Bertino et al.
operation on a, followed by a request for a write operation on a by Tk . In Thomas and Sandhu [1993] it is proved that commit dependencies caused by other configurations of read and/or write operations cannot arise, since they violate the Bell and LaPadula policy. In the above situation, the commit dependency is established if the commit of Tk has to be delayed until Th commits. By Definition 14, this can happen only if Tk →lock Th . Indeed, the only other commit dependencies that can arise in our nested transaction model are those due to the parent-child relationships. However, such dependencies cannot be established between Tk and Th since, by hypothesis, L(Tk ) 6= L(Th ), whereas the security level of a transaction should be equal to that of its children. If Tk →lock Th holds, this means that the operations performed on a by transactions Th and Tk are not compatible with respect to the locking protocol; that is, Th and Tk require incompatible locks on data item a. However, the operations requested by Th and Tk do not establish a →lock dependency between the two, since Th acquires a signal lock on data item a to perform the read operation. This lock does not conflict with the write lock subsequently requested by Tk on data item a to perform the write operation. This means that Tk →lock Th does not belong to H. Thus, a contradiction arises, which proves the thesis. 9. THE ARCHITECTURE AND THE EXECUTION MODEL In the following, we discuss the architecture on which the concurrency control protocol we have presented in this article relies. We then describe the behavior of the various architectural components, by sketching their implementation. 9.1 The Basic Architecture Our approach to concurrency control of nested transactions in a MLS/DBMS is based on the architecture shown in Figure 10, in which, as an example, we assume four security levels (i.e., Top Secret, Secret, Confidential, and Unclassified). The architecture consists of two trusted components.10 This requires the trusted lock manager (TLM) and the trusted file manager (TFM), and a passive component, the file store, which is physically partitioned according to the security level. The architecture also contains an untrusted component, represented by a set of transaction managers (TMs), one for each security level. Each of the above components cooperates in obtaining the secure concurrent execution of transactions. Note that the assumption about the trusted TLM can be relaxed easily by providing one TLM for each security level, similarly to TMs. However, as pointed out in Gray and Reuter [1993], the whole body of a standard lock manager comes to about a thousand lines of actual code, and therefore it is easily verifiable, making quite reasonable the overhead required to deal with a trusted lock manager. Thus, the assumption of a trusted lock manager is justified. For additional information concerning this issue, see Bertino et al. [1998]. The TLM is in charge of implementing the secure 2PL protocol that we described in Section 4. Its main functionality is to provide basic operations for 10 A component is trusted if its software operates flawlessly for the system to enforce the security policy correctly. This requires developing a formal specification of the component software and a demonstration that the implemented system is consistent with the specification.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
361
Fig. 10. System architecture, showing the levels: top secret, secret, confidential, and unclassified.
locking and unlocking data items so that the secure concurrent execution of transactions is ensured. The TM at a given security level l is responsible for the correct concurrent executions of all transactions at level l . When a transaction at level l wishes to perform a read or write operation on a data item, the TM at level l sends an appropriate lock request to the TLM. When the TLM acknowledges the setting of the lock to the TM at level l , the TM sends the write/read request to the TFM. The functionalities of the TLM should be designed and implemented so that each request from a TM at a level l is served transparently by the TLM with respect to low-level transactions. The TFM manages the physical access to data items. Note that, although we use the term trusted file manager, this component does not need to be fully trusted. In Irvine [1995]; Irvine et al.[1990]; and Schaefer and Walsh [1988] some approaches are presented for implementing a TFM that requires only a small trusted computing base as its only trusted component. To prevent covert channels, we require that the TFM provide file services to transactions at a particular level transparently to all low-level transactions. This implies that when a transaction requires an operation (such as a read or write) on lower-level data items, the TFM must execute the operation in such a way that the utilization of any system resource is not observable by low-level transactions (see Irvine [1995]; Irvine et al. [1990]; and Schaefer and Walsh [1988] for more details on this topic). Note that the interactions among the TLM, the TFM, and the TMs cannot be exploited to establish a timing channel. Indeed, each operation executed by a transaction is mediated by the TM at the same security level as the transaction. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
362
•
E. Bertino et al.
The TM for each data operation requested by the transaction issues a proper lock request to the TLM, and it sends the data operation to the TFM, which is in charge of physically executing the operation, only when the lock request is accepted. Thus, a timing channel could only be established by two TMs, either through the TLM or the TFM. However, since both the TFM and the TLM operations are transparent to lower-level TMs, these kinds of timing channels cannot be established. 9.2 The Execution Model In this section we define the behavior of the TM at a certain security level l and that of the TLM. For each transaction Ti executed at level l , the managers rely on two data structures classified at level l . These data structures are shared by the TM at level l and by the TLM, 11 and are defined as follows: —SQi (signal queue for transaction Ti ): each element of the queue corresponds to either transaction identifier Ti , if Ti holds a signal lock on a data item that was modified by a low transaction, or the transaction identifier of a child of Ti that released to Ti a lock on a data item modified by a low transaction. —LLi (lock list for transaction Ti ): is a list containing the locks held or retained by transaction Ti . In particular, for each lock we maintain: (i) the corresponding data item; (ii) the type of the lock (write, read, signal); (iii) the status of the lock (held, retained); (iv) the identifier of the subtransaction that released the lock (in case of retained locks) or the transaction identifier itself, in case of held locks. For each data item a, an additional queue W Q a (waiting queue for data item a) is maintained. Such a queue, which is accessible only by the TLM, contains the identifiers of all the transactions whose access to data item a has been delayed due to some lock conflict, together with the type of the requested lock. The behavior of the managers can be summarized as follows: TM at security level l . The TM executes specific actions for each primitive executed by a transaction at level l . The code of the TM at level l , which is relevant for explaining the behavior of the Raise Signal and Get Signal primitives, is presented in Figure 11, where we use the auxiliary functions reported in Table IV. The TM at level l executes a procedure, denoted in the figure as TransactionRunTimeSupporti , for each distinct transaction Ti executing at level l . Procedure TransactionRunTimeSupporti performs different operations, depending on the type of the primitive that is currently being executed. For instance, in case of a read primitive on a data item a, the procedure determines whether the corresponding transaction needs a signal or a read lock on a, and then waits until the TLM grants the appropriate lock on a before performing the read operation. Similar operations are performed for the write primitive. By contrast, if the primitive is a Raise Signal, procedure 11 By
shared data structures, we mean data structures that can be read and written by both the TM at level l and the TLM.
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
363
Fig. 11. TM module.
TransactionRunTimeSupporti notifies the TLM. The TLM is then in charge of identifying all data items modified by the invoking transaction or by some of its descendants. It then inserts in queue SQk , for each transaction Tk with a security level greater than Ti , the identifier of the transaction itself, if Tk holds a lock on a modified data item, or the identifiers of the children that released to Tk some retained locks on the modified data items. In case of a Get Signal primitive, two cases may arise: If Ti is a leaf transaction, it has performed a read operation on a data item for which the signal lock was broken and its handler list is empty, then the transaction is aborted. By contrast, if Ti is a nonleaf transaction, for each child of Ti that released a signal lock on a data item that was broken, the corresponding handler is executed, following the rules in Section 5.3 (handler execution is performed by function ExecuteHandler ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
364
•
E. Bertino et al. Table IV. Functions in the TM Module
Function
Meaning
Dequeue(Queue)
Returns the first element of Queue and deletes it from Queue.
Wait(FROM, TID, op, a, mode)
Sends a message to the TLM. Message includes the identifier FROM of the TM sending the message, the identifier TID of the current transaction, the operation op to be executed (Lock,Unlock,RaiseSignal), the identifier of the data item a on which the operation has to be performed (if op is RaiseSignal or Unlock, a = null), and the locking mode mode (if op is RaiseSignal or Unlock, mode = null). It then, waits for an acknowledgment from the TLM.
ExecuteHandler(TID, Tk )
Executes the handler associated with transaction TID due to a modification performed by a low transaction, of some data items previously read by the child transaction Tk .
in Table IV). If no data items modified by some low-level transactions have been read by Ti descendants, nothing happens (default exit point). If the primitive is a Request Commit, a request to release the locks held or retained by the ending transaction to the parent transaction is sent to the TLM. Moreover, the data structures S Q i and LLi are deleted. Such deletion is also performed if the primitive to be executed is Abort. TLM. The TLM code is shown in Figure 12, and additional functions used by TLM are reported in Table V. Each request sent by the TM at level l (denoted by TMl ) to the TLM, through the invocation of function Wait, is represented by a tuple of the form (Sender, Ti , op, a, mode), where Sender is the identifier of the TM sending the request, Ti is the identifier of the transaction requiring the operation, op is the operation to be performed on data item a (lock, unlock, or RaiseSignal), and mode represents the required lock (write, read, signal). Before granting any lock, the TLM checks whether the security level of TM and Ti are compatible with the lock required on a. To this purpose, we assume that function L determining the security level of a given TM or a transaction is trusted. After that, the TLM operates in the following way. If a lock operation is required, the TLM verifies that the lock on a can be granted according to the locking protocol, by invoking function Check Conflicts (Table V). If an unlock operation is required, all locks held or retained by Ti are inherited as retained locks by the parent of Ti . A transaction waiting for a conflicting lock can then be woken up. If a Raise Signal is required, the TLM looks for all data items that have been modified by Ti or by some of its descendants. Then, the TLM ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
365
Fig. 12. TLM module.
updates queue S Q k for each high-level transaction Tk that holds or retains a signal lock on a modified data item. Besides what we presented above, we have defined a set of strategies based on additional data structures that improve the efficiency of the TLM and TMs. We refer interested readers to Bertino et al. [2000] for additional details on this topic. 10. FEATURES OF THE PROPOSED APPROACH The proposed execution model is based on two components: an operation-level component, represented by TLM and a set of TMs, and an application-level component, represented by transactions themselves that, by adequately using the proposed primitives, can decide which operations have to be executed depending on application-specific information. This approach leads to a high degree of flexibility and provides more efficient resource allocation, aiming at reducing starvation as much as possible. In the following, these aspects are discussed in more detail. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
366
•
E. Bertino et al. Table V. Functions used in the TLM module
Function
Meaning
Send(TO, TID, response)
Sends a message to TO. The message includes the identifier of a transaction TID and an answer response to a previous request.
Receive(FROM, TID, op, x, mode)
Receives a service request from FROM. The request contains the operation op to be executed for transaction TID on x. If the operation is a lock operation, then mode specifies the locking mode (Read, Signal, Write).
AppendToQueue(Queue, Item)
Inserts Item at the end of Queue.
LookForData(TID)
Returns data items that have been modified by transaction TID or by one of its descendant, by inspecting the LL list associated with TID. It returns the set of modified data items.
ChooseTransaction(a)
Chooses nondeterministically a transaction from queue W Q a . It returns the chosen transaction along with the type of the lock the transaction is waiting for.
CheckConflicts(TID, mode, a)
Returns true if it is possible to grant a lock of type mode on data item a to transaction TID; returns false, otherwise.
Flexibility. The flexibility of the proposed protocol depends both on the strategy it uses to ensure the correct and concurrent execution of transactions and on the chosen transaction model. As already pointed out, adopting a nested transaction model greatly increases flexibility, due to the ability of selectively aborting just a portion of a transaction and not always the transaction as a whole (see Section 3). On the other hand, the proposed approach makes transactions free of deciding which actions have to be executed when some critical situations are notified. This provides a high level of flexibility, since no predefined behavior is imposed on transactions. This is a useful feature in all the cases where a write operation executed by a transaction does not necessarily imply the abort of high-level transactions that previously read such data. Consider, for example, a transaction calculating some statistical functions, such as an average over a large amount of data. Suppose that such a transaction gets a signal, due to a write operation performed by a low-level transaction on some data it previously read. In this particular case, the semantics of the application can lead to the decision that no computation has to be executed again, since the data update can be considered as nonrelevant for computing the final result. In this case, the transaction can continue normal execution, with great improvement in resource allocation and performance. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
367
The proposed method is also more flexible than other typical version-based approaches. Indeed, as we have seen, transactions are free to decide which actions have to be executed when a signal lock is broken. The overhead of such an approach is of course lower than dealing with multiple versions, which have to be created and managed even if transactions deal with just a few of them. However, the high level of flexibility provided by the proposed approach has a negative counterpart, caused by the increase in programming effort due to use of the Get Signal and Raise Signal primitives. But this additional effort can be avoided by using tools that directly insert the proposed primitives in the transaction code, making them transparent to applications. For example, the simplest way to achieve serializability is to introduce a Raise Signal call in the application code after any write operation, and introduce a Get Signal call after any read operation on lower-level data performed by a leaf transaction. Starvation. A key feature of any concurrency control protocol is its ability to avoid starvation. By starvation we mean the situation where some transactions are subject to indefinite delays due to the adopted protocol. It is simple to show that the approach we propose limits starvation as much as possible. Indeed, when a transaction writes a certain data item, a high-level transaction that previously read such data item may —be already committed before getting the signal from the low-level transaction; this situation is quite common for shortlived transactions. In this case, no modification to the normal flow of high-level transaction execution is performed. —not be already committed. In this case, different application-level policies can be applied by the high-level transaction, not necessarily requiring an abort operation, as pointed out before. A good usage of the proposed primitives can lead to application code that avoids starvation. Besides avoiding starvation, as defined mathematically, the proposed approach also avoids aborted transactions reading old data item values when re-executed. Indeed, if we consider correct multilevel nested transactions only, the constraint is imposed that each modification of a data item a, for example by a transaction T , must be followed by the invocation of a Raise Signal primitive so that high-level transactions with a signal lock on a are notified of the modification and a transaction that read a must be rolled back. When such a transaction, say T1 , is restarted and reads a again, it must acquire a signal lock on it. Due to the locking rules in Section 4.2, the signal lock is released only when no other transactions hold or retain a write lock on a. In this situation, it is released at least after the commit of transaction T , which holds a write lock on the data item. This guarantees that when transaction T1 is re-executed, it will read the new value of the modified data item. Performance. Performance of a concurrency control algorithm can be estimated both in terms of resources required by the algorithm itself and in terms of the execution time of the transactions, resulting from the application of the proposed approach. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
368
•
E. Bertino et al.
Concerning the algorithm, several parameters can be considered in estimating performance. Among the interesting ones, we recall the used storage resources, the overhead in additional operations with respect to traditional approaches, and the management of data versions [Atluri et al. 1997]. The proposed algorithm does not waste storage, since it does not maintain versions and stores the data structures required by the computation (i.e., the SQ and LL lists) in main memory. Furthermore, since no version is used, the only computational overhead is due to the management of the new data structures, notification of broken signal locks, and execution of handlers, which, however, represent transaction code. It is important to note that the information about broken signal locks sent by the TLM to the TMs is not sent as soon as the signal locks are broken, but is delayed. More precisely, this information is communicated to TMs only when a lower-level transaction executes a Raise Signal operation. The advantage of such a scheme is that the overhead due to the processing of notifications is reduced. Indeed, once a transaction Ti acquires a write lock on a data item a, the number of high-level transactions that have to be notified about a modification of a can only decrease and not increase. This is due to two different facts: (i) some of the high-level transactions may perform a commit before notification; (ii) all transactions whose execution started after data item a has been modified by transaction Ti and want to read a must wait for the termination of Ti . Additionally, the TLM can further minimize the number of messages sent to a particular TM by grouping all signals to different transactions at the same security level into a single message. As to transaction performance, it depends on the computational costs of the new primitives. The cost of a Get Signal invocation by a transaction Ti depends only on the number of read operations performed by Ti on lower-level data items for which it got a signal (see Figure 11). On the other hand, the complexity of the Raise Signal, called by a transaction Ti , depends on both the number of write operations performed by Ti and by the number of security levels higher than the level of Ti . It is important to note that other concurrency control algorithms for multilevel transactions that are computationally less expensive have been proposed. However, as pointed out in Section 2, the increase in performance is usually associated with the loss of some important properties: some do not avoid starvation [Ammann and Jajodia 1991], and some do not guarantee serializability [McDermott and Jajodia 1992; Maimone and Greenberg 1990]. The proposed approach, even if in some cases computationally more expensive, satisfies all the previous properties, and at the same time guarantees high flexibility and reasonable performance. Performance penalties can be reduced further by a careful transaction programming and an efficient implementation of data structures. 11. CONCLUDING REMARKS This article presented an approach to secure concurrency control for transactions in a multilevel environment. The proposed approach, which uses singleversion data items, is based on the use of nested transactions, application-level recovery, and notification-based locking protocols. The notification protocol is ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
A Nested Transaction Model
•
369
based on the use of signal locks. A signal lock is acquired by a transaction whenever it needs to read lower-level data; such a lock does not delay a write lock request by a low-level transaction on the same data item. Hence, timing covert channels arising from synchronization are eliminated. When a data item on which a write lock is acquired by a transaction is modified, all highlevel transactions holding signal locks on that data are notified by the trusted lock manager, and thus may perform recovery actions. To better support recovery activity, transactions are organized according to the nested transaction model extended with specific primitives for supporting the notification protocol. This article addressed several issues arising from the introduction of a notification protocol in nested transactions. Formal definitions for all the proposed notions were developed and serializability and security results presented. The proposed approach satisfies most of the properties pointed out in Atluri et al. [1997], as basic requirements for a secure concurrency control mechanism in a multilevel environment: it avoids starvation and timing channels, and guarantees serializability. However, unlike Atluri et al. [1997], it relies on a trusted lock manager. We have, however, justified this assumption and discussed how it can be realized. Our work can be extended in several directions. One concerns a detailed performance analysis of the proposed approach. Since several weaker notions of serializability have been proposed (see, for example, Jajodia and Atluri [1992] and Jajodia et al. [1996]), we also plan to extend such notions to nested transactions and define conditions for guaranteeing such weaker notions of serializability under the proposed concurrency control mechanism. Another important issue is the investigation of secure commit protocols for distributed nested transaction models that exploit our approach.
REFERENCES AMMANN, J., JAECKLE, F., AND JAJODIA, S. 1992. A two snapshot algorithm for concurrency control in secure multi-level databases. In Proceedings of the IEEE Symposium on Research in Security and Privacy, 204–215. AMMANN, J. AND JAJODIA, S. 1991. A timestamp ordering algorithm for secure single-version multilevel databases. In Proceedings of the 5th IFIP WG 11.3 Workshop on Database Security. AMMANN, J. AND JAJODIA, S. 1994. An efficient multiversion algorithm for secure servicing of transaction reads. In Proceedings of the 1st ACM Conference on Computer and Communication Security, 118–125. ATLURI, V., JAJODIA, S., MCCOLLUM, C., AND MUKKAMALA, R. 1997. Multilevel secure transaction processing: Status and prospects. In Database Security: Status and Prospects P. Samarati, and R. Sandhu, Eds, Chapman & Hall. BEERI, C., BERNSTEIN, P. A., AND GOODMAN, N. 1989. A model for concurrency in nested transaction systems. J. ACM 36, 2, 230–269. BERTINO, E., CATANIA, B., AND FERRARI, E. 2000. A nested transaction model for multilevel secure database management system. Tech. Rep. Dept. of Computer Science, University of Milan, Italy. BELL, D. E. AND LAPADULA, L. J. 1976 Secure computer systems: Unified exposition and multics interpretation. Tech. Rep. MTR-2997, The Mitre Corp., Bedford, MA. BERNSTEIN, P. A., HADZILACOS, V., AND GOODMAN, N. 1987. Concurrency Control and Recovery in Database Systems. Addison-Wesley, Reading, MA. BERTINO, E., JAJODIA, S., MANCINI, L., AND RAY, I. 1998. Advanced transaction processing in multilevel secure file stores. IEEE Trans. Knowl. Data Eng. 10, 1, 120–135. ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.
370
•
E. Bertino et al.
Department of Defense. Trusted computer system evaluation criteria, DOD 5200.28-STD, Dept. of Defense, Washington, D.C. GOGUEN, J. A. AND MESEGUER, J. 1982. Security policy and security models. In Proceedings of the IEEE Symposium on Security and Privacy. GRAY, J. AND REUTER, A. 1993. Transaction Processing: Concepts and Techniques. Morgan Kaufmann, San Mateo, CA. HALICI, U., ARPINAR, B., AND ASUMAN, D. 1997. Serializability of nested transactions in multidatabases. In Proceedings of the International Conference on Database Theory (ICDT ’97), 321– 335. HARDER, T. AND ROTHERMEL, K. 1993. Concurrency control issues in nested transactions. VLDB J. 2, 1, 39–74. Informix-Online/Secure Administrator’s Guide, Menlo Park, CA. Informix-Online/Secure Security Features User’s Guide, Menlo Park, CA. IRVINE, C. E. 1995. A multilevel file system for high assurance. In Proceedings of the IEEE Symposium on Research in Security and Privacy. IRVINE, C. E., ACHESON, T. B., AND THOMPSON, M. F. 1990. Building trust into a multilevel file system. In Proceedings of the 13th National Computer Security Conference Washington D.C. JAJODIA, S. AND ATLURI, V. 1992. Alternative correctness criteria for concurrent execution of transactions in multilevel secure databases. In Proceedings of the IEEE Symposium on Security and Privacy, 216–224. JAJODIA, S., MANCINI, L., AND RAY, I. 1996. A secure locking protocol for multilevel database management systems. In Proceedings of the 10th IFIP WG 11.3 Workshop on Database Security. JAJODIA, S., MANCINI, L., AND RAY, I. 1990. Multiversion concurrency control for multilevel secure database systems. In Proceedings of the IEEE Symposium on Security and Privacy. MAIMONE, W. T. AND GREENBERG, I. B. 1990. Single-level multiversion schedulers for multilevel secure database systems.In Proceedings of the 6th Annual Computer Security Applications Conference, 137–147. MCDERMOTT, J. AND JAJODIA, S. 1992. Orange locking: Channel-free database concurrency control via locking.In Proceedings of the 6th IFIP WG 11.3 Workshop on Database Security. MOSS, J. E. B. 1985. Nested Transactions: an Approach to Reliable Distributed Computing. MIT Press, Cambridge, MA. PAL, S. 1995. A locking protocol for multilevel secure databases providing support for long transactions. In Proceedings of the 9th IFIP WG 11.3 Workshop on Database Security. SANDHU, R. 1993. Lattice-based access control models. IEEE Computer 26, 11, 9–19. SCHAEFER, M. A. AND WALSH, G. 1988. Lock/ix: On implementing Unix on the Loch TCB. In Proceedings of the 11th National Computer Security Conference, 17–20. Sybase Secure SQL Server Security Administrator’s Guid, Emeryville, CA. THOMAS, R. K. AND SANDHU, R. 1993. Towards a unified framework and theory for reasoning about security and correctness of transactions in multilevel databases. In Proceedings of the 7th IFIP WG 11.3 Workshop on Database Security. Trusted Oracle Administrator’s Guide. Redwood City, CA. Received January 2000; revised May 2001; accepted October 2001
ACM Transactions on Information and System Security, Vol. 4, No. 4, November 2001.