Bug 2082359

Summary: grub2-rpm-sort always crashes with "out of memory" error with grub2-2.06-39.fc37 , built with gcc-12.0.1-0.17.fc37
Product: [Fedora] Fedora Reporter: Adam Williamson <awilliam>
Component: grub2Assignee: Javier Martinez Canillas <fmartine>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: urgent Docs Contact:
Priority: unspecified    
Version: rawhideCC: aoliva, dmalcolm, fmartine, fweimer, jakub, jwakely, law, lkundrak, mpolacek, msebor, nickc, pgnet.dev, pjones, rharwood, robatino, sipoyare
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard: openqa
Fixed In Version: grub2-2.06-40.fc37 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-05-05 22:21:10 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2009537    

Description Adam Williamson 2022-05-05 20:59:14 UTC
In today's Rawhide compose, all installs fail to boot. Digging into it, I found this is because the bootloader entries don't have the right kernel args, and that is because grub2-rpm-sort is broken (which breaks grub2-mkconfig's attempt to update the bootloader entries, because it doesn't find them).

There was no change to the grub2-rpm-sort code between -38 and -39, but -38 was built with gcc 12.0.1-0.16.fc37 , while -39 was built with 12.0.1-0.17.fc37 , and I suspect that might be the cause.

To reproduce, just try this command:

echo lalala | /usr/sbin/grub2-rpm-sort

with grub2-tools-2.06-38.fc37 and grub2-tools-2.06-39.fc37. With -38 it prints "lalala" and exits 0. With -39 it prints "/usr/sbin/grub2-rpm-sort: error: out of memory." and exits 1.

This is an obvious F37 Beta blocker as it prevents any install from booting.

Comment 1 Adam Williamson 2022-05-05 21:00:48 UTC
CCing Jakub as we suspect gcc caused this.

Comment 2 Adam Williamson 2022-05-05 21:02:00 UTC
https://github.com/rhboot/grub2/blob/fedora-37/util/grub-rpm-sort.c is , I believe, the source code for this tool (correct me if I'm wrong, grub folks).

Comment 3 Robbie Harwood 2022-05-05 21:34:36 UTC
With a breakpoint set in add_input(), the first time through the loop, at line 159

(gdb) p	input_buffer
$11 = 0x5555555ab850 "sdf\nfoo\n"
(gdb) p	strchrnul(input_buffer, '\n')
$12 = 0x5555555ab853 "\nfoo\n"

But when we get to line 161:

(gdb) p	position_of_newline
$14 = 0x555ab853 <error: Cannot access memory at address 0x555ab853>
(gdb) p	sz
$15 = 18446650250148970499

This results in a request for a gigantic allocation on line 170, which fails.

I don't think there's anything grub2 can do here; reassigning.

> https://github.com/rhboot/grub2/blob/fedora-37/util/grub-rpm-sort.c is , I believe, the source code for this tool (correct me if I'm wrong, grub folks).

It is, though using debuginfo/debugsource and grub2-tools-2.06-39.fc37.x86_64 is what I did.

Comment 4 Jakub Jelinek 2022-05-05 21:51:01 UTC
Just look at the log file, ignoring warnings is a bad idea, especially warnings like -Wimplicit-function-declaration.
Looking at https://kojipkgs.fedoraproject.org/packages/grub2/2.06/39.fc37/data/logs/x86_64/build.log , I see a lot of them.
The above is most likely caused by:
../util/grub-rpm-sort.c: In function 'add_input':
../util/grub-rpm-sort.c:159:33: warning: implicit declaration of function 'strchrnul' [-Wimplicit-function-declaration]
  159 |          (position_of_newline = strchrnul (input_buffer, '\n')))
      |                                 ^~~~~~~~~
../util/grub-rpm-sort.c:159:33: warning: nested extern declaration of 'strchrnul' [-Wnested-externs]
../util/grub-rpm-sort.c:159:31: warning: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
  159 |          (position_of_newline = strchrnul (input_buffer, '\n')))
      |                               ^
An undeclared function in C is implicitly handled like returning int, so int strchrnul ();
but when it returns a pointer, that matches what you're seeing above, strchrnul returns 0x5555555ab853 but (char *) (int) 0x5555555ab853 is
0x555ab853

Comment 5 Adam Williamson 2022-05-06 07:01:38 UTC
Fix confirmed in testing, thanks!