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