The present disclosure generally relates to buffer overflow protection, and relates in particular to protecting non-control data from buffer overflow attacks by using a secure bit.
Recently, “canary” solutions to buffer-overflow attacks have been implemented in mainstream software. Among the wide variety of canary solutions that exist, the best-known is StackGuard. StackGuard protects against stack smashing by putting a canary word adjacent to a return address. Assuming that overflow occurs in only one direction, validating the canary can detect the overflow of a canary-protected address. Similarly, the concept can also be applied to protect against buffer-overflow attacks on data in general by placing a canary at the end of every buffer or adjacent to each pointer.
Though the mechanism can detect buffer overflow in general, it can be circumvented by replacing the canary word with a valid value when an overflow occurs (see
In contrast, Secure Bit (and similar mechanisms) can preserve the integrity of data across domains. Details relating to Secure Bit can be found in Enbody et al., “Secure Bit,” (WO2006052703A2), filed by the Assignee of the present application on Nov. 3, 2005. Further details relating to Secure Bit, can be found in Enbody et al., “Secure Bit,” U.S. Provisional Patent Application No. 60/650,328, filed by the Assignee of the present application on Feb. 4, 2005. Still further details relating to Secure Bit can be found in Enbody et al., “Secure Bit,” U.S. Prov. Pat. App. No. 60/624,823, filed by the Assignee of the present application on Nov. 4, 2004. The aforementioned patent applications and publication are incorporated herein by reference in their entirety for any purpose.
The Secure Bit mechanism only applies to data which is the target of a jump (including function pointers) because Secure Bit raises an exception when a jump is executed. Secure Bit will not jump to “tainted” (insecure input) data. Non-control data differs because data which is tainted by input may be valid data (e.g. array index). Therefore, Secure Bit cannot be applied directly to protect against buffer overflow on pointers and other non-control data in general. In the case of a pointer (which is not a function pointer), no jump might ever be made to the word storing the pointer. Thus, the need exists for a solution to the problem of protecting against buffer overflow on pointers and other non-control data.
In accordance with the present invention, a computer processor protects a protected word in computer readable memory by employing a canary word in the same buffer as the protected word that is protected by a secure bit and/or by employing a canary bit that directly protects the protected word. In another aspect of the present invention, a bit setting module marks the protected word as tainted by setting the secure bit or canary bit in response to overwrite of the canary word and/or protected word, including overwrite resulting from overflow of the buffer. A further aspect of the present invention provides a validation module which operably validates non-control data stored in the protected word every time the non-control data is used by a computer process by checking the secure bit of the canary word and/or by checking the canary bit of the protected word.
The disclosed process and method of protecting non-control data from buffer overflow attacks is advantageous over previous devices and methods because a word created locally and a word passing from another domain can be differentiated and checked whenever the word is used. For example, validating a pointer protected by a canary word, results in checking the validity of the canary word by its secure bit. Alternatively, validating a pointer protected by a canary bit anytime the pointer is used can detect if the pointer is tainted. Validity of the non-control data is tied to the validity of the secure bit which is protected by the secure bit mechanism. The protection is in two ways. First, the bit itself is protected from malicious modification by an attacker. Second, the secure bit protection of control data prevents the attacker from executing code which could circumvent the canary word/bit protection mechanism. As a result, the disclosed protection mechanism(s) cannot be circumvented. Additional advantages and features of the present invention will become apparent from the following description and appended claims, taken in conjunction with the accompanying drawings.
The present teachings will become more fully understood from the detailed description and the accompanying drawings, wherein:
a) is a flow diagram illustrating a method of operation for the Canary Bit scheme; and
b) is a flow diagram illustrating a method of operation for a Canary Word scheme.
The following description of the preferred embodiment is merely exemplary in nature and is in no way intended to limit the disclosure, its application, or uses.
In accordance with the preferred embodiment of the present invention, the canary solution is a combination of hardware and software solutions. Fundamentally, a tag bit (Secure Bit) is required in hardware for flow tracking. However, there are two different designs for managing the canary: a memory word (or byte) or a hardware bit (in addition to Secure Bit). The first scheme puts greater burden on the software (e.g. compiler). Nonetheless, both can be implemented with hardware and software modifications. These two schemes are referred to as Canary Word and Canary Bit respectively.
Starting with
According to the Canary Word scheme, the protected word 102 is protected by a canary word that is in turn protected by a secure bit. Allocation module 106 allocates the canary word in a first memory location of a buffer in the computer readable memory. The canary word protects the protected word in a second memory location of the buffer. The first and second memory locations have a predefined correlation in terms of location within the buffer. Allocation module 106 also allocates the secure bit to the canary word. Bit setting module 108 marks the canary word as tainted by setting the secure bit in response to overwrite of the canary word, including overwrite of the canary word resulting from overflow of the buffer. Validation module 110 validates non-control data stored in the protected word 102 by checking the secure bit of the canary word every time the non-control data is used by a computer process 112. Bit clearing module 114 prevents the secure bit from being cleared unless an entirety of the canary word is also cleared. This prevention ensures that the canary word cannot be untainted, but only cleared.
According to the Canary Bit scheme, the protected word 102 is protected by a canary bit. Allocation module 106 allocates the canary bit to the protected word 102 in a memory location of the buffer in the computer readable memory 104. Bit setting module 108 marks the protected word 102 as tainted by setting the canary bit in response to overwrite of the protected word 102, including overwrite of the protected word 102 resulting from overflow of the buffer. Validation module 110 validates non-control data stored in the protected word 102 by checking the canary bit of the protected word 102 every time the non-control data is used by the computer process 112. Bit clearing module 114 prevents the canary bit from being cleared unless an entirety of the protected word 102 is also cleared. This prevention ensures that data of the protected word 102 cannot be untainted, but only cleared.
To ease understanding,
Canary Word: In this scheme, a canary word is inserted adjacent to each pointer (
Canary Bit: Rather than inserting a word, a similar result can be achieved by using an additional hardware bit (a.k.a. Canary Bit) associated to each pointer for validating the pointer itself (
Note that there is a fundamental difference between Secure Bit and Canary Bit. While Secure Bit is associated with data, a Canary Bit is associated with an address (location). For example, in this case moving the pointer value to some different destination will carry along the Secure Bit on the move (with the pointer value) and leave the Canary Bit behind unmodified. (To free a memory location and clear the Canary Bit, a program must explicitly clear a memory entry, e.g. with clear instruction).
Up to this point, the concepts of both schemes have been introduced. The implementations of the schemes are explored below.
The implementation of the schemes builds upon Secure Bit where all input gets its Secure Bit set. To enforce the Canary Word solution, compilers can be modified to inject a canary word adjacent to every pointer (or buffer). Whenever a pointer (or variable) is dereferenced, compiler-injected code forces the program to first validate the Canary Word or Canary Bit.
Pointers are validated by checking the status of the Canary. For both schemes, one instruction is sufficient to validate the Canary. The implementation details of each scheme are disclosed below by elaborating one scheme (Canary Word) and pointing out the small differences for the other (Canary Bit).
With the Canary Word scheme, Secure Bit hardware is sufficient for managing the canary. However, an additional instruction can be required for validating the Secure Bit of the canary word. In terms of software, programs must be modified to include canary words and validate instructions (a compiler can do it).
In regard to memory storage, the hardware storage requirements for Canary Word are similar to that of Secure Bit. In fact, Secure Bit hardware can be used for canary words as well as for its original purpose—they are complementary. If Secure Bit does not already exist, a bit is added to every memory location (and register). This bit is handled by the memory manipulating instructions as a regular memory word (moved along with the associated word). Words in buffers passed between processes get their Secure Bit set. By setting Secure Bit in a buffer passing across domains, associated instructions can easily detect that an address (a canary in this case) was modified by a buffer passing from another domain—there was a buffer-overflow.
Regarding validation, one instruction is sufficient to validate the Secure Bit, and multiple options exist. For example, there exist the options of a new mode, a new instruction, and/or new semantics. These options are described below.
The new mode, “canary mode,” can be added to the processor. In this mode, when a canary word is loaded, its Secure Bit is checked. If the Secure Bit is set, an exception is raised. The mode can be set before loading the canary word and then the mode can be cleared afterwards. An advantage of this mode is that no new instruction is needed; however, a disadvantage is that more instructions are executed.
The new instruction, load-and-validate “LD_VD”, can load and validate a canary word. This instruction is no slower than a regular load instruction because the Secure Bit can be compared in parallel. The pros and cons are the opposite of the new mode above: faster, but the ISA changes.
Choosing new semantics, the conditional branch instruction can be modified to branch or raise an exception if the Secure Bit of a word is found to be set. Some advantages are that the ISA is unchanged and performance is fast. However. a disadvantage is that some convoluted semantics might be necessary. A critical issue with these modifications is that none of them set or clear a Secure Bit. That limitation removes these instructions from any attack vector on the Secure Bit mechanism. When compared with existing schemes such as StackGuard or PointGuard, any of these approaches will be at least as efficient while being more secure.
In addition to the hardware component of the solution described above, there is also a software component. Unlike protecting control data, protecting all pointers requires modification to software. The reason is that control data must be independent of input, whereas some pointers will be modified by input, and only the programmer (compiler) knows the difference. Pointers must be identified and canary words must be placed adjacent to the pointers. This task can be performed either manually by a programmer or automatically by a compiler. A compiler must locate each pointer, insert a canary word adjacent to the pointer, and add an instruction to validate the canary word (see validation options above). When a pointer is dereferenced, if the Canary Bit is found to be set, an exception will be raised.
To ease understanding of the mechanism for placing and managing the canary, the concept of how memory is allocated by a compiler is visited here. Normally, local variables are allocated on top of the stack in the order of declaration.
Since overflow goes in one direction, placing a canary adjacent to a pointer provides a mechanism for detecting an overflow to a pointer by validating the value of a pointer (see
In the case of programmer-managed canary, a variable (e.g. an integer) is declared before each pointer. On any reference to the pointer, the canary must be first asserted (validating that the Secure Bit of the canary is cleared). In the example of Table 1, it is assumed that the function assertSecureBit is responsible for validating the Secure Bit of a memory location. In a similar manner, a compiler can be modified to achieve the same result.
——assertSecureBit (&canary);
Possible compiler-injected code in pseudo format is provided below.
Now that the implementation of the Canary Word scheme has been detailed above, the differences of the Canary Bit scheme are detailed below. The Canary Bit scheme is similar to the Canary Word, but requires hardware storage in addition to Secure Bit for storing the Canary Bit. Similar to the Canary Word scheme, an additional instruction can be required for validating the Canary Bit of the canary word. Similarly, programs can be modified to manage and validate the Canary Bit.
Regarding memory storage, the hardware requirements for Canary Bit are similar to those of Secure Bit. However, an additional bit is added to every memory entry (word or byte). Words in buffers passed between processes get both their Secure Bit and Canary Bit set. However, the Canary Bit is left unmodified when handled by the memory manipulating instructions (not moved along with the associated word). Thus, a special mechanism is required for initializing and allocating the Canary Bit. One such mechanism can be achieved by modifying the semantics of a “clear” instruction to clear the Canary Bit of a memory entry. By setting the Canary Bit in a buffer passing across domains, associated instructions can easily detect that an address was modified by a buffer passing from another domain—there was a buffer-overflow.
Regarding validation in Canary Bit, the validation protocol is the same as that of the Canary Word scheme. However, regarding the software, with the additional hardware providing the Canary Bit, there is no need for inserting a word adjacent to a pointer—hence no gap for a Canary Word is needed. In addition, since there is no need to verify the adjacent word, there is no additional memory access for loading and verifying the Canary Word. The validation can be performed when the pointer itself is loaded. However, the Canary Bit, unlike Secure Bit, has to be initialized (e.g., to zero) for every memory allocation. With Canary Bit the Canary Word program in Table 1 may look like the pseudo code provided below:
Now that the implementations of the two schemes have been described, various options can be explored below. In particular, with either Canary solution in place, other interesting tasks can be performed. For example, this technique allows us to perform hardware-assisted bounds checking. One can place a canary word at the end of a buffer and use the validation instruction to check that the buffer has not gone beyond its bounds. Additionally, one can use a string null terminator as a canary word by associating and validating the Secure/Canary Bit.
Finally, the Canary Bit need not be limited to protecting pointers. Any other critical data can be protected with a canary word. However, using a canary word in such a fashion automatically may not work well in every instance. Thus, some circumstances can benefit from automatic application of the canary word, while others can benefit from manual application of the canary word.
Security is enhanced with respect to other Canary schemes because of the hardware support. Neither the Secure Bit nor Canary Bit can be maliciously modified independent of modifying the protected data. This feature removes an important attack vector. It is believed, but not yet proven, that no attack on the scheme exists.
Turning to
Turning to
This disclosure is merely exemplary in nature and, thus, variations that do not depart from the gist of the disclosure are intended to be within the scope of the disclosure. Such variations are not to be regarded as a departure from the spirit and scope of the disclosure.
This application claims priority from U.S. Provisional Patent Application No. 60/849,879 filed on Oct. 9, 2006. The disclosure of the above application is incorporated herein by reference in its entirety for any purpose.
Number | Date | Country | |
---|---|---|---|
60849879 | Oct 2006 | US |