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. |
One of the basic rules of kernel-module development is that modules can only access symbols (functions and data structures) that have been explicitly exported. Even then, many symbols are restricted so that only modules with a GPL-compatible license can access them. It turns out, though, that there is a readily available workaround that makes it easy for a module to access any symbol it wants. That workaround seems likely to be removed soon despite some possible inconvenience for some out-of-tree users; the reason why that is happening turns out to be relatively interesting.
The backdoor in question is kallsyms_lookup_name(), which will return the address associated with any symbol in the kernel's symbol table. Modular code that wants to access a symbol ordinarily denied to it can use kallsyms_lookup_name() to get the address of its target, then dereference it in the usual ways. This function itself is exported with the GPL-only restriction, which theoretically limits its use to free software. But if a proprietary module somewhere were to falsely claim a free license to get at GPL-only symbols, it would not be the first time.
Will Deacon has posted a patch series that removes the export for kallsyms_lookup_name() (and kallsyms_on_each_symbol(), which is also open to abuse). There were some immediate positive responses; few developers are favorably inclined toward module authors trying to get around the export system, after all. There were, however, a couple of concerns expressed.
One of those is that there is, it seems, a class of out-of-tree users of kallsyms_lookup_name() that is generally considered to be legitimate: live-patching systems for the kernel. Irritatingly, kernel bugs often stubbornly refuse to restrict themselves to exported functions, so a live patch must be able to locate (and patch out) any function in the kernel; kallsyms_lookup_name() is a convenient way to do that. After some discussion Joe Lawrence let it be known that the kpatch system has all of its needed infrastructure in the mainline kernel, and so has no further need for kallsyms_lookup_name(). The Ksplice system, though, evidently still uses it. As Miroslav Benes observed, though: "no one cares about ksplice in upstream now". So it would appear that live patching will not be an obstacle to the merging of this patch.
A different sort of concern was raised by Masami Hiramatsu, who noted that there are a number of other ways to find the address associated with a kernel symbol. User space could place some kprobes to extract that information, or a kernel module could, if time and CPU use is not a concern, use snprintf() with the "%pF" format (which prints the function associated with a given address) to search for the address of interest. He worried that the change would make life harder for casual developers while not really getting in the way of anybody who is determined to abuse the module mechanism.
In response, Deacon posted an interesting message about what is driving this particular change. Kernel developers are happy to make changes just to make life difficult for developers they see as abusing the system, but that is not quite what is happening here. Instead, it is addressing a support issue at Google.
Back in 2018, LWN reported on work being done to bring the Android kernel closer to the mainline. One of the steps in that direction is moving the kernel itself into the Android generic system image (GSI), an Android build that must boot and run on a device for that device to be considered compliant with the Android requirements. Putting the kernel into the GSI means that hardware vendors can no longer modify it; they will be limited to what they can do by adding kernel modules to the GSI.
Restricting vendors to supplying kernel modules greatly limits the kind of changes they can make; there will be no more Android devices that replace the CPU scheduler with some vendor's special version, for example. But that only holds if modules are restricted to the exported-symbol interface; if they start to reach into arbitrary parts of the kernel, all bets are off. Deacon doesn't say so, but it seems clear that some vendors are, at a minimum, thinking about doing exactly that. The business-friendly explanation for removing this capability is: "Monitoring and managing the ABI surface is not feasible if it effectively includes all data and functions via kallsyms_lookup_name()".
After seeing this explanation, Hiramatsu agreed that the patch makes sense and offered a Reviewed-by tag. So this concern, too, seems unlikely to prevent this patch set from being merged.
It's worth repeating that discouraging module developers from bypassing the export mechanism is generally seen as more than sufficient motivation to merge a change like this. But it is also interesting to see a large company supporting that kind of change as well. By more closely tying the Android kernel to the mainline, Google would appear to be better aligning its own interests with the long-term interests of the development community — on this point, at least. That, hopefully, will lead to better kernels on our devices that also happen to be a lot closer to mainline kernels.
Unexporting kallsyms_lookup_name()
Posted Feb 29, 2020 20:21 UTC (Sat) by ncm (subscriber, #165) [Link]
(A certain alternative pronunciation of its name perhaps telegraphs its purpose.)
We may be heartened by the previously demonstrated inability of large organizations to create a viable new kernel from scratch--OS/360 excepted.
Unexporting kallsyms_lookup_name()
Posted Feb 29, 2020 21:12 UTC (Sat) by mfuzzey (subscriber, #57966) [Link]
Maybe Google does want to move Android to Fuchsia but they don't need to change anything in Linux to do that.
Unexporting kallsyms_lookup_name()
Posted Feb 29, 2020 22:00 UTC (Sat) by Lionel_Debroux (subscriber, #30014) [Link]
Unexporting kallsyms_lookup_name()
Posted Mar 1, 2020 17:58 UTC (Sun) by NYKevin (subscriber, #129325) [Link]
Fuchsia is open source.
Unexporting kallsyms_lookup_name()
Posted Mar 1, 2020 18:17 UTC (Sun) by rahulsundaram (subscriber, #21946) [Link]
Upstream is at the moment. Given that it is permissive licensed and mobile vendors like to slap on a ton of patches for differentiation, how it will be distributed in practice is murky and the outlook isn't great given the track record even with current Android
fuchsia license looks like BSD 3-clause
Posted Mar 1, 2020 20:39 UTC (Sun) by stephen.pollei (subscriber, #125364) [Link]
The fuchsia license looks a lot like the 3-Clause BSD License. For some reason, reminds me of BSD - The Dark Horse of Open Source.
Unexporting kallsyms_lookup_name()
Posted Mar 9, 2020 14:57 UTC (Mon) by scientes (subscriber, #83068) [Link]
FTFY
Unexporting kallsyms_lookup_name()
Posted Mar 2, 2020 11:26 UTC (Mon) by Sesse (subscriber, #53779) [Link]
Unexporting kallsyms_lookup_name()
Posted Mar 3, 2020 2:52 UTC (Tue) by pabs (subscriber, #43278) [Link]
https://wiki.gentoo.org/wiki/Elivepatch
There is also another one (KernelCare I think) that IIRC has its own non-mainline patching mechanism.
Copyright © 2020, Eklektix, Inc.
This article may be redistributed under the terms of the
Creative
Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds