liske / needrestart

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

Use of uninitialized value $ucode_vars{"CURRENT"} in concatenation #295

Open jlecour opened 7 months ago

jlecour commented 7 months ago

Hi, on a Lenovo x1 Carbon Gen 10 with Debian 12, I get this error :

# needrestart -b
NEEDRESTART-VER: 3.6
NEEDRESTART-KCUR: 6.1.0-17-amd64
NEEDRESTART-KEXP: 6.1.0-17-amd64
NEEDRESTART-KSTA: 1
NEEDRESTART-UCSTA: 1
Use of uninitialized value $ucode_vars{"CURRENT"} in concatenation (.) or string at /usr/sbin/needrestart line 940.
NEEDRESTART-UCCUR: 
Use of uninitialized value $ucode_vars{"AVAIL"} in concatenation (.) or string at /usr/sbin/needrestart line 941.
NEEDRESTART-UCEXP: 
NEEDRESTART-SESS: jlecour @ session #2

Context :

# uname -a
Linux synopsis 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64 GNU/Linux

# dpkg -l | grep microcode
ii  intel-microcode                          3.20231114.1~deb12u1                    amd64        Processor microcode firmware for Intel CPUs
ii  iucode-tool                              2.3.1-3                                 amd64        Intel processor microcode tool

# dpkg -l | grep needrestart
ii  needrestart                              3.6-4+deb12u1                           all          check which daemons need to be restarted after library upgrades
ii  needrestart-session                      0.3-11                                  all          check for processes need to be restarted in user sessions
stevemoca commented 7 months ago

I am also seeing the same thing, just starting with the recent Debian Stable point release v.12.5. Before that, there was no issue.

According to Debian, Stable release v.12.5 updated needrestart to "Fix microcode check regression on AMD CPUs". Unfortunately, the update seems to have created a new problem on Intel (at least, in my case):

root@san1:~# cat /etc/debian_version
12.5
root@san1:~# needrestart -b
NEEDRESTART-VER: 3.6
NEEDRESTART-KCUR: 6.1.0-18-amd64
NEEDRESTART-KEXP: 6.1.0-18-amd64
NEEDRESTART-KSTA: 1
NEEDRESTART-UCSTA: 1
Use of uninitialized value $ucode_vars{"CURRENT"} in concatenation (.) or string at /usr/sbin/needrestart line 940.
NEEDRESTART-UCCUR:
Use of uninitialized value $ucode_vars{"AVAIL"} in concatenation (.) or string at /usr/sbin/needrestart line 941.
NEEDRESTART-UCEXP:

Context: I am running an old, Intel-Xeon-based server:

root@san1:~# lscpu
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         36 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  4
  On-line CPU(s) list:   0-3
Vendor ID:               GenuineIntel
  BIOS Vendor ID:        Intel
  Model name:            Intel(R) Xeon(R) CPU E31220 @ 3.10GHz
    BIOS Model name:     Intel(R) Xeon(R) CPU E31220 @ 3.10GH            To Be Filled By O.E.M. CPU @ 3.1GHz
    BIOS CPU family:     179
    CPU family:          6
    Model:               42
    Thread(s) per core:  1
    Core(s) per socket:  4
    Socket(s):           1
    Stepping:            7
    CPU(s) scaling MHz:  47%
    CPU max MHz:         3400.0000
    CPU min MHz:         1600.0000
    BogoMIPS:            6185.66
    Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_
                         tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr
                         pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsave
                         opt dtherm ida arat pln pts md_clear flush_l1d
Virtualization features:
  Virtualization:        VT-x
Caches (sum of all):
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    1 MiB (4 instances)
  L3:                    8 MiB (1 instance)
NUMA:
  NUMA node(s):          1
  NUMA node0 CPU(s):     0-3
Vulnerabilities:
  Gather data sampling:  Not affected
  Itlb multihit:         KVM: Mitigation: Split huge pages
  L1tf:                  Mitigation; PTE Inversion; VMX conditional cache flushes, SMT disabled
  Mds:                   Mitigation; Clear CPU buffers; SMT disabled
  Meltdown:              Mitigation; PTI
  Mmio stale data:       Unknown: No mitigations
  Retbleed:              Not affected
  Spec rstack overflow:  Not affected
  Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:            Mitigation; usercopy/swapgs barriers and __user pointer sanitization
  Spectre v2:            Mitigation; Retpolines, IBPB conditional, IBRS_FW, STIBP disabled, RSB filling, PBRSB-eIBRS Not affected
  Srbds:                 Not affected
  Tsx async abort:       Not affected
dugwood commented 7 months ago

Same issue. The issue lies in Debian that didn't use the latest version of needrestart Perl library, which fixes it: https://github.com/liske/needrestart/commit/149e5462595584df472accfd3cf9d8ddb48e672f

Note that the code is clearly different, for instance: https://github.com/liske/needrestart/blob/master/perl/lib/NeedRestart/uCode.pm#L55

    unless ( exists( $vars{CURRENT} ) && exists( $vars{AVAIL} ) ) {

And in Debian's file: (using grep AVAIL /usr/share/perl5/NeedRestart/uCode.pm)

    unless ( exists( $vars{AVAIL} ) ) {

Strange thing I can't find a similar version in the commits on this repository.

Best option would be to update the code in /usr/share/perl5/NeedRestart/. Or use PERL5LIB=/usr/local/... where this repository would be cloned.

dugwood commented 6 months ago

Using strace on Debian 12's needrestart gives:

newfstatat(AT_FDCWD, "/etc/perl/NeedRestart.pmc", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/etc/perl/NeedRestart.pm", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/local/lib/x86_64-linux-gnu/perl/5.36.0/NeedRestart.pmc", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/local/lib/x86_64-linux-gnu/perl/5.36.0/NeedRestart.pm", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/local/share/perl/5.36.0/NeedRestart.pmc", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/local/share/perl/5.36.0/NeedRestart.pm", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/perl5/5.36/NeedRestart.pmc", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/perl5/5.36/NeedRestart.pm", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/share/perl5/NeedRestart.pmc", 0x7ffd2c30fe50, 0) = -1 ENOENT (Aucun fichier ou dossier de ce type)
newfstatat(AT_FDCWD, "/usr/share/perl5/NeedRestart.pm", {st_mode=S_IFREG|0644, st_size=6019, ...}, 0) = 0

Hence we can do the following:

  1. cd /usr/local/share/
  2. mkdir -p perl/5.36.0
  3. git clone -b "v3.6" --depth 1 https://github.com/liske/needrestart.git
  4. mv needrestart/perl/lib/* perl/5.36.0/
  5. rm needrestart -r

Now it works as expected with the latest v3.6 release, and without tampering the Debian package.

Good to know that a bug report has been opened on the BTS: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1063719

I suggest we leave this bug open for now (even if it's not a needrestart bug), and close it when Debian releases a bugfix. That will prevent other bug reports here.