Bug: libefibootguard corrupts efibootguard configuration

19 views
Skip to first unread message

Kaufmann, Bjoern

unread,
Feb 19, 2025, 9:23:31 AMFeb 19
to efibootg...@googlegroups.com, Lisicki, Raphael, Kiszka, Jan
Package: libefibootguard
Version: 0.15-1


Dear maintainers,

When opening and closing a context within libefibootguard, the bootloader config gets corrupted, inhibiting further boots of the system.

Context:
We are using efibootguard in context of isar-cip-core with A/B partitioning scheme:
Partition 1 - efibootguard
Partition 2 - efibootguard config A
Partition 3 - efibootguard config B

After software update, we need to know if the bootloader is in testing mode so that we can trigger a rollback. For this, we need to call ebg_env_getglobalstate which is taking a pointer provided by ebg_env_open_current.

Code:
ebgenv_t e;
ebg_env_open_current(&e); // seems that closing is not really needed, no leaks found.
uint16_t ustate = ebg_env_getglobalstate(NULL);
//ebg_env_close(&e); not closing it beacuse it writes & breaks

printf("obtained ustate is %u\n", ustate);

if (ustate == 2 /*testing mode */) {
return 0;
}
else {
return -1;
}

Expected Behaviour:
efibootguad configs (on partition 2 and 3) should not get corrupted.

Possible Solution/Workaround:
We are now calling ebg_env_getglobalstate with NULL as a parameter as, looking at the code, it is not used anyway. So we don't need to do open/close.

Steps to reproduce:

1. Do ebg_env_open_current and ebg_env_close in a loop and interrupt it with CTRL-C
2. check config with bg_printenv
3. one config is set to all (most) zeros. Works mostly on first attempt, retry loop if needed.


We can work for now, but this should be fixed in the future.


Thanks,
Bjoern

Storm, Christian

unread,
Feb 19, 2025, 10:34:18 AMFeb 19
to efibootg...@googlegroups.com
Hi Bjoern,

> Package: libefibootguard
> Version: 0.15-1

This is a rather old version of EFI Boot Guard... but upgrading won't help you here, see below reasoning.


> When opening and closing a context within libefibootguard, the bootloader config gets corrupted, inhibiting further boots of the system.

Whether or not they get "corrupted" depends on what you do (or rather not do) with a once opened environment. The problem is that, in the current implementation and semantics of libebgenv, `env_close()` first *writes* to the current environment and then closes it. If you happen to write the information you read, there's no corruption. However, you're writing to the environment for no good reason which one shouldn't do. This is why the SWUpdate binding to EFI Boot Guard (https://github.com/sbabic/swupdate/blob/master/bootloader/ebg.c#L89-L91) goes to great lengths to avoid this behavior...
Yes, this will definitely need to be addressed in a libebgenv version 2.0.



Kind regards,
Christian

--
Dr. Christian Storm
Siemens AG, FT RPD CED
Friedrich-Ludwig-Bauer-Str. 3, 85748 Garching, Germany

Jan Kiszka

unread,
Feb 19, 2025, 10:57:04 AMFeb 19
to Storm, Christian, efibootg...@googlegroups.com, Lisicki, Raphael, Kaufmann, Bjoern
We can simply make that usage of ebg_env_getglobalstate with NULL as
parameter official. It was and it will be never used because that
"global" in this function implies that a single, externally managed env
cannot contribute anything to the call.

Another way, but that implies calling a process and parsing output:

bg_printenv -c -r -o ustate

Jan

--
Siemens AG, Foundational Technologies
Linux Expert Center

Raphael Lisicki

unread,
Feb 19, 2025, 11:30:25 AMFeb 19
to Jan Kiszka, Storm, Christian, efibootg...@googlegroups.com, Kaufmann, Bjoern
Hi Jan,

On 19.02.25 16:56, Jan Kiszka wrote:
>
> We can simply make that usage of ebg_env_getglobalstate with NULL as
> parameter official. It was and it will be never used because that
> "global" in this function implies that a single, externally managed env
> cannot contribute anything to the call.
>

At least in version 0.15-1 directly calling ebg_env_getglobalstate did not
work. It appeared to work but the returned result was always the same.
That's why Bjoerns snippet still contains ebg_env_open_current allthough
its return value is not used.

ebg_env_open_current and others do some internal initialization (not
referenced by their returned handle) that is needed as well.

best regards
Raphael

Jan Kiszka

unread,
Feb 19, 2025, 11:49:26 AMFeb 19
to Raphael Lisicki, Storm, Christian, efibootg...@googlegroups.com, Kaufmann, Bjoern
That seems even more weird. All that should still be needed is bgenv_init.

Can you reproduce with the latest version as well?

Raphael Lisicki

unread,
Feb 19, 2025, 11:55:49 AMFeb 19
to Jan Kiszka, Storm, Christian, efibootg...@googlegroups.com, Kaufmann, Bjoern


On 19.02.25 17:49, Jan Kiszka wrote:
> On 19.02.25 17:30, 'Raphael Lisicki' via EFI Boot Guard wrote:
>> Hi Jan,
>>
>> On 19.02.25 16:56, Jan Kiszka wrote:
>>>
>>> We can simply make that usage of ebg_env_getglobalstate with NULL as
>>> parameter official. It was and it will be never used because that
>>> "global" in this function implies that a single, externally managed env
>>> cannot contribute anything to the call.
>>>
>>
>> At least in version 0.15-1 directly calling ebg_env_getglobalstate did not
>> work. It appeared to work but the returned result was always the same.
>> That's why Bjoerns snippet still contains ebg_env_open_current allthough
>> its return value is not used.
>>
>> ebg_env_open_current and others do some internal initialization (not
>> referenced by their returned handle) that is needed as well.
>>
>
> That seems even more weird. All that should still be needed is bgenv_init.

I don't remember which function it was, maybe that one. I only remember that
the function was not declared in a system header. Linking by implicit
declaration worked, but seemed worse than the lone ebg_env_open_current.

>
> Can you reproduce with the latest version as well?

I can try again tomorrow.


>
> Jan
>


best regards
Raphael

Jan Kiszka

unread,
Feb 19, 2025, 12:59:17 PMFeb 19
to Raphael Lisicki, Storm, Christian, efibootg...@googlegroups.com, Kaufmann, Bjoern
Ouch, yes, bgenv_init is only indirectly called, either via
ebg_env_create_new or ebg_env_open_current. We could also call it in
ebg_env_getglobalstate, though.

>>
>> Can you reproduce with the latest version as well?
>
> I can try again tomorrow.
>

No need to, no difference there, unfortunately.
Reply all
Reply to author
Forward
0 new messages