25

In an interesting crossover between current events and Retrocomputing, the vulnerability known as "Meltdown" was publicly disclosed on January 3rd 2018. The retro-computing tie-in is that this vulnerability is reported to impact all Intel microprocessors back to the 1995 release of the Pentium Pro (P6 micro-architecture).

In the late 1990s, the dominant OS's for Intel machines were MS-DOS, which was slowly being retired, and Windows 95 and 98, which were the replacements still underpinned by MS-DOS. Of course, Windows NT was also on the rise, but was most prevalent in enterprises. My question is which of these OS's were TECHNICALLY vulnerable to Meltdown, taking into account whether the OS offered any real attempt at memory protection?

My impression is that MS-DOS and Windows offered no such protection*. Therefore, it's arguable that they weren't actually vulnerable to Meltdown, by virtue of the fact that no such vulnerability needed to exist to allow a rogue process to access "private" data owned by other processes. If this is true, then what time-frame can we pinpoint when systems became vulnerable to Meltdown accounting for OS features that guaranteed memory protection?

*NOTE: I'm recalling dev tools for Windows, like Dr. Watson and Bounds Checker, that seemed to allow full access to process memory without any special privilege.

  • 2
    You're asking two questions. Please ask one question. – wizzwizz4 Jan 5 '18 at 21:39
  • 3
    I hear your criticism, but mainly I'm trying to dispute the claim that computers have been vulnerable to Meltdown since 1995. It's not a vulnerability if the system has no existing privilege that needs the exploit to bypass it. – Brian H Jan 5 '18 at 23:41
  • 15
    You don't need to pick the lock when the door doesn't even have one. Ms-Dos doesn't even have a door, 9x didn't have a lock on the door. – Loren Pechtel Jan 6 '18 at 3:00
  • 5
    If disputing that claim is the actual objective, the attempt falls at the first hurdle. Protected memory multiprocess paging-based operating systems for consumer PCs such as OS/2 Warp and Windows NT existed in 1995. A far more interesting question is whether Windows NT on MIPS or Alpha would have been vulnerable at the time. – JdeBP Jan 6 '18 at 14:01
  • 5
    "Your armor-piercing bullets cannot hurt me, for I am not wearing armor!" – user2357112 Jan 7 '18 at 8:35
34

The Meltdown attack is about figuring out what's in protected memory (typically, kernel memory) by arranging for it to be speculatively read, and then looking for residual side effects after the speculative read is discarded.

MS-DOS is immune to Meltdown because it doesn't do memory protection. If you want to figure out what's in RAM, you can simply look.

Windows 9x has a userspace/kernelspace split with kernel protection (and some bugs: parts of kernel-critical memory were left user-writeable, so a userspace program could bring down the entire system). The kernelspace memory mapping includes all of physical RAM, which means a Meltdown-style attack can read everything, just like it could on an unpatched Linux system.

  • 31
    I'm not sure I'd say that MS-DOS is "immune". It's more like Meltdown isn't needed, precisely because what Meltdown gets you around (memory protection) isn't a thing at all in plain MS-DOS. The rest of your second paragraph is certainly correct. – a CVn Jan 6 '18 at 13:40
  • 1
    @PeterCordes I believe Win 95 does try process isolation to a degree. That's why it can have "force quit". security.stackexchange.com/q/107546/40884 – Phil Frost Jan 6 '18 at 22:25
  • 1
    @PhilFrost: Force Quit is possible in a pre-emptive multi-tasking OS without memory protection. But Gilles's answer you linked says that processes don't all share the same address space. (And Ross's answer here says that a Win9x app would have to load a device driver to read other process memory. The security model doesn't stop it from loading a VxD, but it does prevent most bugs from hosing other programs). – Peter Cordes Jan 6 '18 at 22:54
  • 3
    @PeterCordes, One of the most common bugs in C code is not checking a pointer to see if it's null. On most systems, a null pointer is represented by memory address 0, and Windows 9x stores some system-critical information in that general area without write-protecting it. A straight write to a null pointer will just crash the program, but performing pointer arithmetic before writing to a not-quite-null pointer can crash the system. – Mark Jan 7 '18 at 0:14
  • 2
    @PeterCordes Windows NT also has that region protected; but don't forget that writing to the first 256 bytes of memory was perfectly legal (and necessary!) in DOS applications. But not mapping the lowest 64kiB in Windows 95 was actually for compatibility with broken CPUs that didn't allow you to map those addresses to virtual memory (blogs.msdn.microsoft.com/oldnewthing/20110112-00/?p=11773). The support for these CPUs was dropped for the release, but it was too late to fix the fix. Linux didn't care much about support - I had to write my own drivers for everything anyway :D – Luaan Jan 7 '18 at 11:14
