[cap-talk] Security and languages talk
kosik at fiit.stuba.sk
Mon May 5 04:20:52 CDT 2008
I do not know how much my point of view matters but here it is:
(I am sorry for the length)
Ivan Krstić napísal:
> I'm directing much of my recently-gained spare time towards a few
> things I've wanted to work on for a while, but haven't had the time in
> the course of my breakneck two years with OLPC. One such thing is,
> after giving a bunch of high-profile talks about systems security,
> writing a short one about security and programming languages.
> The Boston Lisp folks invited me to give the talk on May 27th, so
> the audience is a fairly clueful programming crowd without any
> necessary prior exposure to language security and capability ideas.
> I'll be talking for 25 minutes: covering the basic ideas and looking
> briefly at things like E, Joe-E, Caja and CaPerl.
Most (all?) object-capability languages are at present in a deadlock. They will be used when they
become useful and they will be useful when they become used (because people will find (and fix?)
bugs, contribute with libraries, create awsome programs that will attract other developers. How to
break this deadlock is an interesting question. Certainly, even if these ideas are great, they will
not spread autonomously because the net-effect of the legacy is too strong.
> Questions for this crowd:
> * Have you seen any _great_ short introductory capability and
> language security talks before? What made them great?
> * What do you think are things that I absolutely must cover?
It may be interesting to point out what you loose and what you gain when you switch to some
object-capability language (or a "tamed" version of some original language).
Things you will probably loose:
- some time until you learn new things
(if these things were worthless, you would not gain anything, so one has to choose what to learn)
Things you will gain:
- raised consciousness
This projects into
- the way how you will structure your software with respect to robustness (security is one aspect of
robustness so that property is subsumed)
This all is too abstract (it can be understood only by people who already understand it) so it may
have sense to show some examples. The examples should be chosen with expected interest of the
audience so not necessarily those which I will list below (and in 25 minutes there will not be time
for many such examples):
It is an implementation of the (simplified version) of the traditional ping program. In Unix, ping
program must be run with superuser authority because it performs a certain system call (opeing a
socket in raw mode) which for some peculiar reasons cannot be done by normal user
<beyond the scope>
A whole separate talk could be devoted to such "security measures" which do not increase security
but decrease the comfort
</beyond the scope>
While nowadays nobody has a problem with the ping programs because it is open-source, anybody can
look at it, people indeed do that so noone fears. What we get is not arbitrary ping program but ping
program signed by our operating system distributor whom we all trust---we trust him and to everyone
in the Internet.
This is status quo and it need not to be obvious how to improve this situation to the audience.
If I rewrite the same (subset of) functionality in an object-capability language:
I have lost some things:
- not all languages are fit for this
but I have gained a little bit too. The whole functionality is split into:
- trusted part (which is part of TCB)
- untrusted part
is only a set of measures that ensure all the important things (untrusted component will have
minimal authority; trusted component will be allowed to have non-minimal (usually ambient) authority
and some way how to communicate capabilities from the trusted component to the untrusted component
to raise the authority of the untrusted component to a sufficient and acceptable level (unless these
goals are in conflict).
It has some implications for the programmer but I can confirm that it is not at all difficult to do
this in practice. People do not have to believe this automatically, but if they try they will see
that it is not a big problem. Actully, there is not more competent person to determine required
authority of a given program than its author. Anyone else would have only more problems.
Additionally, the programmer can during development change the design of the system so that not only
functionality will be delivered but POLA without pain can be followed. Securing existing systems is
much more difficult and this is what people do.
What is important, systems that are designed according to these principles have many positive
advantages for security auditors (original programmers, operating system distributors, independent
payed auditors and/or perhaps knowledgable users can make such audits).
The fact is, that we can safely assess the threat we face by examining the trusted computing base.
The hypothesis is that by using object-capability programming languages we can make TCB small. The
TCB will be proportional only to the complexity of the security policy, it will not be proportional
to the complexity of the whole system.
So, if I take the original ping program and count the lines of the TCB, I get:
cat ping.c ping_common.c ping_echo.c ping_address.c \
ping_router.c ping_timestamp.c ping_common.h ping_impl.h | wc -l
That is `1586' lines of code (at least). This is understatement because to in fact you would also
have to add the size of code of all functions from the standard C library used by this program etc
but since those functions are used in many places they were reviewed more carefully and they are
more trustedworthy than the software in development.
If you look at the "Powerboxed ping program" then its trusted part looks as follows:
(guest pr args socket alarm signals);
It has 8 lines. *This is what security auditor has to review.* He will be immediatelly able to
assess the threat. The untrusted (Guest) component
- holds the `pr' capability so it can print arbitrary things on the screen
- holds the `args' capability so it will be able to parse the command line arguments
- holds the `socket' capability so it will be able to open socket in a raw mode
- holds the `alarm' capability so it will be able to schedule SIGALRM signal for itself.
- holds the `signals' capability so it will be able to register handlers for any UNIX signal.
(if you know the what those other modules which export relevant capabilities do).
So even if we run a given program with the superuser authority, we can efficiently checks what part
of this authority is communicated to the untrusted part and we can assess the threat and thus decide
whether it is acceptable.
<people can object here>
People can object here, that the TCB is larger than 8 lines and they will be right. All those
*trusted* modules we directly or indirectly use co-form TCB. It would be indeed fantastic if TCBs of
realistic systems were that small. What can we (perhaps) "only" claim that with object-capability
languages our TCBs we can conveniently create *the smallest* TCB; not-exceptionally without
affecting the readability.
Consider for example the functionality that parses the command line arguments. It is split into
- trusted part (15 lines of code) that has access to `argc' and `argv' variables and makes them in
asome allowed (trivial) way accessible to ...
- untrusted part (140 lines of code) which implements and exposes high-level functionality for
parsing various command line flags and command line parameters of integer or strning type.
So the TCB does not grow as fast as the provided functionality---it grows only as fast as the
complexity of the security policy. That kind of complexity cannot be avoided anyhow.
Additionally, if you consider the size of libc than these objections seem void to me.
</people can object here>
The problem with most programs is that we cannot assess the threat we face. Consider the popular
program `gaim' (or `pidgin' on Debian) used for ICQ, jabber, MSN and such communication. It has more
lines of code. If it were programmed in an object-capability programming language, if it had 1000
lines of code I would regard it unacceptable. Many security policies would have to be factored out
to libraries (such as the ability to open sockets in some way; the ability to draw whatever on the
canvas but nowhere else; the ability to send sounds to the mixer). I think the real number would be
a hundred lines of code or something like that.
I am personally interested in using powerboxes to confine authority of kernel components.
It is my hobby project and one of the possible reasonable ways how to write operating system kernel
internally (regardless of its actual interface). There are certainly other ways (Coyotos) I believe
can also work work and there are other ways I have serious doubts about (Minix3, Singularity)
despite having similar goals (small TCB, robustness, simplicity).
It would be very nice to be able to follow POLA on Windows or on Linux but I do not believe that it
is possible. This does not mean that non-mainstream operating systems which (as a lighthouse) follow
these principles make no sense.
> * If this was your first brush with the relevant topics, what could
> I say that would really pique your interest?
>  <http://radian.org/notebook/maintaining-clarity>
>  <http://radian.org/notebook/talk-language-security>
Matej Kosik (http://altair.sk)
More information about the cap-talk