Friday, January 02, 2004
Security and ACLs
Just a random thought
Well, I was thinking about LSM and RSBAC and grsecurity ACLs and such, and I came up with a question. How exactly does it work? So I sat down for 10 minutes with Dia and came up with how I would do a modular ACL system if I had come up with it. Here's my brain-dump.
Keep in mind that this isn't meant to be based on anything out there, nor is it meant to be an actual idea for a new one; it's just something I randomly spit out.
The basic idea is this. There is a single exported function sec_register_module(secMdFctnCheck *smfctn) that registers the decision making function of the security module and returns the moduleId of the module. When a module is loaded, it registers itself via this function. The module is not placed at any level and is never consulted because it has yet to be placed. The placement is not done with a parameter to sec_register_modules() because the module may by some twist be malicious (think about loading modules via /dev/kmem and such; even though these may be secured via ACL, this is not a certainty).
Then the security administrator runs a process which calls the sec_set_module_level(moduleId, moduleLevel) syscall and moves the module to an appropriate level. Now the module is ready to run.
Now to explain the process relavent to the above flow-chart.
The lowest (i.e. most embedded) level, 0, takes top priority. From there, priority steps down to whatever the highest (i.e. most removed) level is. Thus, an allow or deny at level 0 is effective regardless of whatever is at any other level; as is an allow or deny at level 5 regardless of anything at levels 6 and above.
Each access to a file runs through all modules in no particular order at each level, from the lowest level to the highest. Each module is given the User ID and Group ID of the user; the Filesystem that the object is on and its Inode (to positively identify the object); and the Operation the user wishes to perform (read, write, execute, delete, append). After processing, each module returns one of three states. The three states any module may return are Explicite Allow, Explicite Deny, and No Allow.
Explicite Allow means that this module affirms that the user has the right to access the data in this manner. An Explicite Allow is subject only to modules at its own level or lower levels, and thus may only be retracted by an Explicite Deny. Explicite Allows are effective if and only if they occur on a level less than any and all Explicite Denies. In the basic sense, if there are no explicite denies at lower levels, and if there are no denies at the current level, then the operation is GRANTED (allowed).
Explicite Deny means that the module affirms that the user does NOT have the right to access the data in this manner. An Explicite Deny immediately stops the processing of security modules and exits the security check loop, denying access. The operation is DENIED. Explicite Denies are not effective at levels higher than any existing Explicite Allows; Explicite Denies are effective if and only if they occur at a level greater than than or equal to that of any and all Explicite Allows.
No Allow means that the module does not grant access to the data for the given operation to the user. It also means that the module itself does not deny access. At any level, if all modules return No Allow, that level is a No Allow level. No Allow has no effect on Explicite Allow and Explicite Deny states in other modules; however, if after all modules have been processed the final state is No Allow (no modules return Allow or Deny), then the operation is DENIED.
At any level, the state that is reached at the end of all relavent processing of modules is that Level State. For example, if level 3 reaches an Explicite Allow from any modules and all other modules return a No Allow state, that level has an Explicite Allow Level State. Processing proceeds to the next level if and only if the Level State is No Allow. When processing ends, whatever the Level State of the last processed level is becomes the Final State.
Under normal circumstances, the highest level would contain a module to anylize normal POSIX permissions (those set by chmod). This way a final state of No Allow will never be reached; if no modules have any decision on an object, the DAC system will make the decision. However, this module could optionally not be used, thus requiring a MAC system to be in place.
The basic aim here is to find the central connection point of each filesystem operation and insert hooks there that simply ask for any of these three states. Hopefully, there'd be no constraints put in placeby something like this; each module would bring all of its own rules, configuration syscalls, decision making functions, etc. The only thing that would need to be supplied would be a kernel-level filesystem object access function that evaded the security checks, so that the modules could read their data from and write it to the hard drive.
The operations would have to include things such as actually displaying and accessing certain filesystem objects (i.e. the /rsbac directory made by RSBAC, which RSBAC likes to make sure ls doesn't display), but the whole thing could just be expanded as needed.
Once again, this is just something I spit out randomly, and has nothing to do with any existing systems, nor does it pretend to wish to compete with anything currently in place or in development.