14

For the most part you're correct. Neither MS-DOS nor Windows 95/98/ME implemented a security model that would not be impacted by the Meltdown or Spectre vulnerabilities. MS-DOS didn't protect memory at all, Windows 9x's separation of user and "kernel" memory was just to protect against user processes accidentally from modifying memory outside of their process. An MS-DOS program can read whatever memory it wants and any Windows 9x program can load a device driver (VxD) that can read whatever memory it wants.

However there is one way that potentially these operating systems could be affected by these vulnerabilities, at least in theory, and that's through a JavaScript program running in an web browser. MS-DOS I would assume is safe from this in practice because I assume the are no web browsers for DOS that support JavaScript, but Windows 9x would be a different matter. A mitigating factor for Windows 9x is that web browsers that support these old operating systems would be old and so probably don't have the JavaScript features necessary for the exploit to work and probably have other JavaScript vulnerabilities that would be easier to exploit

  • 15
    Earlier versions of ActiveX in IE can format your computer over the internet. We didn't need anything remotely as complex as Meltdown/Spectre to read everything on your PC in the Win 9x era... – Nelson Jan 6 '18 at 10:31
  • "An MS-DOS program can read whatever memory it wants and any Windows 9x program can load a device driver (VxD) that can read whatever memory it wants." But an MS-DOS program running under Windows in V86 mode is, presumably, protected from other such programs? At least I've always generally assumed that that would be true, even if I've never investigated the idea in depth, because I've never found the need to rely on it. – Jules Jan 6 '18 at 20:49
  • @Jules Well, an MS-DOS program running under Windows 9x can just load a VxD to do the memory reading, just like a Windows program. A MS-DOS program running under Windows NT wouldn't be able to. – Ross Ridge Jan 6 '18 at 21:41
8

This flaw does not affect MS-DOS because there is no kernel protection to subvert. It affects any protected mode Windows of any era that has a speculative CPU.

However, nothing before the Pentium Pro speculatively executed so a regular Pentium or below does not exhibit the bug. Therefore it is unlikely to affect a substantial number of real machines.

There are two observations underlying Meltdown:

  • speculative execution can see memory even if accessing it should cause an access violation;
  • speculative execution has a side effect, cache loading, that can be observed even when the speculative branch isn't taken.

So if you use one bit of a byte you don't have access to as an array index, multiplied by a suitable amount, you can test whether that bit was set or cleared by observing the timing effect of trying to access the array yourself. If the section indexed when the bit is a 1 is in the cache, the bit must have been a 1.

The fix is not to have kernel memory mapped at all when running user code. The mapping and unmapping cause a large performance hit.

No operating system would volunteer to apply that protection if it weren't necessary, so you should expect all protected mode operating systems to be affected.

5

Windows 95 is vulnerable to Meltdown. Spectre attack from JavaScript on 32 bit systems can turn into Meltdown if the processor is vulnerable to Meltdown. You probably don't care because where are you going to get a web browser for Windows 95 that supports JavaScript but doesn't have ridiculous security holes in it.

Java applets are in a worse state. The root construction can be built in Java code. It looks like this:

