xGoat
More tea please.

Anaconda bug

Fedora 14 came out yesterday. Amongst various run-of-the-mill updates, a couple of things stand out in it for me. The newer gdb and gcc combination allow for a much improved debugging experience that rarely involves one cursing at the words “value optimised out”. I happen to know this as good as it says on the tin because I resorted to using an alpha of F14 in qemu to attack a particularly gristly situation I got myself into about a month back. systemd also looks quite interesting, and I think it’s possible to switch over to that in F14.

So I waited patiently for Fedora 14 to appear in preupgrade, which downloads all the updates, reboots and installs them without the need for a CD, DVD, USB key, or data-laden Armadillo. It downloaded everything and I rebooted into the updater to be presented with a prompt asking me to insert a driver disk. Not only did it not tell me what driver it was looking for, it also wouldn’t let me proceed with the upgrade without this “driver disk”.

Now I knew that it didn’t genuinely require some kind of magic driver to continue. My machine contains no exotic hardware, and has been running a plain-old Fedora kernel since its inception. I decided to delve somewhat deeper.

With the help of the Anaconda wiki pages, I quickly worked out how to replace the Anaconda instance that preupgrade was running with one that I’d massaged myself. I got Anaconda to run gdbserver, which I then connected to. Unfortunately 99% of the variables I wanted to look at had been optimised away. I then spent a fair while injecting print statements throughout the bits of relevant code.

Eventually, I discovered the problem. “stage1” of Anaconda, who’s responsibility is to load the more graphical “stage2”, searches through all the block devices in the machine to find disk drives that are worth inspecting. Part of this “worthiness” test involves it inspecting the size of the disk to determine if it’s above some small size that no disks today could be below. This test reads the contents of the ‘size’ file sysfs provides for the device that’s being examined (e.g. /sys/block/sda/size). This file contains a number. This number is the number of 512-byte blocks that the device has. On my machine this file contains “2930277168”.

This bit of Anaconda then used strtol() on this string to convert it to an integer. An important feature of strtol is that it returns a long int. On most 32-bit systems, this is a 32-bit number. It’s signed, so its maximum value is 2147483647. Note that the value from my hard disk, 2930277168, is larger than 2147483647. So strtol returns indicating the value’s out of range. Anaconda’s device listing stuff immediately explodes because of this, and then the (somewhat disturbing) state machine decides that we need a driver disk to solve the problem of us not having a device list.

Solution: A patch to Anaconda to use strtoll instead, which uses long long ints. These are 64-bits, and so there won’t be a problem until disks are measured in zettabytes.

Fun times.

Posted at 9:40 am on Wednesday 3rd November 2010

Site by Rob Gilton. © 2008 - 2019