When ELF notes reveal too much
Did you know...? LWN.net is a subscriber-supported publication; we rely on subscribers to keep the entire operation going. Please help out by buying a subscription and keeping LWN on the net. |
The Linux kernel uses a number of hardening techniques to try to protect itself against compromise; one of those is kernel address-space layout randomization (KASLR). But randomization is of little benefit if the kernel spills the beans on where its code has ended up. As it happens, the kernel has been doing exactly that — since 2007, in a behavior that predates the addition of KASLR. Some changes are in the works to close that hole, but it is illustrative of just how hard some secrets are to keep.
Exploits of the kernel (as with any other program) often rely on jumping into specific code in unexpected ways. Numerous techniques have been developed to prevent this from happening; control-flow integrity mechanisms, for example, exist to prevent execution from being diverted from the intended paths. Other techniques, though, try to make it difficult for an attacker to know where to redirect the control flow to, even if they find a bug that would allow that sort of compromise. KASLR is one of those techniques, built on the observation that, if an attacker does not know where the kernel has been placed in its address space, they cannot redirect control flow to a known location.
The idea behind KASLR is simple enough: at boot time, the actual location for the kernel in memory is chosen randomly. The offset chosen for each boot is different, so an attacker does not know, at the outset, where the kernel lives on any given target machine. If the kernel takes pains not to tell the attacker about its location, it creates an added barrier to successfully exploiting any vulnerability that might exist.
KASLR was first added to the kernel (for the x86 architecture) during the 3.14 development cycle in 2013. Randomizing the kernel's layout, though, has turned out to be the easy part of the job; the harder part is preventing the kernel from leaking information about its location and making the whole effort useless. There was, for example, a lot of kernel code that would happily encode kernel pointer values in printk() calls. After a fair amount of work, that problem was mostly resolved by fixing kernel code to use special formatting directives for pointers and refusing to output actual pointer values to the log unless kptr_restrict is set accordingly. Various other /proc and sysfs files were also redacted as needed. Over time, learning about the kernel's location on any given system has become harder; whether it is hard enough to effectively slow down a capable attacker is still a matter of dispute.
The problem is that there are a lot of information channels between the
kernel and user space, and any one of them might turn out to be leaking
information that reveals the kernel's location. Consider, for example, the
relatively obscure sysfs file /sys/kernel/notes. This file is documented
rather tersely as containing "the binary representation of the running
vmlinux's .notes section
". That section, part of the ELF file
containing the kernel image, contains useful information about the
image itself; any kernel code can add data to this section using the ELFNOTE()
macro. Anything placed there can be read from
/sys/kernel/notes, albeit in a binary format that goes rather
against the usual "one value per file" sysfs rule.
The most common use for this file is to store a version of the kernel's version number, but there is at least one other. Guixiong Wei recently noticed that this file contained potentially sensitive information, including the location of the startup_xen symbol; that information is enough for an attacker to defeat KASLR. That is particularly problematic because this file is world-readable, so that information is made available to an unprivileged attacker. Wei posted a patch restricting readability to the root account, closing the hole somewhat. As of this writing, that patch has not found its way to the mainline, though that can be expected to happen in the near future.
Kees Cook, who got much of the KASLR work into the kernel (built on work by others that had been underway for a while), confirmed that the result was a KASLR exposure that had been in place since 2007, long before KASLR itself was added. He welcomed the permissions change, but also asked whether addresses in /sys/kernel/notes needed boot-time relocation at all; the answer from Xen developer Jürgen Groß was that Xen, at least, does not need that relocation to happen. In other words, the address that appears in /sys/kernel/notes does not need to be adjusted to reflect the randomized offset chosen at boot time. So we may see further changes to this sysfs file in the future, though it is always hard to know that such changes can be made without breaking some user-space program somewhere.
As this episode suggests, finding kernel code that leaks addresses to user space is a bit of a game of whack-a-mole, except in this case one of the moles has managed to remain standing for 11 years after its presence was made unwelcome. There is a tool that is meant to help in the detection of moles in need of whacking called leaking_addresses.pl; it looks at the system log and walks through /proc and /sys in search of kernel addresses that have escaped to user space. It missed /sys/kernel/notes, though, because it's looking for addresses expressed as human-readable strings; /sys/kernel/notes is a binary file, which is rather less amenable to the grep-like approach used by this tool. Addresses encoded into ASCII are relatively easy to recognize; in binary form, instead, they just look like data.
Most data, though, does not contain a value corresponding to the address of a kernel symbol. To find the exceptions (and catch addresses leaked in binary form), Cook has posted a patch to leaking_addresses.pl. It can read a file of kernel symbols, such as /proc/kallsyms, and look to see if the the addresses associated with those symbols appear in a binary file like /sys/kernel/notes. With this change, leaking_addresses.pl would have found this longstanding kernel-address disclosure; it should help to prevent others from being introduced in the future as well.
These changes will keep /sys/kernel/notes from wrecking KASLR on
systems going forward. It seems almost certain that there are other moles
in need of whacking, though. For most of the kernel's history, developers
had no particular reason to conceal internal addresses; even now,
preserving KASLR is not one of the top concerns for most developers. KASLR
is a useful defense when combined with other techniques but, in a world
where any developer in an inattentive moment can compromise it, KASLR
cannot stand alone.
Index entries for this article | |
---|---|
Kernel | Security/Address-space layout randomization |
(Log in to post comments)
When ELF notes reveal too much
Posted Feb 22, 2024 19:02 UTC (Thu) by rgb (subscriber, #57129) [Link]
When ELF notes reveal too much
Posted Feb 22, 2024 22:28 UTC (Thu) by Phantom_Hoover (subscriber, #167627) [Link]
When ELF notes reveal too much
Posted Feb 23, 2024 5:14 UTC (Fri) by npws (subscriber, #168248) [Link]
KASLR
Posted Feb 23, 2024 11:44 UTC (Fri) by timon (subscriber, #152974) [Link]
By the way, Kassler is _maybe_ cognate with the English casserole via the French casserole (other explanations Wikipedia gives for “Kassler” are a butcher named Cassel or the city of Kassel) -- I’m mentioning this just in case you need more tasty connotations for KASLR ;-)
KASLR
Posted Feb 23, 2024 13:27 UTC (Fri) by paulj (subscriber, #341) [Link]
KASLR
Posted Feb 23, 2024 14:13 UTC (Fri) by excors (subscriber, #95769) [Link]
> Boucher: ... the first order of business was to figure out what we were going to call the standard. We were told it can't be SASI, which was really a shame because Shugart Associates System interface, I mean SASI, was such a cute word [pronounced “Sassy”] ... So, basically I felt that we should keep it as close to SASI as we could and there was a lot of discussion. There were all different opinions on the committee. But we came up ultimately with SCSI [“Scuzzy”] because “Small Computer Storage Interface” would help us continue to differentiate from those guys that were trying to build this monster [IPI]
>
> ... So I figured well okay, we can call it “sexy”. I was hoping that it would go from SASI to sexy but when the committee meeting broke at the same time as Dal’s committee, Dal walks in and says, "Okay. So what's happening?" I said, "Well, we've got a name. It’s SCSI." And he said, "Oh scuzzy." I said, "No. No. No. [it is “sexy”]
>
> Burniece: So he's the one that pronounced SCSI scuzzy rather than sexy?
>
> Boucher: Yes. I think he claims he's not, but he is. He's the one ... and because he wanted in the worst way to kill us. So he laughed when he said, "Oh, so you guys are scuzzy."
(https://archive.computerhistory.org/resources/access/text...)
KASLR
Posted Feb 24, 2024 12:52 UTC (Sat) by kid_meier (subscriber, #93987) [Link]
The day that this clicked was ... well 30+ years later and I still remember it.
KASLR
Posted Feb 24, 2024 17:12 UTC (Sat) by songmaster (subscriber, #1748) [Link]
KASLR
Posted Feb 24, 2024 19:56 UTC (Sat) by Wol (subscriber, #4433) [Link]
Cheers,
Wol
KASLR
Posted Feb 25, 2024 21:21 UTC (Sun) by notriddle (subscriber, #130608) [Link]
KASLR
Posted Feb 23, 2024 14:04 UTC (Fri) by comio (subscriber, #115526) [Link]
KASLR
Posted Feb 27, 2024 4:56 UTC (Tue) by marcH (subscriber, #57642) [Link]
Notes relocations
Posted Feb 22, 2024 20:51 UTC (Thu) by corbet (editor, #1) [Link]
Kees has now posted a patch ending the relocation of addresses in the notes section, as expected.