Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bootchooser for the output of efibootmgr 18 #1197

Merged
merged 3 commits into from
Aug 1, 2023

Conversation

dvzrv
Copy link
Contributor

@dvzrv dvzrv commented Jul 28, 2023

Since efibootmgr 18, the default output of efibootmgr is now more verbose [1], which breaks the assumptions made by RAUC in regards to parsing the output. This issue is also affecting others [2].

Fix the parsing logic by unconditionally splitting on a tab in the detected name part of the boot entry, so that the unused data part can be discarded.
Emit a debug message for each found boot entry, as this helps in detecting issues in the future.

[1] rhboot/efibootmgr@8ec3e9d
[2] rhboot/efibootmgr#169

This fix is not related to an open ticket, as I noticed this quite recently and got in touch on matrix to discuss a possible fix.
I verified this to work in an Arch Linux VM using efibootmgr 18 and a RAUC 1.10 with this patch applied.

As writing C is not really my forte, I'd appreciate feedback (especially whether this works as intended with efibootmgr < 18).

Copy link
Member

@jluebbe jluebbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure this can work reliably, we need to check that the boot name doesn't contain whitespace. See https://github.com/rauc/rauc/blob/master/src/config_file.c#L235 for the place where it is read. That area also has examples for reporting an error. The bootname check should be in a helper function.

src/bootchooser.c Outdated Show resolved Hide resolved
@dvzrv
Copy link
Contributor Author

dvzrv commented Jul 28, 2023

To make sure this can work reliably, we need to check that the boot name doesn't contain whitespace. See https://github.com/rauc/rauc/blob/master/src/config_file.c#L235 for the place where it is read. That area also has examples for reporting an error. The bootname check should be in a helper function.

Maybe I lack context here, but why can it not contain a whitespace? This seems certainly possible in the context of e.g. efibootmgr.

@jluebbe
Copy link
Member

jluebbe commented Jul 28, 2023

To make sure this can work reliably, we need to check that the boot name doesn't contain whitespace. See https://github.com/rauc/rauc/blob/master/src/config_file.c#L235 for the place where it is read. That area also has examples for reporting an error. The bootname check should be in a helper function.

Maybe I lack context here, but why can it not contain a whitespace? This seems certainly possible in the context of e.g. efibootmgr.

We currently don't have checks for the bootname, so it could contain a tab character. In that case, applying this change would break at runtime. Adding a check during config parsing would report that issue early. And while adding that check, we should also reject any unusual bootnames containing whitespace (to be better prepared for future efibootmgr changes).

@dvzrv
Copy link
Contributor Author

dvzrv commented Jul 28, 2023

We currently don't have checks for the bootname, so it could contain a tab character. In that case, applying this change would break at runtime. Adding a check during config parsing would report that issue early. And while adding that check, we should also reject any unusual bootnames containing whitespace (to be better prepared for future efibootmgr changes).

I see. But validating the config input and more robustly dealing with the output of efibootmgr are two separate issues (in my mind).
Are there any straightforward facilities to search for the right-most tab character? Maybe that would make more sense.

@dvzrv
Copy link
Contributor Author

dvzrv commented Jul 28, 2023

Are there any straightforward facilities to search for the right-most tab character? Maybe that would make more sense.

Ah, nevermind. That'd of course be problematic with efibootmgr < 18 and a bootname containing a single tab.

So generally you'd rather not allow tabs or spaces then, which makes sense I guess.

@dvzrv dvzrv force-pushed the dvzrv/bootchooser_efibootmgr_18 branch 4 times, most recently from f5a41df to 301b159 Compare July 28, 2023 17:39
@dvzrv dvzrv requested a review from jluebbe July 28, 2023 17:52
@codecov
Copy link

codecov bot commented Jul 30, 2023

Codecov Report

Patch coverage: 96.55% and project coverage change: +0.02% 🎉

Comparison is base (966a86b) 80.28% compared to head (84ecf94) 80.30%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1197      +/-   ##
==========================================
+ Coverage   80.28%   80.30%   +0.02%     
==========================================
  Files          58       58              
  Lines       18000    18029      +29     
