m5d@bobkat.UUCP (02/03/87)
In article <1169@steinmetz.steinmetz.UUCP> davidsen@kbsvax.UUCP (william E Davidsen) writes: > >If you allocate a full 64k to data, there is hardware protection: you >can't address more than that. This assures that any program which >doesn't deliberately set out to cause problems will not modify the >code. ... What about a program with a bug in it? Like "strcpy(a, b)" when "a" is not quite what I meant? It's real easy to make this kind of mistake; how many times while debugging a program on a VAX (or whatever) do you get SIGBUS or SIGSEGV? All it takes is a bad value passed to a routine which expects a pointer. This won't happen in a finished program, but it's not unlikely in a program under construction. To me, the most irritating thing about non-MMU systems is that a simple bug can cause me to wait 5 (or 10 or more, depending on the system) minutes to re-boot -- not to mention possible problems with the disk. For example, let's say I've got a program that goes a little bonkers and writes into a memory location that it shouldn't touch. Let's say (by admittedly slim chance, though not at all impossible) that the memory my program attacks happens to contain a block of data in the disk cache waiting to be written. When it gets written out, BLAMMO! My directory structure may have just bitten the dust. -- Mike McNally, mercifully employed at Digital Lynx --- Where Plano Road the Mighty Flood of Forest Lane doth meet, And Garland fair, whose perfumed air flows soft about my feet... uucp: {texsun,killer,infotel}!pollux!bobkat!m5d (214) 238-7474
m5d@bobkat.UUCP (02/04/87)
In article <511@bobkat.UUCP> m5d@bobkat.UUCP (Mike McNally (dlsh)) writes: >In article <1169@steinmetz.steinmetz.UUCP> davidsen@kbsvax.UUCP (william E Davidsen) writes: >> >>If you allocate a full 64k to data, there is hardware protection: you >>can't address more than that. ... > >What about a program with a bug in it? Like "strcpy(a, b)" when "a" is >not quite what I meant? It's real easy to make this kind of mistake; >how many times while debugging a program on a VAX (or whatever) do you >get SIGBUS or SIGSEGV? > >All it takes is a bad value passed to a routine which expects a >pointer. ... > > me Duhhhhh. Sorry. I just realized that the worst that can happen from a bad call to "strcpy" is that stuff beyond the logical end-of-segment (but within 64K of the base) could get trashed. If pointers are only 16 bits, it's hard to change the segment base value. Duhhhhh. Sorry William E. Davidsen. I just get carried away sometimes. AH! I could of course pass the address of a function to strcpy... Unlikely, but possible. I guess my point is that although it's not real easy to crash the system, it is possible, and the results are potentially bad (like a messed-up file system). But this is not my primary concern in life. If somebody wants to use this kind of a system, and they're happy, then so am I. Here's a more constructive question (which may have been answered, but I missed it if so). Does Minix provide a graphics interface to the screen of the PC? It would be nice if the "plot" routines worked. -- Mike McNally, mercifully employed at Digital Lynx --- Where Plano Road the Mighty Flood of Forest Lane doth meet, And Garland fair, whose perfumed air flows soft about my feet... uucp: {texsun,killer,infotel}!pollux!bobkat!m5d (214) 238-7474
perry@omepd.UUCP (02/07/87)
In article <1169@steinmetz.steinmetz.UUCP> davidsen@kbsvax.UUCP (william E Davidsen) writes about the protection of parallel MINIX processes by using the 8086 segment registers: > >If you allocate a full 64k to data, there is hardware protection: you >can't address more than that. This assures that any program which >doesn't deliberately set out to cause problems will not modify the >code. ... All right. Let's assume that all our little MINIX processes are well-behaved, i.e. they don't touch their segment registers that have been set up by the OS. Let's further assume that we have split I/D space, i.e. that code and data/stack segments do NOT overlap. (If they do, any stray pointer can CHANGE my code into a FAR jump or call... and here goes my protection.) Now the idea of our poor man's hardware protection is that we never write to the code segment, only to the DS/SS/ES segments that are identical. So we can indeed be sure that our process never modifies its code (which is fine because it allows text sharing and simplifies demand paging of code) and likewise never modifies memory in other processes, including the OS. Good. Unfortunately, the stack is part of the data segment. Remember CALLs? The return address INTO THE CODE SEGMENT is written onto the stack and used upon return. If, by accident (read: bug), you smear garbage over your stack, you are liable to clobber some return address. When the return occurs, you will happily jump to a random location in the code segment. This is likely to be the middle of some instruction, or a constant. [You CAN put constants in the code segment and access them with segment overrides as long as you don't need a pointer to them!] Again, this random instruction may accidentally modify my segment registers and clobber whoever happens to be out there. Don't say that's unlikely. Besides the MOVs to segment registers, there are the FAR jump, call and return instructions that all change the code segment, the LDS and LES instructions that change DS/ES (clobber, clobber!) and some others. Consider that at that stage, your program is executing random code, i.e. running around in circles and screaming. When it executes some millions of instructions per second, it has quite a chance to hit one of those critical instructions eventually. (Of course, it can also just hang in a closed loop.) By the way, accidentally hitting a CLI (disable interrupts) instruction kills you too (it disables the clock interrupt that activates the MINIX kernel!). Some other ways how random instructions can disrupt the machine are left as an exercise to the reader. Incidentally, there IS a way out! All we have to do is to separate the stack and data segments. If these two segments do not overlap, bad pointers and our other favorite bugs cannot disrupt the stack. Unfortunately, this means that the stack is outside our 'data address space' and can no longer be used to hold automatic variables. We would have to split the stack into a *control stack* in the stack segment, holding subroutine return information, and a *data stack* that is allocated in the data segment and holds automatic variables. We'd have to use SI or DI as a 'data stack pointer' (BP implies the stack segment, and always using segment overrides is no fun), interfering with their use in string instructions. Processes would become significantly larger (we'd have to allocate 64K for the stack segment, or else a stack overflow would overwrite something) and slower (stack management gets more cumbersome). Note that even with split stacks, we are STILL vulnerable to undisciplined PUSH and POP operations - a PUSH AX followed by a RETN (near return) is the perfect recipe for a runaway program (see above). But that's nothing new - any assembler programmer can screw up MINIX with ease, anyway, and our C compiler just has to keep its PUSHs and POPs straight. Oops! That's gotten longer than I intended. My apologies to those who aren't so interested in the lower pits of the hardware. If you can see where I went wrong, tell me. Flames per mail, please. -- perry ------------------------------------------------------------------------ << Perry The Cynic >> ...!tektronix!ogcvax!omepd!inteloa!perry ...!verdix!omepd!inteloa!perry (Peter Kiehtreiber) -or try- perry@inteloa.intel.com