my first patch to the linux kernel
How a sign-extension bug in C made me pull my hair out for days but became my first patch to the Linux kernel!
Intro
A while ago, I started dipping my toe into virtualization. It's a topic that many people have heard of or are using on a daily basis but a few know and think about how it works under the hood.
I like to learn by reinventing the wheel, and naturally, to learn virtualization I started by trying to build a Type-2 hypervisor. This approach is similar to how KVM (Linux) or bhyve (FreeBSD) are built.
Since virtualization is hardware assisted these days , the hypervisor needs to communicate directly with the CPU by running certain privileged instructions; which means a Type-2 hypervisor is essentially a Kernel Module that exposes an API to the user-space where a Virtual Machine Monitor (VMM) like QEMU or Firecracker is running and orchestrating VMs by utilizing that API.
In this post, I want to describe exactly how I found that bug. But to make it a bit more educational, I'm going to set the stage first and talk about a few core concepts so you can see exactly where the bug emerges.
x86 Task State Segment (TSS)
The x86 architecture in protected mode (32-bit mode) envisions a task switching mechanism that is facilitated by the hardware. The architecture defines a Task State Segment (TSS) which is a region in the memory that holds information about a task (General purpose registers, segment registers, etc.). The idea was that any given task or thread would have its own TSS, and when the switch happens, a specific register (Task Register or TR) would get updated to point to the new task .
This was abandoned in favor of software-defined task switching which gives more granular control and portability to the operating system kernel.
... continue reading