==========================================
+ Hits        14451    14479      +28     
- Misses       3549     3550       +1     
Files Changed Coverage Δ
include/utils.h 100.00% <ø> (ø)
src/bootchooser.c 79.37% <80.00%> (+<0.01%) ⬆️
src/config_file.c 86.41% <100.00%> (+0.07%) ⬆️
src/utils.c 76.29% <100.00%> (+0.51%) ⬆️
test/config_file.c 99.85% <100.00%> (+<0.01%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@dvzrv dvzrv force-pushed the dvzrv/bootchooser_efibootmgr_18 branch 2 times, most recently from 8853e36 to 423f22c Compare July 30, 2023 17:12
@jluebbe jluebbe self-assigned this Jul 31, 2023
@jluebbe jluebbe force-pushed the dvzrv/bootchooser_efibootmgr_18 branch from 423f22c to 1b0de0c Compare July 31, 2023 13:41
@jluebbe
Copy link
Member

jluebbe commented Jul 31, 2023

I've adjusted the commit titles to our usual format, made some changes to the code (see the fixup commits) and added a test-case for the config value check. @dvzrv does this look OK for you? Could you test it with efibootmgr 18?

@jluebbe jluebbe requested a review from ejoerns July 31, 2023 13:42
@jluebbe jluebbe added this to the Release v1.10.1 milestone Jul 31, 2023
@jluebbe jluebbe assigned ejoerns and unassigned jluebbe Jul 31, 2023
@dvzrv dvzrv force-pushed the dvzrv/bootchooser_efibootmgr_18 branch from 1b0de0c to 8a9a1d2 Compare August 1, 2023 08:59
@dvzrv
Copy link
Contributor Author

dvzrv commented Aug 1, 2023

I've adjusted the commit titles to our usual format, made some changes to the code (see the fixup commits) and added a test-case for the config value check. @dvzrv does this look OK for you? Could you test it with efibootmgr 18?

Thanks! I've rebuild the package for Arch Linux locally with the updated fixes. Tests run fine and after installing the updated package in a VM (with A/B setup) the output of rauc status --detailed works without issue.

@dvzrv dvzrv force-pushed the dvzrv/bootchooser_efibootmgr_18 branch from 8a9a1d2 to a4d83ab Compare August 1, 2023 09:42
dvzrv and others added 3 commits August 1, 2023 13:08
Since efibootmgr 18, the default output of `efibootmgr` is now more
verbose [1], which breaks the assumptions made by RAUC in regards to
parsing the output. This issue is also affecting others [2].

Fix the parsing logic by unconditionally removing anything after a tab
in the detected name part of the boot entry, so that the unused data
part is discarded.
Emit a debug message for each found boot entry, as this helps in
detecting issues in the future.

[1] rhboot/efibootmgr@8ec3e9d
[2] rhboot/efibootmgr#169

Signed-off-by: David Runge <dave@sleepmap.de>
Add the new helper function `value_check_tab_whitespace()` which
errors on tab or whitespace in the input string.
Ensure that when parsing `bootname` in `parse_slots()`, that the values
do not contain tab or whitespace.

Signed-off-by: David Runge <dave@sleepmap.de>
Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
@dvzrv dvzrv force-pushed the dvzrv/bootchooser_efibootmgr_18 branch from a4d83ab to 84ecf94 Compare August 1, 2023 11:09
@ejoerns
Copy link
Member

ejoerns commented Aug 1, 2023

As we already have a regex there, wouldn't it make more sense to adapt this?

--- a/src/bootchooser.c
+++ b/src/bootchooser.c
@@ -1147,7 +1147,7 @@ static gboolean efi_bootorder_get(GList **bootorder_entries, GList **all_entries
        }

        /* Obtain mapping of efi boot numbers to bootnames */
-       regex = g_regex_new("^Boot([0-9a-fA-F]{4})[\\* ] (.+)$", G_REGEX_MULTILINE, 0, NULL);
+       regex = g_regex_new("^Boot([0-9a-fA-F]{4})[\\* ] ([^\\t\\n]+).*$", G_REGEX_MULTILINE, 0, NULL);
        if (!g_regex_match(regex, g_bytes_get_data(stdout_buf, NULL), 0, &match)) {
                g_set_error(
                                error,

works v17 and v18 this seems to work for me.

I have also an example here where there is a space in an EFI boot entry. Thus I would assume having spaces is uncommon but possible. Why would we want to reject both tabs and spaces if only tabs collide with known assumptions?

@jluebbe
Copy link
Member

jluebbe commented Aug 1, 2023

Spaces/tabs are also problematic for bootnames in other places, like the kernel cmdline, so it's better to reject them early.

The strchr approach seems simpler, so I prefer it for the point release.

@ejoerns
Copy link
Member

ejoerns commented Aug 1, 2023

Spaces/tabs are also problematic for bootnames in other places, like the kernel cmdline, so it's better to reject them early.

Since a broken config will fail early with this approach, go for it.

The strchr approach seems simpler, so I prefer it for the point release.

Agreed for the point release.

@ejoerns ejoerns merged commit 8bcd935 into rauc:master Aug 1, 2023
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants