Zack's Kernel News
Zack's Kernel News

Chronicler Zack Brown reports on the latest news, views, dilemmas, and developments within the Linux kernel community.
Cleaning Up Dependencies on Older GCC Versions
When Linus Torvalds recently agreed to raise the GCC minimum supported version number to 4.8, it meant that any older system that still used older build tools, including older versions of GCC, wouldn't be able to compile new kernels without upgrading that software. The justification for his decision was partly that the various kernel ports had come to depend on later GCC versions and partly that the various Linux distributions had started shipping with later GCC versions as well. To Linus, this meant that regular users would almost certainly not be inconvenienced by the change; while kernel developers – well, Linus didn't mind inconveniencing them so much.
But it wasn't entirely an inconvenience to developers, as Steven Rostedt recently demonstrated. Now that GCC 4.8 was the new minimum, the kernel no longer had to support older versions of GCC that lacked some of the modern new features. The way this generally works is that the kernel build system checks which version of GCC is installed and then compiles certain kernel features that are specifically coded for that GCC version. This way, by hook or by crook, all kernel features get implemented, even if they have to work around deficiencies in an older compiler. When the older compilers aren't supported anymore, all of that targeted kernel code can simply be torn out by the roots, without anyone making a fuss.
Steven had noticed that function tracing had traditionally used two possible implementations: one using only GCC's -pg
flag, and one using the -pg
flag in conjunction with -mfentry
. Everyone understood that -pg
plus -mfentry
was better, but the kernel build system had always had to support using only the -pg
flag by itself, because older versions of GCC didn't support the -mfentry
flag. In order to make sure function tracing was supported in all kernels, there needed to be multiple implementations: some using the excellent -pg
plus -mfentry
, and others using the less excellent -pg
. Now that the minimum GCC version was 4.8, it meant that all supported GCC versions now implemented the -mfentry
flag, so the -pg
solution was no longer needed.
Steven posted a patch to remove it.
There was wide applause for this violent and merciless act. Peter Zijlstra and Jiri Kosina both shouted with glee, while Linus smiled contentedly.
It's common with this sort of adjustment that developers will start to look deeper into the given piece of code to identify yet more areas that can be simplified or removed. In this case, as Linus pointed out, there were a bunch of conditionals that no longer had more than one choice, now that the second choice had been taken away. So it would now be possible to get rid of all those conditionals and simplify the code still further.
This type of patch is very popular with Linus and his core group of developers – anything that shrinks the code base, or that shrinks the size of the compiled kernel, is already a patch they like, before they've even looked at what it does. After that, they may object for other reasons. But just tell people your patch removes X hundreds of lines of code, and they start nosing around interestedly, hoping to find an excuse to apply this patch to the tree.
Protecting RAM from Hostile Eyes
Security issues are always weird. They're always something nobody has thought of yet. And then lo and behold, there it is, like a rabbit in a hat. Where did that come from? Or else you're implementing what seems to be a perfectly good feature, like a macro language for your closed source word processor product; what could ever go wrong with that? And lo and behold, you create an entirely new universe of attacks against perfectly innocent users.
In the Linux world, Matthew Garrett saw a sliver of danger lurking in the crack of time between when a piece of RAM is freed by a piece of software and when it gets wiped clean by the kernel. In that moment, a hostile attacker could potentially reboot the system into a different OS, read the RAM, and see the data belonging to that piece of software. If that data was secret and sensitive, there could be a problem.
There are already mechanisms to prevent sensitive data being sent into swap and to make sure RAM gets thoroughly overwritten when the program is done with it. But there was always that sliver of time between release and overwrite, when a reboot might leave the data exposed.
Now, it was also possible to instruct UEFI firmware to wipe all RAM before booting to another OS. But as Matthew pointed out, this would actually multiply the time it took to boot the system by quite a bit, producing a truly unacceptable slowdown.
A better approach, he felt, was for Linux itself to wipe all RAM before shutting down. Assuming the attacker didn't simply turn off the power to induce a cold boot, Linux could then shut down gracefully, deleting all data and leaving the attacker with nothing to target. There was real value in this, Matthew said. Consider if the OOM killer suddenly killed a process, without giving it any time to exit cleanly and delete its own data. The operating system itself would have to be the last line of defense. Matthew posted a patch to implement his idea.
There was a bunch of support for this. However, Christoph Lameter pointed out that Matthew's patch only wiped RAM a little bit earlier than it would otherwise be wiped, given that RAM was always scrubbed clean before being allocated to another process. If anything, he said, Matthew's patch would reduce the width of the dangerous sliver of time, but it wouldn't eliminate it completely. And since Matthew's patch extended the behaviors of system calls and created whole new kernel behaviors, it seemed to Christoph that this slight reduction of the attack surface was not worth the added complexity.
It's unclear whether Christoph's objection might stop the patch from going into the kernel. Clearly his point is valid. But there was also a fair amount of initial support for the patch, and it seems like a common sense precaution in some ways. Ultimately, I believe, if the security hole remains open, it may make Linus Torvalds less willing to accept a patch that adds any sort of complexity to the kernel. But to close the hole entirely may prove to be impossible.
Verifying Return Addresses
Some security fixes look cool but are nonstarters for other reasons. For example, Mike Rapoport from IBM wanted to strengthen Linux address space isolation, which on its own merits could be very useful. Address space isolation is where a given process can only "see" a certain range of RAM addresses, and anything outside of that range is completely cut off from potential attack.
Mike's approach, he explained, was to have the kernel confirm every address that popped off the stack. This way, the return addresses of any function calls made in an address space, would be guaranteed to bring execution back to that calling function. Without Mike's patch, a hostile user might be able to insert a fake return address that didn't exist in the kernel's predefined symbol table. Then when that address came up off the stack, control would be handed over to a hostile piece of code, possibly with root access. Mike's patch stopped that dead in its tracks.
Unfortunately, as Mike himself admitted, confirming that every single return address had a corresponding entry in the symbol table was going to be a high-intensity operation, happening many times per second on a normal system. He saw no way to accomplish this without the kernel taking some kind of generalized speed hit.
Not only that, but as Jiri Kosina said, Mike's code was actually incompatible with other security projects that attempted to solve similar problems. So between the speed hit and the project conflicts, the otherwise useful aspects of Mike's patch were not sufficient to gain any interested supporters among the kernel developers.
It's not such a rare outcome – someone works many hours to prove that a given feature is possible, only to find that it doesn't work with another obscure project that seems to have more favor or that the feature itself has some inescapable drawback like a speed hit or something else that dooms it.
At the same time, in many cases, a failed project points the way towards a better approach that later on succeeds. It's almost never the case that a project is simply bad and useless, especially if a developer thought it was important enough to invest so much time.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.
News
-
The GNU Project Celebrates Its 40th Birthday
September 27 marks the 40th anniversary of the GNU Project, and it was celebrated with a hacker meeting in Biel/Bienne, Switzerland.
-
Linux Kernel Reducing Long-Term Support
LTS support for the Linux kernel is about to undergo some serious changes that will have a considerable impact on the future.
-
Fedora 39 Beta Now Available for Testing
For fans and users of Fedora Linux, the first beta of release 39 is now available, which is a minor upgrade but does include GNOME 45.
-
Fedora Linux 40 to Drop X11 for KDE Plasma
When Fedora 40 arrives in 2024, there will be a few big changes coming, especially for the KDE Plasma option.
-
Real-Time Ubuntu Available in AWS Marketplace
Anyone looking for a Linux distribution for real-time processing could do a whole lot worse than Real-Time Ubuntu.
-
KSMBD Finally Reaches a Stable State
For those who've been looking forward to the first release of KSMBD, after two years it's no longer considered experimental.
-
Nitrux 3.0.0 Has Been Released
The latest version of Nitrux brings plenty of innovation and fresh apps to the table.
-
Linux From Scratch 12.0 Now Available
If you're looking to roll your own Linux distribution, the latest version of Linux From Scratch is now available with plenty of updates.
-
Linux Kernel 6.5 Has Been Released
The newest Linux kernel, version 6.5, now includes initial support for two very exciting features.
-
UbuntuDDE 23.04 Now Available
A new version of the UbuntuDDE remix has finally arrived with all the updates from the Deepin desktop and everything that comes with the Ubuntu 23.04 base.