byte array[] = new byte[65536];
int z = targetbyte; /* plus some offset we can't know yet -- but kernel memory is high */
int accum = 0;
for (int b = 0; b < 8; ++b)
    for (int x = 0; x < 32; x++)
        for (int t = 0; t < 3; t++) {
            int s = 0;
            /* force array[4096] out of L1 cache */
            for (int y = 8192; y < 65536; ++y) s |= array[y];
            int y = (x == 31) ? z : 1;
            long time1 = System.nanoTime();
            if (y < 16) { /* branch predictor is trained for true */
                do {
                    /* s = array[1] during normal execution;
                       reads out-of-range memory during speculative execution
                       expression is jmpless array[array[y] ? 0 : 4096] */
                    s = array[(array[y] & (1 << b)) >> (1 >> b) << 12];
                } while (s == 0 && y < 16); /* loops only during speculative execution */
            }
            s = array[4096];
            long time2 = System.nanoTime();
            if (x == 31 && (time2 - time1) < some_constant_unique_per_cpu)
                accum |= (1 << b);
         }

This is the unified sequence that attacks both Spectre and Meltdown and targets the small cache liens on Pentium II and III processors (adjust to bigger lines for a VM guest). Pentium I isn't vulnerable. The internal if protecting array bounds is also trained to true by the same code so it won't hose us.

Any Java applet running in the web browser can read all memory on the system (int wraps around in 32 bit) so if by some miracle you have a fully patched web browser and Java implementation you still get smacked.

Windows 95 memory mapping is so poor that a Spectre attack is the equivalent of a Meltdown attack. (And MS-DOS uses a 1-1 mapping when running 32 bit DOS programs.) All memory is mapped above 3GB in all processes.

If you are running this in a VM guest on a 32 bit host vulnerable to Meltdown it will read all host memory. If your host is 64 bit the host is protected by the fact the guest can't generate 64 bit read offsets and so can't read kernel memory.

I haven't been able to fully check this, but the following should be correct: If your host machine is vulnerable to rowhammer (~doesn't have ECC memory), than you really are in trouble. Emulators tend to allocate the guest VM in one swoop, which tends in turn to allocate host memory in one swoop. This makes guessing adjacent memory easy, and the Spectre attacks on jitting emulators and true VMs able to bust out of the emulator by flipping bits in the jitted code (we remember true VMs have to JIT the guest kernel in some cases--once we have full control of the guest we can arrange them) and thereby get control of the VM process in the host machine. Please not the Spectre attack doesn't "know" it's in a VM and will read outside the VM bounds into the host process. Rowhammer is difficult to exploit. Rowhammer when you know the memory layout is not. If the host is vulnerable to Meltdown we can then repeat the process and take over the kernel. If not, we have the emulator process, which probably isn't running as its own user. (I think VirtualBox processes run as root; and the user probably started qemu as himself--either way is really bad.)

  • The Java stuff raises an interesting question, possibly more on topic for this site: can host machine data be accessed by code running on emulators that emulate different platforms? Is DOSBox vulnerable? How about an Amiga or MacOS Classic emulator? I'm presuming that emulators of much slower systems, e.g. Z80 or 6502 based systems are so slow that the timing differences are effectively invisible to them (is this actually the case?), but some of these other systems run at speeds with emulated cycle times that are reasonably close to current day memory access times, so it seems plausible. – Jules Jan 6 '18 at 20:42
  • @Jules: Pure emulators such as DOSBox, Amiga, etc. are not vulnerable. The Java path exists only because of jitters. If you ran your Win95 in a pure emulator rather than a VM (such as VirtualBox or VMWare) or a jitting VM (such as QEMU) there is no path to exploit. – Joshua Jan 6 '18 at 20:47
  • 2
    I believe that DOSBox includes a JIT mode (the instructions call it dynamic recompilation mode), and don't know what other emulators do either. I know that some of the targets supported by QEmu use JIT recompilation, but I'm not sure about other emulators of older targets... – Jules Jan 6 '18 at 21:00
5

