On Wed, 2005-12-07 at 07:10 -0500, Stephen Smalley wrote:
If you want to map the role to an integer index that can be
compared,
you need to do that in the kernel. The SELinux security server does
maintain such indices for the individual context components, but doesn't
presently export them outside of the security server (not even to the
rest of the SELinux module, which only deals with SIDs that are indices
to complete contexts, not individual fields). If the security server
starts exporting those indices to the audit system, then we also need to
deal with consistency there, so a policy reload would have to trigger a
re-mapping of the original role strings to the correct index in the new
policy (and the new policy may no longer define that role at all, at
which point you have to invalidate the entire filter in some way).
...
The audit system could ask SELinux via a new interface for the role
value (string or index) corresponding to the current task, and compare
that value (string or index) with the one in the filter.
Ok, this is good info, Stephen. I'm thinking now that we should
probably design this with flexibility in mind so that any of those
components (user,role,type,sensitivity) could be filtered upon.
Now, these indices of individual components that are not exported...
Can SELinux easily and quickly translate the strings into their indices?
Is it hashed or something? If not, we're right back to the string
matching, just pushing the work deeper into SELinux.
The following is conceptual C code that I'm proposing as a design. This
assumes that SELinux can easily split a full context into its components
(or elements as it's called below), and that SELinux can easily turn
these into their unique indices. If that's not the case, please correct
me and I think I'll have to scrap this and go back to the drawing board.
--
Let's say that SELinux exposes the following function to the audit
subsystem:
extern int security_match_element(const char *haystack_ctx, const char *needle,
const int element) {
if (
security_element_atoi(needle) == security_ctx_element_atoi(haystack_ctx, element)
)
return 1;
return 0;
}
Where:
haystack_ctx is a string that might look something like:
"system_u:object_r:tmp_t:s0"
needle is a string that might look something like: "object_r"
element is an int [0-3] (or a #define constant like SECURITY_ROLE_ELEMENT) that specifies
which component to match: 1
Internal to SELinux, helper functions would exist such that the
appropriate element can be extracted from the string and translated to
an int:
#define SECURITY_USER_ELEMENT 0
#define SECURITY_ROLE_ELEMENT 1
#define SECURITY_TYPE_ELEMENT 2
#define SECURITY_SENS_ELEMENT 3
u32 security_ctx_atoi(const char *ctx, const int i) {
char *a;
switch(i) {
case (SECURITY_USER_ELEMENT):
/* get the user element out of ctx string */
case (SECURITY_ROLE_ELEMENT):
/* get the role element out of ctx string */
case (SECURITY_TYPE_ELEMENT):
/* get the role element out of ctx string */
case (SECURITY_SENS_ELEMENT):
/* get the sensitivity element out of ctx string */
}
return security_element_atoi(a);
}
And a function that can translate the string representation to the int:
u32 security_element_atoi(const char *a) {
/* code here that translates a user, role, type, or sensitivity string to an int */
}
Thoughts?
:-Dustin