tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: secmodel_register(9) API



On 29.11.2011 14:25, Matthew Mondor wrote:
I admit not having audited the kauth and secmodel code recently, the
last time being shortly after Elad's initial implementation, please
bear with me if some observations are irrelevant:

   There are various ad-hoc calls to printf() which could probably be
   replaced by a more generic function call also resolving the error
   number to a string matching the constant i.e. secmodel_perr(int
   errno, const char *function); or similar, possibly wrapped by a macro
   using __FUNCTION__ avoiding the redundant function names
That can be done.

   The initialization functions, such as secmodel_keylock_init(), will
   report an error in the dmesg but do not propagate errors (they're
   void functions, suggesting the caller will not suspect anything).
   Should not the system panic for similar security critical failures?
   I think that I saw a similar situation under the various "case
   MODULE_CMD_INIT".
For keylock secmodel (which does not use the module framework), panicing 
would be better, definitely.
For the other modules, that depends on the functions; usually, 
_init/start initialize and register listeners, but an error can be 
returned and will be handled by module framework (like we do with 
secmodel_register() for suser and securelevel).
   When seeing the strcasecmp() calls in the eval_* functions for names
   such as "is-securelevel-above" or "is-root", my first impression was
   that integer constants, macros, or even a system of interned strings
   and references would be nice.  Then it struck me that if the goal
   was to export these, exporting actual variables might be best
   (although in any case, exporting these seem to somewhat defeat
   kauth-style centralization.  But if I understand, this is not for
   general use in the kernel, but for use by other security models?  If
   so, it's not so much out of scope in the sense that it remains in
   sys/secmodel)...
I don't follow you there: what do you mean? replacing strings with 
ad-hoc integers? Secmodel documentation to explain how these commands 
should be interpreted? Something else?
However, I've always found its design to be slightly too dynamic,
perhaps too much of an interpreter (and those eval_* functions make it
even more so).  Then there is all the C code dedicated to attaching,
detaching parts to the "program tree" at runtime, etc.  Although I'm
not familiar enough with the original Darwin implementation, that is
probably similar there.
Hmmm, the "dynamic" part here is too allow querying for state (and even 
setting, if there's a need to), without putting any requirement on the 
presence of a secmodel.
Usually, higher level languages come with a runtime that allows to query 
for module/instance states safely, and handle exceptions that could 
occur when the element is absent or invalid.
In C alone, we can't. You have to find a solution around this 
limitation, and this is the sole purpose of this API: query a secmodel 
and allow the API to return an error when the secmodel cannot handle the 
request, because it's either not loaded or non existent.
We could also design the API to use the in-kernel linker to access 
secmodel variables, but this had two downsides:
- you have to expose a symbol for the thing to be resolved
- you cannot implement complex logic, where you need argument evaluation by the targetted secmodel (suser "is-root" is a good example).
Since this is security related, it would not be unreasonable if the only
possible runtime changes were user/admin configuration (module-specific
sysctl configuration knobs, file system permissions, PaX flags, etc).
This means that the final runtime security system could be statically
generated at compile-time.
Make them into builtin modules. You won't be able to unload them any 
more, and the secmodel_eval(9) is still there to send requests between 
secmodels.
Security people usually turn off a number of dynamic options in a 
kernel, from modules loading/unloading, BPF filters, uneeded drivers and 
protocols, etc.
Dreaming ahead along that path (this part could still be possible with
an interpreter-like model though), it might be possible to create a
similar system, centralized yet modular (not at runtime, but for
human-friendly organization), to design and use a simple mostly
declarative language to edit and represent security models, then
compile that representation to static code.  The input could be more
elegant (also more easily allowing to define the domains and their
authorize interface, any hierarchies, etc), the output could permit a
more efficient runtime (generating unrolled code where wanted rather
than loops running among hooks lists)...  And of course there could be
specialized static analysis and test tools to warn model designers of
possible shortcommings in their designs.  With finally a preprocessor
tool so that it'd be possible to embed the language with C code, where
necessary...
FLASK/Fluke? Now, if you like complexity...

But then again, I'm only pipe dreaming, and that's always easier than
implementing any of that, of course :)
Beware of dreams that can turn into nightmares :)

--
Jean-Yves Migeon
jeanyves.migeon%free.fr@localhost


Home | Main Index | Thread Index | Old Index