mainly I'm trying to dispute the claim that computers have been vulnerable to Meltdown since 1995.

The claim was never that all computers since 1995 were vulnerable, just some.

Microsoft was not the only OS vendor for Pentium Pro CPUs in 1995.

Linux in 1995 (when PPro was released) had many real users (and full working memory protection between separate userspace processes). So did other Unix implementations on 386, like 386BSD, and some non-free Unix implementations for 386 which predated Linux.

Microsoft's crufty Win9x OS family being widely used at the time meant that most people didn't have an OS with full privilege separation for multiple users (or unprivileged processes), or to protect the kernel from applications. Win9x used virtual memory to stop processes from accidentally crashing each other, not for security. See Ross's answer, and another question: Even Win9x did run processes in separate address spaces from each other, but its security model allowed any process to load a driver (VxD) and bypass that.


Also note that Pentium Pro was not widely used in home computers. Pentium II in May 1997 was what really replaced Pentium MMX. Even the consumer-targeted PII was expensive at first: My first PC (in early 1998, IIRC) was a P-MMX running Linux.

The workstations / servers that used PPro were probably mostly not running Win9x. Some were probably running Linux or other Unix, many probably running Windows NT as mentioned in comments.


The claim that Intel CPUs dating back to 1995 were vulnerable to Meltdown is based on the fact that all of Intel's out-of-order CPUs (other than Pentium 4 (netburst microarchitecture)) can trace their lineage back to the first generation of P6 (Pentium Pro), and use the same fault-handling strategy for under-privileged TLB hits on kernel-only mappings: let the load continue microarchitecturally, and only flag it to fault on retirement (after potentially making other changes to micro-architectural state that depend on the loaded "secret" data, specifically the cache. This is the Meltdown design flaw).

Sandybridge-family is a new microarchitecture family, but it did evolve from P6-family (Nehalem being the last generation). SnB incorporates some ideas from Netburst, but in a different form. (e.g. the decoded-uop cache instead of the trace cache).

Most Intel-based computers in 1995 were either using in-order CPUs, and/or running OSes that didn't try to enforce process isolation. Some old 586 and 486 CPUs stayed in service for many years... (But since some software at the time had a security model that's defeated by Meltdown, it makes sense to say computer, not just CPU).

  • 4
    Not to mention Windows NT and OS/2 which were both in active use in '95 and fully implemented the use of protected memory. – mnem Jan 6 '18 at 9:15
  • 2
    Indeed. While NT was definitely niche on the workstation in '95 (I distinctly remember lots of press about NT 4, though, around when it was released in '96), OS/2 was in relatively wide use. Probably far more so on the workstation side of things than any Unix-like system, including Linux. – a CVn Jan 6 '18 at 13:44
  • 1
    Don’t forget Novell - 4.1 was out at the time. I also recall a lot of us moving from 3.5 to 3.51 at the time in ‘95, even on pre-release versions, as it offered some significant stability benefits. – rnxrx Jan 6 '18 at 17:47
  • 1
    "Privilege separation for multiple users"? Windows 95 didn't have multiple concurrent users in the first place, so that's irrelevant. It was a home single-user system - it didn't even have a file system that supported any kinds of permissions. Not protecting the kernel from user applications is relevant, but you could make the computer unusable without doing that anyway, so it wasn't that important - as long as you keep full compatibility with coöperative multitasking, any user application can block the whole computer. Compatibility is a huge burden even today :) – Luaan Jan 7 '18 at 11:24
  • 1
    @Luaan: That's exactly my point; I was comparing Win95 with OSes like Linux which do isolate multiple users from each other while both have processes running simultaneously. But since you mention it, Win95's security model didn't try to make unprivileged processes possible either, which can be useful even on a single-user desktop. Win9x does at least stop processes from writing each other's memory by accident (but apparently writing the zero page can hose the whole system), so I had to write something to replace my mistaken claim that it didn't even try to use the HW memory protection. – Peter Cordes Jan 7 '18 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.