On Mon, Nov 11, 2002 at 08:40:45PM +0100, Ulrich Weigand was heard to remark: > Linas Vepstas wrote: > > Every page of memory has a storage key, which holds a key and a > fetch-protection bit. If the fetch-protection bit is cleared, > then anyone can read the page; if the fetch-protection bit is > set, only code running with a PSW key equal to the page key > can read the page. So I guess you could make pages read-only > to everyone. > > Still, the question is whether read-only access is enough; a typical > library function interface is: here's a buffer, please write some > data into it.
-- if 'exception 04' can be caught and passed back up to the library, then potentially the library can decide what sort of access should have been allowed: none, read-only (change fetch protection bit), and read-write (change key). -- its important to distinguish what the 390 can do today, from "what could be done if *it* (whatever *it* is) was done right". I am guilty of mising up these two. > >OK, I presented a spcific example, from the land of graphics hardware, > >from the mid 1990's, where these traditional unix solutions completely > >failed. [...] > the same: this process. Aside: In some varients, the access was per-thread. > Therefore it easily fits into the whole > Unix access rights concept. Hmm. To implement this stuff, we needed to design some fairly sophisticated kernel modules, and make some changes to page & process tables. The unix guys screamed bloody murder at the time. 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'. > What you propose is a finer-grained X (not 'this process' but > 'this process while it is executing code mapped from this library'). > This is what IMO is the core problem of this idea. > > To stay with your example: why didn't you change the system so that > a process was allowed to directly access the (whole) video memory, Because we didn't trust the process > but only why it was executing code from a special, trusted video > library that ensured it didn't do anything it shouldn't? That > would have been comparable ... Because there is no way (in todays unix, in (most of) today's cpus) to trust a library. We might have argued for fundamental changes in the CPU design, if we'd figured this out earlier, but it was too late for that, and besides, as this conversation attests, new ideas are not easily accepted when it comes to the architected interface of a CPU. The app did have to use a special graphics library which made some special kernel calls to set things up. Once set up, we used a page-fault-like mechanism to serialize access to the graphics hardware. i.e. only n apps could have direct access, the (n+1)th would page fault. We'd use time-slices to make sure all n+1 had a shot at running. > Yes, but what about the difficult questions? ;-) Dunno. Wish I had enough time to think about this properly, try some prototypes, etc. As stated before, I'm not convinced that the 390 in its current state can really support the idea. It seems to have at least some of the pieces. > Where are the > arguments passed and returned? Where does the stack reside, and is > it switched at function call or not? Dunno. > [If yes, the standard C calling > convention doesn't work any more -- what to use instead? ? 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. If done right, with all the bells & whistles, one would need to have a way of informing the linker that this is a 'special' call, and to insert some different subroutine glue code. > How to avoid tricking the xlib into doing bad things by passing incorrect > arguments to it? Well, certainly, one can check argument validity manually. The x server does this by examining each packet it receives, and doing bounds checks, etc. There is a fair amount of programmer-hour overhead to do this. If you mean, "how can we automatically check that the arguments to a 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 that you are supposed to use that perform run-time type checking and type-casting. There's also crap in there for marshalling and closures and etc. that are handy for ensuring program correctness. But I view this as a language design issue, since the closure thing is more important java and scheme than it is to C. > I think in this particular example, those questions might be solvable, > because the current design already has a clear separation in place. > So you'd for example just continue to do the same validity checks on > arguments that the X server currently does. Yes. > Also, the data is currently > already prepared for passing across a socket, so you don't need to > pass complex data structures containing pointers; this means it > would be easy to pass just a single data block across the protection > boundary. Yes. :-) > But if you do that, you basically have exactly the same scenario as > now, except that the read/write across the socket is replaced by > a program call (plus possibly some other actions like stack switching; > in fact you might even need to perform a system call to inform the > kernel that you're now in another protection domain). So what does > all this buy you? A context switch on Linux is already quite fast, > and while a program call might be a bit faster, it is also a complex > milli-coded instruction that takes hundreds of cycles AFAIK, so I'm > not convinced this gets you a huge increase in speed ... (This holds > even more if you do need a system call; a system call with or without > a context switch takes about the same time, at least on S/390.) Yes. And maybe some hypothetical future cpu could make this faster, but that is besides the point. Recall, there's both a 'features' and a 'performance' side to my argument. On the 'performance' side, one should focus on the X11 XShm extension, which uses shared memory to pass pixmaps between client and server, thus avoiding the socket overhead. The other hypothetical example I gave was the direct-access database, the point being that direct memory access is much faster than a subrutine call, no matter how fast that call may be. On the 'features' side, the example was one of giving, e.g. the apache web server the ability to protect itself from a rogue module. The cost in performance is presumably worth the gain in protection. The 'performance' argument is difficult to win, or loose, since OS weaknesses and strengths fundamentally alter how one goes about designing applications & libraries. If unix had a way of securing libraries 10 or 20 years ago, you can be sure that many applications would have been designed differently from the ground-up today. But its hard to say which ones, since clever programmers find ways to work around the limitations, usually by using fundamentally different paradigms. (I once saw a presentation on the strange new world one could have if one could make the 'private' part of a C++ object truly, securely private. The vision was a trully strange and fantastic one. Perhaps I am swayed by this memory.) 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. 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. 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. Wish I had the time to play with this .... --linas -- pub 1024D/01045933 2001-02-01 Linas Vepstas (Labas!) <[EMAIL PROTECTED]> PGP Key fingerprint = 8305 2521 6000 0B5E 8984 3F54 64A9 9A82 0104 5933
