Saturday, September 1, 2018

Debian and FreeBSD on QEMU with MMX-only CPU

A recent bug (and PR) was opened, aircrack-ng couldn't be built with MMX using a i586 toolchain.

The PR looks pretty simple and just removed some code to allow building with MMX. Building the code will obviously work. There isn't a x86 CPU these days that cannot support anything less than SSE2, which was released after MMX.

So, let's take the opportunity to use qemu to emulate a MMX-only CPU so we can actually test how it runs on such CPU after building it.

If you aren't familiar, qemu is known to emulate a lot of different CPUs, most of the time to play (old) games and using non-x86 CPU. It supports a wide range of x86 CPU too. Using it might sound intimidating but it's actually fairly easy.

Pentium MMX, Pentium 2 (and probably Celeron of that same generation) as well as a few AMD support MMX and do not have any SSE/SSE2 instructions.

Another feature in the Pentium 2 is PAE support. Celeron of the same generation typically don't support PAE. Basically, memory was addressed, like the CPU, with 32 bit, which means a limitation of 4Gb of memory. PAE extended this to 64 bit, allowing more memory on 32 bit CPUs. The OS also has to support it.

The vast majority of Linux distributions these days are built with PAE even if they mention they ship in i386/i486. One exceptions: Debian. However, Debian derivative distributions don't support non-PAE systems. CentOS 6 or 7 may work too but they haven't been tested.

In this example, Ubuntu 18.04 64 bit Desktop was used as a host but it should work on any other currently supported OS. We'll download the latest i386 debian ISO (XFCE or netinst) on the host.

First step is to install the x86 version qemu and the required tools:

apt-get install qemu qemu-system-x86

Now, let's create a disk of 10Gb called hda:

qemu-img create hda 10G

And finally, we start the VM using qemu:

qemu-system-i386 -cpu pentium2,enforce -cdrom debian-10.1.0-i386-xfce-CD-1.iso -m 2G -show-cursor -net user,hostfwd=tcp::1022-:22 -net nic hda

Let's go over the different options.

-cpu pentium2 will use a typical Pentium 2 system. Details of that system can be found by running man qemu-system-i386. The 'enforce' parameter forces to use the instructions of that CPU only. By default, qemu will run executables on the host CPU as shown here, hence why the use of enforce, to fully emulate how a program would behave on that CPU.

The second option, -cdrom debian-10.1.0-i386-xfce-CD-1.iso will mount the ISO inside the emulated system as a CD-ROM. This option won't be needed when the system is installed.

-m 2G will give 2Gb of RAM to the emulated system. QEmu defaults to 128Mb of RAM, which is definitely not enough for Debian.

-show-cursor displays the mouse cursor. Otherwise it is invisible.

-net user,hostfwd=tcp::1022-:22 -net nic is initializing a NIC so we can access the virtual machine SSH server from the host. We'll have to connect using ssh -p 1022

And finally hda, the disk we created previously.

A screen will pop up. The installation process is no different than a regular computer; it will just take much longer while because we are emulating a system.

Restarting the virtual machine later on will use the same command as above minus the -cdrom option.

Here is the output of lscpu on the newly created VM:

user@debian:~$ lscpu
Architecture:          i686
CPU op-mode(s):        32-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 5
Model name:            Pentium II (Deschutes)
Stepping:              2
CPU MHz:               2591.957
BogoMIPS:              5183.91
Flags:                 fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 mmx fxsr hypervisor

I bet you never seen a Pentium II overclocked that much :)

Once we got it compiled, to make sure it isn't executed on the host (that supports anything from MMX to AVX2), we will try running the SSE2 version of the executable:

user@debian:~$ aircrack-ng --simd=sse2 -S
Illegal instruction

As expected, it ended up with an Illegal instruction and it means the CPU is fully emulated in the guest (and not executed directly on the host). Anything other than the generic version will result in that error.

So, since the toolchain used is i586, we need to go even further than pentium2 and use the pentium CPU in qemu (P55C). However, we have a serious issue here, there isn't a Linux distribution that supports i586 anymore, not even Debian. If you try to boot it on such platform, it will fail to boot the kernel with a CMOV instruction missing error. So, that would leaves us with Gentoo.

Linux isn't the only option here and BSD supports older CPUs. For example, latest FreeBSD (11.2) still supports i486 CPUs.

The set-up (and results) is identical to what was done for Debian earlier. Installation is straight-forward, exactly the same as you would expect on a real system. And results will be identical.

No comments:

Post a Comment