My First Kernel Patch - Part 4

Introduction

This journal entry was written by me, Brandon Nolet, in the context that this is taking much more time than I expected and I’m having trouble concentrating on one task at a time.

The other task is learning org-mode and how to implement templates by directory. I anticipate that will take longer than learning to patch this kernel.

Continuing

As mentioned in the last post I felt it was necessary to re-download the source of the linux kernel. I made some modifications while patching that went wrong (due to a misunderstanding of the patch program) and I wasn’t sure how to revert those changes. Perhaps a greater knowledge of git might have solved that.

Anyway, now that I’ve re-cloned the kernel source, I’m going to get to patching. Where did I put those patches again?

I think there might have been a problem with applying the patches I did. I re-read the security bulletin and it turns out that (and I know, I should have paid more attention) only some of the patches actually apply to the kernel I’m compiling. Here’s a list of the patches I’ll be applying, with the respective links.

Since I’m using Linux Kernel version 5.2.0 patches PATCH_net_1a_4.patch and PATCH_net_2_4.patch are not necessary (as per the security bulletin).

Patching

Now that the appropriate patches have been downloaded and saved, it’s time to apply them (again).

Starting with the first patch, I run the patch command below:


patch -p1 <../patches/PATCH_net_1_4.patch

Again, I’m getting that message I got last time:


Reversed (or previously applied) patch detected!  Assume -R? [n]

This time I will say no, and apply patch anyway. The message just means that either the patch was actually previously applied or that the source code being patched is newer than the patch I’m applying. Patch uses an unreliable method of determining this, in my opinion.

Again, I got hunks failing, but let’s carry on and see what happens. I’m sure I’ll come back here and end up modifying the code by hand, but that’s okay.

On the second patch, it’s basically the same patch but replace the 1 in the patchfile name with a 3, and a 4 for the 4_4 patch.

Okay, so every single patch resulted in patches being “skipped”. Let’s find out what that means. Using --verbose proved to be ineffective and trying to find why a patch might be skipped resulted in a bunch of posts about why you might skip a given patch. Useless.

Taking a Look Inside

I decided to peek inside the files that are being patched and see if there’s any difference between the supposed original state of the source file and the supposed patched state, all mentioned in the patch. There is a difference, and it’s quite substantial.

That being said, the changes made are trivial do to by hand so I think I will do such right now. It’s going to be a little tedious, I’m sure, but I’m up for the task!

For some reason I decided to start at patch 4_4 and…it was a change that was already applied!

The following was added in the patch:


mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss);

This was already present in the source code downloaded.

As I thought, this is the case for several more of the hunks that failed. It seems like all of the hunks in patch 1_4 were irrelevant as the functions they were meant to patch had been rewritten or refactored in some way. Either the problems are fixed or it’s beyond me to figure out how to fix them.

The Final Compilations

I guess it’s time to perform the compilation! Wish me luck.


make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-sackpatched1

2 minutes in and we’ve made it much further than the first time I attempted to patch.

12 minutes in and we’re still going strong!

20 minutes in, and the following errors were achieved:


make[2]: *** [debian/rules:6: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2
make[1]: *** [scripts/package/Makefile:75: deb-pkg] Error 2
make: *** [Makefile:1420: deb-pkg] Error 2

I suspect this is due to not running make clean before compiling. Nope, I checked scripts/package/Makefile:75 and it has to do with file creation and moving:


mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz

So realistically it wasn’t a failure in compilation. Also, I found out that and the error obtained that was mentioned in the previous during the writing of the previous post(dpkg-source: error: cannot represent change to vmlinux-gdb.py:) was actually the result of an artifact of compilation. The vmlinux-gdb.py (from what I understand) is a configuration file for the GNU debugger software and doesn’t actually belong there during compilation time. Leaving it in between compilations will result in the error.

Let’s try again!

Again, failed. Maybe my theory was wrong? This time I’m going to re-copy the .config file over, and re-run the few commands after that. Then compile.

Here we go, one more time. If it still doesn’t compile, I’m throwing my hands up and calling it quits. Seeing as most of the patches were already applied, I think the previously compiled kernel I already applied to my VPS should be just fine.

I’m not entirely sure but I think this may have been the actual source of the compilation failure. It may have been hidden by the plethora of lines that are output during compilation as I wasn’t consistently watching the wall of text climb the screen:


net/ipv4/tcp_input.c:1386:5: error: redefinition of ‘tcp_skb_shift’
 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
     ^~~~~~~~~~~~~
net/ipv4/tcp_input.c:1371:5: note: previous definition of ‘tcp_skb_shift’ was here
 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
     ^~~~~~~~~~~~~
net/ipv4/tcp_input.c:1401:5: error: redefinition of ‘tcp_skb_shift’
 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
     ^~~~~~~~~~~~~
net/ipv4/tcp_input.c:1371:5: note: previous definition of ‘tcp_skb_shift’ was here
 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,

This looks to be the file that was modified by the patches applied. Looks like the hunks that succeeded…broke the source. Perhaps by the time I downloaded the source the patches had already been applied and this series should have been called My First Kernel Compilation - And Fussing Around With Unneeded Patches.

Yet it continues to compile.

And I just saw the errors just above scroll right out of the terminal buffer as the kernel nears the end of the failing compilation.

And we’re done.

Conclusion

Thank you for embarking on this crazy confusing adventure. If nothing it was certainly an opportunity to learn about the struggles of a kernel maintainer, about the patching process, about compiling the kernel, and about doing my due dilligence in reading.

This was a wild ride for me.