Friday, February 18, 2005

The IOCW hack

Setting the scene

The time is the early 1970's. The computer, a Honeywell 6000 running the GCOS operating system. Some characteristics of this system:

Addressing space was 18 bits, but fortunately the addressable unit was a four byte word so addressable space was one megabyte (where a byte has nine bits, but that's irrelevant). The OS had virtual memory but individual processes were still limited to the 1M space.

The system had a separate I/O processor (known as the IOC) that handled all input and output. The IOC was progammable using a very limited instruction set (I/O control words (IOCW)). To perform I/O you created one of these programs in your memory and asked the IOC to execute it. You could do scatter/gather I/O using IOCWs. You could also branch (but not conditionally) from one set of IOCWs to another.

When an application requested I/O the OS validated the IOCW's then started the I/O. The OS handled interrupts and status coming back from the IOC, then passed the results (and a limited form of interrupts) back to the application.

The Problem


Memory is at a premium, and dynamic memory allocation is tough in assembly language. Where do you put the IOCW's?

The Hacker

Jim Mettes (who happened to be my boss at the time.)

The Hack

Put an IOCW directly in the read buffer. The IOC fetches the instruction from the buffer first, then reads the data into the buffer -- overwriting the IOCW which is no longer needed. Four bytes (the size of an IOCW) saved!



At this point you should decide for yourself where this hack rates on the slimey to righteous scale. Zero is ultra-slime and 10 is mega-righteous.



The rest of the story.

Consider what happens when a recoverable I/O error happens. The IOC reports the error. The OS determines that it is retryable and asks that age-old question: "Abort, Retry, or Ignore?" In this case the question goes to the console operator, not the person running the program. "Retry" says the console operator because that's what his proceedure manual says to answer.

The OS tells the IOC to try again. The IOC refetches the IOCW -- but it's been overwritten by the data from the previous attempt. Remeber the point about the OS validating the IOCWs before issuing the I/O request? Guess what the designers of the OS forgot to do during the retry? If you were lucky you ended up with a core dump of your application. If you weren't quite so lucky the system administrators ended up with a core dump of the whole machine and came looking for your head!

The Score

I give it a 1. High danger, low payoff. And how do you tell your boss about it?

No comments: