Linas Vepstas wrote:

>-- if 'exception 04' can be caught and passed back up to the library,

Unfortunately it can't, as key-protection violation is a 'terminating'
exception condition, which means the CPU state at the time the
interruption is delivered is undefined. This means that the instruction
that caused the exception might have already been *partially* executed,
but there's no way to find out whether and to what extent that happened.
The only thing you can reliably do in that situation is to terminate
the process.

This is as opposed to a regular protection violation, which is a
'suppressing' exception condition, i.e. the interruption is delivered
with a CPU state corresponding to the state before the start of the
instruction causing the exception.  This allows the kernel to fix up
whatever caused the fault and restart the instruction.

>Aside: In some varients, the access was per-thread.

Now this is distincly weird ;-)  I would imagine this made the
implementation much more difficult (aren't threads supposed to
share the same address space? ;-/), and I can't quite see the
security benefits as any non-privileged thread could 'take over'
the privileged thread by overwriting the code that this thread
was currently executing ...

>Last I heard, when a similar proposal was made for adding this to the
>Linux kernel, Torvalds called it a "stupid idea" (he didn't think
>per-thread storage should be done that way.)  So even that did not
>fit well with 'traditional unix concepts'.

Well, I certainly agree with Linus as to the per-thread thing
here ;-)  However, if we are simply talking per-process, I think
something like this is already now in the Linux kernel: the
direct-rendering module (DRM) extension uses a special X server
module in conjunction with kernel support to provide a similar
facility to user-space processes AFAIK (on cards that have
the required hardware support, of course).

>If you mean, "how can we automatically check that the arguments to a=20
>subroutine call have valid values",  I don't know of anyway of doing
>this easily at run-time, and there are only limited tools at compile-time.
>But this is a generic problem, and not limited to this discussion.
>e.g. in gnome, (gtk, and in glib2 'gobjects'), there are C macros=20
>that you are supposed to use that perform run-time type checking
>and type-casting.

Well, I was not so much thinking about programming errors, but more
about deliberate attempts to trick the trusted part into violating
security.  For example, on Intel the kernel address space is
actually part of the process' 4 GB address space, it just isn't
accessible.  However, imagine a malicious user space application
performs a write system call and passes a buffer address that
points to some *kernel* address (i.e. above 3 GB).  If the kernel
would now naively fulfil the write request, it would access the
data to write (which is now, in kernel context, perfectly
readable) and put it into the file.  User space could then
read the file back, and -voila- it has accessed memory it should
not be allowed to access ;-)

While this problem is well-known to kernel programmers, even now
there are sometimes new security exposures found due to this
type of failure to validate syscall arguments ...

>?  Huh?  A unix 'system call' is still expressed as a standard C
>function call, although the 'linkage' is certainly unusual in that
>it involves an SVC, and argument passing happens quite differently
>than as in between 'ordinary' C calls.

Well, what is expressed as a standard C function call *is* in fact
a standard C function call, namely to a function implemented in
libc (which actually performs the real SVC system call).  As to
the calling convention of the SVC itself, we cheated by disallowing
more than 5 arguments, so that all arguments can be passed in
registers (if there are more than 5 arguments, the libc stub
packs them into a struct and passes a pointer to it to the SVC).

>The 'performance' argument is difficult to win, or loose, since OS
>weaknesses and strengths fundamentally alter how one goes about
>designing applications & libraries.

Indeed.  One should never make performance arguments without
having actual measurements as support; I've been bitten by
'I think this should be faster' arguments before ;-)

>The 'features' argument is quite different. Clearly, the creators of
>apache accept and trust all apache modules. Would they still do so
>if it was 'easy' not to trust them? I suspect not.

On the other hand, if it was important to them to establish a
trust boundary, they could easily do so by running modules as
separate processes; AFAIK the main task of a module is to
create a stream of bytes to be returned to the remote user,
so the interface would naturally fit a pipe/socket-based
inter-process communication mechanism ...

But I guess if you can't trust the module, you can't really
trust the whole server, as the module is the instance that
generates the data the user actually sees.

>Can one create
>a trust-boundary between apache and apache modules that is easy to
>use, and relatively foolproof and flexible? I don't really know,
>but it is the premise of this coversation that one can.

This is exactly the point where I'm a bit more skeptical; I don't
think a real trust-boundary can ever be easy to use; at least on
the trusted side one always need to be very aware of what's going
on (e.g. argument validation etc.).

It certainly would be nice to have something like that; but I
definitely agree with you that:

>I suspect that the argument has gotten to the point of actually needing
>some sort of prototyping and fooling around just to see how
>workable/unworkable it really is.

Bye,
Ulrich

--
  Dr. Ulrich Weigand
  [EMAIL PROTECTED]

Reply via email to