Page 1 of 1

Capability-based security discussions

Posted: Wed Jul 11, 2018 9:08 am
by Schol-R-LEA
I need to head out shortly, but I did want to create this thread as a discussion topic, as it had come up in the segmentation thread. Fee free to discuss capability systems - hardware or software - in as much detail as you feel reasonable.

I'll quickly aggregate some previous discussions on the topic:
from the thread "Memory Segmentation in the x86 platform and elsewhere":
Schol-R-LEA wrote:Capability-based addressing would be part of the memory protection as well, being basically a more fine-grained form of the same memory protections, except that it checks the source of the access rather than the element being accessed. Since the burden of proof is on the requester, rather than the object's state, it turns the entire approach on its head, and becomes a lot more flexible and secure.
Schol-R-LEA wrote:
Qbyte wrote:
Schol-R-LEA wrote:And I really do still think that capability-based addressing would be a closer fit to your goal (and rdos's) than segments, either as a general concept or in terms of existing implementations, but since that seems to be even more of a dead topic than hardware segments, well... :roll:
I'm no stranger to the idea of capability based addressing, but as intriguing as it is, I've personally arrived at the conclusion of it just being a more convoluted and contrived way of enforcing access rights in comparison to segments. At the end of the day, an object is just a region of memory, so it makes the most sense to just explicitly define the ranges of addresses that a process is allowed to access and be done with it. Anything beyond that just seems like fluff. I'd love to be convinced otherwise, so if you've got any original, concrete points in favor of a capabilty based scheme, I'm all ears.
They aren't really comparable, IMAO, because caps shift the burden of proof from accessed resource to the one doing the accessing - if the process don't have a capability token, it can't even determine if the resource exists, never mind access it - it has to request a token from the management system (whether in hardware or in software), and if the system refuses the request, it is not given a reason why (it could be because the requester isn't trusted, or because it isn't present in the first place).
Qbyte wrote:In what way is that different from partitioning, aside from being more complex to implement and manage? With partitioning, each process has a number of regions in memory that it is allowed to access, and the "burden of proof" is on the process to obtain access to those regions in the first place. All that's required to implement partitioning is a simple memory protection unit that contains the base, limit, and PID tag for each region it supports. That's all. It's simple, fast, efficient to manage, and achieves the exact same ends as what capabilities do. Despite my best efforts to do so in the past, I fail to see what meaningful advantages a capability based strategy brings to the table.
linguofreak wrote:I actually started thinking about capabilities before I knew what they were called, in pondering what I didn't like about flat paging schemes, Intel pmode segmentation, etc.

Where I think the advantage of capabilities lies is that it can be more fine grained than just "this process can access these bits of memory", which is what you get with a fixed page table or segment table. With capabilities, you can have something like "No matter which process it is running as part of, this library can access this shared memory region, but no other code in that process can access said region". Depending on CPU architecture, your User/Kernel bit or protection ring number provides this on a very course level with a fixed and generally small number of possible privileged libraries (on many architectures just one, the kernel), but a capability architecture could be used to implement an arbitrary number of privileged libraries with disjoint private memory regions (rather than lumping them all into a monolithic kernel or scattering them into separate processes and requiring IPC for processes to request services from them, which are the alternatives on non-capability systems). That said, many capability architectures seem to have failed by trying to be *too* fine grained, often trying to do per-object capabilities (witness iAPX 432). On the other hand, the 386 was almost a capability architecture with the right coarseness, but didn't quite go far enough (hardware tasks weren't reentrant, LTR was privileged, segmentation could have provided capabilities, but didn't quite manage without hardware tasks, etc). A good capability architecture, I think, would support capabilities on approximately the coarseness of files, stacks, and heaps, and would switch between protection contexts without OS involvement on events like far jumps and stack switches.
Schol-R-LEA wrote:I am by no means an expert on capabilities, but according to those who are, the main issue is that any system based on access-control lists - that is to say, RWX bits set on a per-group or per-priority basis, and similar mechanisms - are vulnerable to a class of exploits referred to as a the 'confused deputy problem', while capabilities supposedly aren't. Again, I am no expert, but based on sources such as this one, the reasoning behind this assertion seems sound to me.

Also, capabilities are issued according to the process, rather than the user, and can even be issued per code unit. Thus, they are more fine-grained than the more common approaches - as linguofreak points out, it is possible to have a caps system in which some library code running in a process can have a capability, but the process as a whole doesn't.

Finally, since the system is deciding who to give a capability token to dynamically and programmatically, on a per-request basis, rather according to to a static set of rules, and can cancel a specific token or group of tokens at any time without changing the permissions held through any other capability tokens, the capability manager can react more flexibly to changes in the situation based on new information.

Or at least this is my understanding of the topic, based on those sources I've read. I don't know what you know about them, so I am posting this as much to make sure we are on the same page as anything else. Comments and corrections welcome.

As I've said earlier, this isn't specific to memory hardware, even for a hardware based capability mechanism. Capability-based security is a broad category that applies to limiting access to any sort of resource. Indeed, the most common examples given when describing caps (and AFAICT the most common actual applications of caps in systems using them) are regarding file system security.
I need to go right now, but I'll do more of this later. I will link to the thread "A (possibly) new aproach to capabilities" for further reference on my own understand and ideas, as well as some comments made on them.