November 2023 – Linux Kernel work

a71abeb3-f942-4200-b9de-0390f33f904e

-Wstringop-overflow

Late in October I submitted a patch to globally enable the -Wstringop-overflowcompiler option, which finally landed in linux-next on November 28th. It’s expected to be merged into mainline during the next merge window, likely in the last couple of weeks of December, but “We’ll see”. I plan to send a pull request for this to Linus when the time is right. 🙂

I’ll write more about the challenges of enabling this compiler option once it’s included in 6.8-rc1, early next year. In the meantime, it’s worth mentioning that several people, including Kees Cook, Arnd Bergmann, and myself, have submitted patches to fix -Wstringop-overflow warnings over the past few years.

Below are the patches that address the last warnings, together with the couple of patches that enable the option in the kernel. The first of them enables the option globally for all versions of GCC. However, -Wstringop-overflow is buggy in GCC-11. Therefore, I wrote a second patch adding this option under new configuration CC_STRINGOP_OVERFLOW in init/Kconfig, which is enabled by default for all versions of GCC except GCC-11. To handle the GCC-11 case I added another configuration: GCC11_NO_STRINGOP_OVERFLOW, which will disable -Wstringop-overflowby default for GCC-11 only.

Boot crash on ARM64

Another relevant task I worked on recently was debugging and fixing a boot crash on ARM64, reported by Joey Gouly. This issue was interesting as it related to some long-term work in the Kernel Self-Protection Project (KSPP), particularly our efforts to transform “fake” flexible arrays into C99 flexible-array members. In short, there was a zero-length fake flexible array at the end of a structure annotated with the __randomize_layout attribute, which needed to be transformed into a C99 flexible-array member.

This becomes problematic due to how compilers previously treated such arrays before the introduction of -fstrict-flex-arrays=3. The randstruct GCC plugin treated these arrays as actual flexible arrays, thus leaving their memory layout untouched when the kernel is built with CONFIG_RANDSTRUCT. However, after commit 1ee60356c2dc (‘gcc-plugins: randstruct: Only warn about true flexible arrays’), this behavior changed. Fake flexible arrays were no longer treated the same as proper C99 flexible-array members, leading to randomized memory layout for these arrays in structures annotated with __randomize_layout, which was the root cause of the boot crash.

To address this, I submitted two patches. The first patch is the actual bugfix, which includes the flexible-array transformation. The second patch is complementary to commit 1ee60356c2dc, updating a code comment to clarify that “we don’t randomize the layout of the last element of a struct if it’s a proper flexible array.”

diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 07022bb0d44d..0d28172193fa 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -162,7 +162,7 @@ struct neighbour {
 	struct rcu_head		rcu;
 	struct net_device	*dev;
 	netdevice_tracker	dev_tracker;
-	u8			primary_key[0];
+	u8			primary_key[];
 } __randomize_layout;
 
 struct neigh_ops {
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
index 910bd21d08f4..746ff2d272f2 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -339,8 +339,7 @@ static int relayout_struct(tree type)
 
 	/*
 	 * enforce that we don't randomize the layout of the last
-	 * element of a struct if it's a 0 or 1-length array
-	 * or a proper flexible array
+	 * element of a struct if it's a proper flexible array
 	 */
 	if (is_flexible_array(newtree[num_fields - 1])) {
 		has_flexarray = true;

These two patches will be soon backported to a couple of -stable trees.

-Wflex-array-member-not-at-end

During my last presentation at Kernel Recipes in September this year, I discussed a bit about -Wflex-array-member-not-at-end, which is a compiler option currently under development for GCC-14.

One of the highlights of the talk was a 6-year-old bug that I initially uncovered through grepping, and later, while reviewing some build logs from previous months, I realized that -Wflex-array-member-not-at-end had also detected this problem:

This bugfix was backported to 6.5.7, 6.1.57, 5.15.135, 5.10.198, 5.4.258 and 4.19.296 stable kernels.

Encouraged by this discovery, I started hunting for more similar bugs. My efforts led to fixing a couple more:

On November 28th, these two bugfixes were successfully backported to multiple stable kernel trees. The first fix was applied to the 6.6.3, 6.5.13, 6.1.64 stable kernels. The second fix was also applied to these, along with the 5.15.140 stable kernel.

I will have a lot of fun with -Wflex-array-member-not-at-end next year. 😄

-Warray-bounds

In addition to these tasks, I continued addressing -Warray-boundsissues. Below are some of the patches I sent for this.

Patch review and ACKs.

I’ve also been involved in patch review and providing ACKs. Kees Cook, for instance, has been actively annotating flexible-array members with the__counted_byattribute, and I’ve been reviewing those patches.

Google Open Source Peer Bonus Award

In other news from November, I want to share that I’m thrilled to be the recipient of this award from Google for the first time. I feel really grateful and honored! 🙂🙏🏽

This comes as a result of my contributions to the Linux kernel over the years.

Honestly, I didn’t even know about the existence of this award until I received an email from someone at Google informing me about it. However, learning about it made me feel really great!

My appreciation goes out to my teammates in the Kernel Self-Protection Project, especially to Kees Cook, who has been an invaluable mentor to me over the years. Special thanks to Greg Kroah-Hartman as well, who was instrumental in setting me on my journey as a Linux kernel developer.👨🏽‍💻🐧

Acknowledgements

Special thanks to The Linux Foundation and Google for supporting my Linux kernel work. 🙂

Dusting off this blog

This weekend I learned that Jerry Cooperstein has retired, and while dusting off my personal blog (I will be posting regularly next year –once a month, actually), I ran into my “LFD420 Linux Kernel Internals and Development” certificate of completion, which was signed by Jerry back in May 2016.

In December of that year, I quit my job at a consulting company to pursue my dream of becoming a professional Open Source Developer. Then, exactly one year after completing my Linux Foundation training (at The Linux Foundation Training and Certification), in May 2017, I began my career in Open Source. 😀

2024 will mark my 8th consecutive year working as a professional Upstream Linux Kernel Engineer, and I feel so grateful for all the things that have happened over the years. 🐧

Thanks to all the people who have dedicated their careers to making the dream of Open Source possible. It’s really a great community, full of people who truly make a difference in the lives of billions of people around the world.

I’m so honored to be part of this family. 🙂

My Linux Kernel activities in May-July 2017

Hello everybody,

During this time I’ve managed to fix 151 issues in the Linux kernel. I got 16 patches upstream in May, 29 in June and 106 more in July.

The following is a list of the top ten Linux kernel developers over the last four months. I’ve managed to make it to the top three thanks to my recent contributions 🙂 :
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/stats

The following file contains detailed information regarding the categories and types of bugs I’ve resolved, as well as the software components in which they were detected:
https://github.com/GustavoARSilva/linux-hardening/blob/master/cii/2017/reports/mayjunjul_detailed

As a result, I’ve managed to contribute to the following subsystems and architectures during this time:

Below are more links to my contributions upstream during this time:

https://github.com/GustavoARSilva/linux-hardening/blob/master/cii/2017/reports/mayjunjul_commits.log
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/?qt=author&q=Gustavo+A.+R.+Silva

Also, during the last week I’ve been working with Julia Lawall on a Coccinelle script that is awaiting upstream at the moment. This script is going to help kernel developers to reduce the code size and increase maintainability, in cases where the lifetime of some variables don’t need to be extended beyond their scope. See the example below:

In the code above, the static on local variable var is unnecessary because such variable is always initialized before it can be used. So there is no need to extend the lifetime of the variable beyond its scope, which in this case is the foo() function.

I’ve managed to identify and fix more than 10 of such cases during the last month and, currently there exist around 60 more in the last linux-next tree.

Similar cases are expected to emerge in the Linux kernel in the future, as they can be easily introduced during code refactoring or maintenance.

The Coccinelle script I’ve been working on is intended to detect and fix those cases. Follow the link for more details: https://lkml.org/lkml/2017/8/1/34

Special thanks to The Linux Foundation‘s Core Infrastructure Initiative for supporting my work. 🙂

Gustavo A. R. Silva