I'm experimenting with Linux Security Modules, trying to make one.
My main source of knowledge about how they're supposed to work are mailing lists archives and the existing LSMs' sources, plus the few pages about them in the Linux documentation.
I understand that there are two kinds of LSMs.
LSM_FLAG_EXCLUSIVE
flag set in their LSM definition.Browsing the source code of all these LSMs, I figured out non-exclusive ones never make use of security blobs. On the other hand, exclusive ones make heavy use of them.
For instance, see the AppArmor LSM definition, and the one for Yama.
So, can non-exclusive LSMs specify blob sizes and use this feature ?
Trying to find an answer, I explored the framework's source to see if maybe security blobs were switched between each LSM hook call, I guess that would allow each LSM to only have access to its own blobs and not those of another LSM.
However, we can see here in the LSM framework that it is not the case.
If my LSM declares blob sizes, can I use the blobs if my kernel also have SELinux, for instance, enabled ? Won't the structures from SELinux and mine overlap ?
Alright, I found the relevant code in the LSM framework.
QED: Yes, all LSMs can use security blobs as long as they use the sizes structure as containing offsets once the module is ignited.
Explanation:
When you define your LSM, you use the DEFINE_LSM
macro followed by various informations, including a pointer to a struct lsm_blobs_sizes
.
During its own ignition, the LSM framework (which is mostly implemented in security/security.c
) manipulates your structure in a few operations.
ordered_lsm_init()
`- prepare_lsm(*lsm)
`- lsm_set_blob_sizes(lsm->blobs)
`- lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
lsm_set_blob_size
is responsible for the actual addition to the framework's structure instance.
However, combined with lsm_set_blob_sizes
, it effectively replaces each size in the currently prepared LSM's struct lsm_blob_sizes
with the offset at which this LSM's part of the blob resides.
The framework then calls their init function.
Later, when any structure with a security blob (a task_struct
for instance) gets allocated, the framework will allocate one blob with enough space for the blobs of all security modules, which in turn will find their spot in this larger blob using the offsets in their own lsm_blobs_sizes
.
The summed-up sizes of security blobs is actually meant to be controlled using init_debug
, here.
So what this means is that all LSMs can define security blobs sizes. The framework is responsible for their allocation (and deallocation) and the blobs for different LSMs can happily live side by side in memory.