11 ms·
Interesting. Is this in practice implemented as just capabilities being large numbers so it's impractical to guess them, or does the kernel have a table with al
by why_only_15 4y ago
Interesting. Is this in practice implemented as just capabilities being large numbers so it's impractical to guess them, or does the kernel have a table with all of a process's capabilities and when a message is sent to a process with capabilities the kernel adds them to the table?
That is -- are capabilities just pieces of data in a message you can detect and try to use, or do they have to be added explicitly to a message to send them
- giyanani 4y agoI’m not sure how fuschia does it, or how feature-based capabilities work, but Cheri[1] uses capabilities for memory management and isolation. It uses a couple of techniques, like wide/tagged pointers, object ids, and a special hardware managed bit to track illegal modifications. If I had to hazard a guess, those object ids are probably useful for general capability systems. I think apple (maybe as just an arm feature?) can do encrypted pointers, with a per application key tracked by the kernel. [1] https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/ https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
- zahllos 4y ago> I think apple (maybe as just an arm feature?) can do encrypted pointers, with a per application key tracked by the kernel. ARM has added both pointer authentication codes and memory tagging extensions to their ISA, from (I think) ARMv8.5-A. Apple are the only ones to implement silicon that supports PAC that anyone can buy today but a) this will change fast and b) I might've missed something else. I wouldn't say "encrypt". You can still read what the pointer is, you just can't forge it. It is more like a message authentication code, or keyed hash. Confusingly, the ARM ISA suggests you use the block cipher QARMA, a lightweight block cipher of their design. This is not a mistake - from a crypto academic's perspective the distinction between block cipher and hash is not so easy to draw as it tends to be communicated: you can get a block cipher out of the SHA family of hash functions (called SHACAL) and so on. There was a line of work on finding a suitable family of permutations (e.g. Gimli) that could be hardware-accelerated and appropriate constructions built from that. tl;dr it is kinda a "signed pointer", and if you forge the pointer but get it wrong you don't get another chance because the CPU triggers a fault, so you can use lower security lightweight ciphers and still make exploitation very unreliable. Now Fuchsia: As to how Fuchsia does it, we can just look at the source: 1) https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/kernel/object/include/object/job_dispatcher.h#265 https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/z... 2) https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/kernel/object/include/object/job_policy.h#18 https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/z... 3) https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/syscalls/policy.h https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/z... For example. I don't think there's any magic here: the kernel maintains some structure to reference jobs, tasks or whatever we are calling our isolated privilege boundaries, in which the capabilities are described. On the face of it this "looks" a lot like the traditional permission-style system, but the key difference is that the root job will hand out capabilities to processes it has created. An example is probably the best way to proceed: on a linux system, you might decide your process needs to read `/system/sensitive_file`. To allow this to happen, you might grant access to the user using some other command: chown .../chmod ..., or you might set an selinux policy, semanage fcontext -a -t myprocess_t /system/sensitive_file. In a capability-based system, chmod/chown and even running the process as a user don't exist as concepts. You would need to use a process authorized to transfer a capability to your target process to access this file. In some ways, this is closer to selinux, in the sense that semanage fcontext updates policy, except that the policy is somewhat dynamic here: if your controlling process provides the capability, then the child process gets it. In a microkernel-based architecture, the idea is that "servers" (jobs that are arguably part of the system, but don't need to be in kernel) are similarly userspace processes subject to said capabilities also. Of course, some part of the code still needs to be privileged here, let's call it the "executive". This code is doing the capability enforcement, and if that code contains bugs, all bets are off, as always. You can't defend such code from itself, even with capabilities. The real disappointment is that Zircon is written in C++. Granted it was probably started before Rust was a thing, but while Ada/SPARK might be considered a bit unfashionable, it has some formal verification available, and if you're going for a software solution this should help reduce exploitable bugs. Personally I also wonder what about seL4 made it unsuitable for this: granted, it is not complete as a system, but neither is Zircon alone.
- conioh 4y ago> ARM has added both pointer authentication codes and memory tagging extensions to their ISA, from (I think) ARMv8.5-A. Apple are the only ones to implement silicon that supports PAC that anyone can buy today but a) this will change fast and b) I might've missed something else. I'm not aware of other generally available chips with pointer authentication. The Qualcomm Snapdragon 8cx Gen 3 supposedly support PA. The Lenovo ThinkPad X13s supposedly contains it, but when will it actually be commercially available is anyone's guess. Also, I think it's ARMv8.3.
- pjmlp 4y agoApple isn't the only one, Oracle did it first with SPARC ADI on Solaris.
- zahllos 4y agoTrue. I was mainly responding to the ARM encrypted pointers part with that bit. ARM also didn't invent memory tagging, which might also have come from SPARC ADI (I'm not sure), but they also plan to include that. QARMA itself looks to be designed by Qualcomm engineers: https://eprint.iacr.org/2016/444.pdf https://eprint.iacr.org/2016/444.pdf A lot of good stuff has come from SPARC :)
- saagarjha 4y agoPAC is ARMv8.3, and Apple implements their own custom algorithm rather than QARMA.
- zahllos 4y agoYeah, ISA says you can. I wouldn't be surprised if other people pick other implementations, I'm not entirely sure why ARM felt the need for QARMA in the first place given there are already extensive choices for lightweight block ciphers, but... there you are.
- jamesr_ 4y agoThe kernel maintains a table of which handle values each process owns and uses that to check the capabilities of the calling process when handling a syscall. Sending a capability in a message updates this table as the ownership changes. We use (somewhat) large and non-dense numerical values for handle values to reduce the risk of accidental reuse of values.
- throwawaymaths 4y agoIn theory you could do even better than that -- you could make capabilities cryptographically signed tokens, so that you don't need to ask the kernel to verify the validity of your request every time. If your chipset supports crypto intrinsics this will almost certainly be better than an interrupted syscall.
- jnwatson 4y agoNot even theoretical. An early capability based OS called KeyKOS worked that way.
- throwawaymaths 4y agoOh man KeyKOS, that brings back memories. I wonder if crypto intrinsics might breathe life back into something like KeyKOS. More contemporary, I think Sel4 does as well. In my comment I meant "in theory fuscia could have been architected/could be rearchitected that way", sorry should have been more clear.
- staticassertion 4y agoYeah, reminds me of biscuits[0] - because they're based on asymmetric cryptography they can be delegated, but also attenuated. If you just use a uuid that's not really going to work as well, unless you're willing to go back to some authority to forge a new, lesser capability.
- formerly_proven 4y agoYou know a limited kind of capability - file descriptors (or kernel handles). Those are just a number that allow you to manipulate some object in a defined way. You can give this number to someone else, and they can't make use of it at all, you have to go ask the kernel (using e.g. a unix socket and ancillary messages) to pass the capability to another process.
- staticassertion 4y agoThat is sort of the opposite of a capability. In fact, files are capabilities exactly because you can hand off a file descriptor and, by virtue of that handle, you grant access. File systems aren't actually capability based (generally, in practice) because you can 'ls' and 'cd ../'. Otherwise they could be. Dropbox Paper is a good example of a capability based system. Anyone with a URL can perform actions on a page, but there is no way to derive a URL without already having access to it, you must be told what it is. This is because the urls are sufficiently random so as to be unguessable.
- trasz 4y ago>File systems aren't actually capability based (generally, in practice) because you can 'ls' and 'cd ../'. Otherwise they could be. That's precisely how it works in FreeBSD (https://www.freebsd.org/cgi/man.cgi?capsicum https://www.freebsd.org/cgi/man.cgi?capsicum).
- staticassertion 4y ago"generally, in practice" There's also openat on linux. My point is that the general, practiced approach is not capability based.
- trasz 4y agoIt it’s not capability based, because Linux doesn’t provide necessary functionality. FreeBSD does, as explained in the man page I’ve linked to.
- monocasa 4y agoIt's per process like the file descriptor tables under most kernels. Knowing that some other process has a certain socket open as fd '5' on their fd table doesn't give you enough information to attach the same socket to your fd table at fd 5 or otherwise.