You must design the key protection so that any incorrect
references to memmory can easily be detected and repaired.
To design key protection into a kernel extension, perform
the following steps:
- Define memory classes. A memory class is a set of virtual
pages that are associated with the same storage protection key. Ideally,
each memory class is represented by a unique kernel key, although
there are limits on both the actual number of kernel keys that can
be used, and the actual number of hardware keys that are available
for the kernel and kernel extensions.
- Allocate a kernel key for each memory class. You can use
the kkey_assign_private kernel service to allocate unique kernel
keys.
- Assign kernel keys to the (pages of) memory to be included
in each memory class. You can use the heap_create kernel service
to create a memory heap whose pages are protected with a specified
kernel key. Your new heap can then be used by the xmalloc and xmfree kernel
services as usual.
When your program ends, use the heap_destroy kernel
service to clean up any heaps you have created.
- Determine which kernel keys are required by the kernel
extension to satisfy the requirements of other kernel extension data
that is referred to. For the best result, add the access rights from
one of these predefined key sets to your own, rather than build up
your key set from scratch. See Kernel Keys and Kernel Key Sets.
- Create the kernel key sets defining the access authorities
that are needed by your extension to refer to its private memory classes.
You can use the following kernel services:
- kkeyset_create
- Allocates an empty key set.
- kkeyset_add_key
- Adds access rights for a kernel key to your key set.
- kkeyset_remove_key
- Removes access rights to a given kernel key from your key set.
- kkeyset_add_set
- Adds the access rights that are defined in one key set to another.
- kkeyset_remove_set
- Removes the access rights that are defined in one key set from
another.
- kkeyset_delete
- Frees a key set after it has been used to create a hardware key
set by 6.
- Create hardware key sets that you
need to control access to the memory classes during execution. These
hardware key sets are needed to implement your protection gates. The kkeyset_to_hkeyset service
performs this translation.
Attention: The HKEYSET_GLOBAL key
set is defined to access any memory no matter which key protects it.
Therefore, this hardware key set should be used with caution.
- Implement protection gates as needed to grant access to
the memory classes, and to restore the prior authority mask register
state. Typically, you can perform these steps at the entry and exit
points of the major functions of the kernel extension. You can implement
a replace gate at an entry point in your driver to grant access appropriately.
Without one, the driver has the inappropriate access rights of its
caller, typically the kernel. You can implement a restore gate at
exit points to restore the access rights back to those of the calling
program. See Protection Gates for
more information about protection gates.
- Link the kernel extension using the new -b ras flag,
so that the kernel can recognize it as a key-safe kernel extension.
If the extension must refer to user space memory, use
the copyin, copyout, or one of the cross-memory kernel
services. These services acquire the appropriate additional hardware
keys necessary to access and protect user space. (The user-space application
might use storage protect keys itself.) It is possible, but not suggested,
to add user keys to the current authority mask register with the hkeyset_update_userkeys service,
and to restore the previous state with the hkeyset_restore_userkeys service.
Any
kernel keys can be used, with appropriate care, by any kernel extension.
You can also remove keys that you do not need. For example, you can
remove the KKEY_TRB key if your extension does not use services such
as the tstart kernel service, which uses the trb structure.
Though not required, the action can increase the benefit of using
storage protect keys by minimizing the access rights of your kernel
extension. Start with a predefined key set, and remove specific keys;
rather than start with an empty key set, and figure out which ones
you need to add.
In general, you do not need to test your code
for the presence, absence, or number of available hardware keys. All
key-protection kernel services work efficiently in all cases.