liske / needrestart

Restart daemons after library updates.
GNU General Public License v2.0
420 stars 67 forks source link

wrong report of needed kernel upgrade if kernel name is too long #293

Closed jaycci closed 6 months ago

jaycci commented 9 months ago

When the kernel version string is too long, needrestart falsely reports that the kernels needs ABI upgrade.

needrestart needs a better way to parse the kernel version string from the kernel file.

How to see the problem (with my kernel):

/usr/sbin/needrestart -bkvvvvvvvvvv
[...]
[Kernel] Linux: kernel release 6.1.42-syshawk-amd64, kernel version #6086+bookworm SMP PREEMPT_DYNAMIC Sat Nov 18 18:57:15 UTC 2023
Failed to load NeedRestart::Kernel::kFreeBSD: [Kernel/kFreeBSD] Not running on GNU/kFreeBSD!
[Kernel/Linux] /boot/vmlinuz-6.1.42-syshawk-amd64 => 6.1.42-syshawk-amd64 (root@runner-q6tz9kj-project-23-concurrent-0) #6086+bookworm SMP PREEMPT_DYNAMIC Sat Nov 18 18:57:15 UTC 20 [6.1.42-syshawk-amd64]
[Kernel/Linux] Expected linux version: 6.1.42-syshawk-amd64
NEEDRESTART-KCUR: 6.1.42-syshawk-amd64
NEEDRESTART-KEXP: 6.1.42-syshawk-amd64
NEEDRESTART-KSTA: 2

If you look at the version string in the kernel file, you'll read:

strings /boot/vmlinuz-6.1.42-syshawk-amd64 |grep '6.1.42'
6.1.42-syshawk-amd64 (root@runner-q6tz9kj-project-23-concurrent-0) #6086+bookworm SMP PREEMPT_DYNAMIC Sat Nov 18 18:57:15 UTC 2023
6.1.42-syshawk-amd64 (root@runner-q6tz9kj-project-23-concurrent-0) (gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #6086+bookworm SMP PREEMPT_DYNAMIC Sat Nov 18 18:57:15 UTC 2023

The first line is the one grabbed by needrestart (see file needrestart/perl/lib/NeedRestart/Kernel/Linux.pm function nr_linux_version_x86($$)).

This function hardcodes a max length of the kernel string of "128" bytes read from the file: https://github.com/liske/needrestart/blob/280c1aeaff28a7f1ff1f38e7427e938a7e3579fd/perl/lib/NeedRestart/Kernel/Linux.pm#L71

As you can see in my example, the version string of the kernel is 130 bytes, more than 128.

The documentation for this string (https://www.kernel.org/doc/html/v6.1/x86/boot.html, look for "kernel version") only says that the string is NUL-terminated.

The hardcoded max length of "128" should be increased, or another way to parse this string should be chosen (but I don't know the best way to do it).

pietsch commented 7 months ago

Doubling the buffer size as suggested by @jaycci fixed the false positive in Rocky Linux 9.3 (Blue Onyx) for me. It's based on RHEL. My currently running kernel is called /boot/vmlinuz-5.14.0-362.13.1.el9_3.x86_64. Here is some output after monkeypatching:

# /usr/sbin/needrestart -bkvvvvvvvvvv
[main] eval /etc/needrestart/needrestart.conf
[main] needrestart v3.6
[main] running in root mode
[main] systemd detected
NEEDRESTART-VER: 3.6
[Kernel] Linux: kernel release 5.14.0-362.13.1.el9_3.x86_64, kernel version #1 SMP PREEMPT_DYNAMIC Wed Dec 13 14:07:45 UTC 2023
Failed to load NeedRestart::Kernel::kFreeBSD: [Kernel/kFreeBSD] Not running on GNU/kFreeBSD!
[Kernel/Linux] /boot/vmlinuz-5.14.0-362.13.1.el9_3.x86_64 => 5.14.0-362.13.1.el9_3.x86_64 (mockbuild@iad1-prod-build001.bld.equ.rockylinux.org) #1 SMP PREEMPT_DYNAMIC Wed Dec 13 14:07:45 UTC 2023 [5.14.0-362.13.1.el9_3.x86_64]*
[Kernel/Linux] /boot/vmlinuz-5.14.0-362.8.1.el9_3.x86_64 => 5.14.0-362.8.1.el9_3.x86_64 (mockbuild@iad1-prod-build001.bld.equ.rockylinux.org) #1 SMP PREEMPT_DYNAMIC Wed Nov 8 17:36:32 UTC 2023 [5.14.0-362.8.1.el9_3.x86_64]
[Kernel/Linux] /boot/vmlinuz-5.14.0-284.30.1.el9_2.x86_64 => 5.14.0-284.30.1.el9_2.x86_64 (mockbuild@iad1-prod-build001.bld.equ.rockylinux.org) #1 SMP PREEMPT_DYNAMIC Sat Sep 16 09:55:41 UTC 2023 [5.14.0-284.30.1.el9_2.x86_64]
[Kernel/Linux] /boot/vmlinuz-0-rescue-27326f61465d413b9d1e91c582c7d28f => 5.14.0-362.8.1.el9_3.x86_64 (mockbuild@iad1-prod-build001.bld.equ.rockylinux.org) #1 SMP PREEMPT_DYNAMIC Wed Nov 8 17:36:32 UTC 2023 [5.14.0-362.8.1.el9_3.x86_64]
[Kernel/Linux] /boot/vmlinuz-0-rescue-e9cdc240366d4c94b251b55d2cfed1e0 => 5.14.0-284.11.1.el9_2.x86_64 (mockbuild@iad1-prod-build001.bld.equ.rockylinux.org) #1 SMP PREEMPT_DYNAMIC Tue May 9 17:09:15 UTC 2023 [5.14.0-284.11.1.el9_2.x86_64]
[Kernel/Linux] using RPM version sorting
[Kernel/Linux] Expected linux version: 5.14.0-362.13.1.el9_3.x86_64
NEEDRESTART-KCUR: 5.14.0-362.13.1.el9_3.x86_64
NEEDRESTART-KEXP: 5.14.0-362.13.1.el9_3.x86_64
NEEDRESTART-KSTA: 1
liske commented 6 months ago

Thanks for the analysis.

I've increased the read to 512 bytes. That should work for most (all?) setups in the field while not making the code not more complex as needed.