[U-Boot] Using CONFIG_ENV_FLAGS_LIST

Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment. This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
Thanks, Claudius

Hi Claudius,
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment. This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
I think that Wolfgang had a long discussion with Takahiro AKASHI (both CC'ed) about similar problem with u-boot envs.
For example: https://patchwork.ozlabs.org/patch/1158770/
Thanks, Claudius
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

Hi Lukasz,
On 07/09/2019 00.23, Lukasz Majewski wrote:
Hi Claudius,
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment. This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
I think that Wolfgang had a long discussion with Takahiro AKASHI (both CC'ed) about similar problem with u-boot envs.
Were there any conclusions here?
For me this 'flags' feature looks more and more like its was not build to save guard the loading from unsigned and untrusted external environments. I think what we would need here is some sort of variable whitelist with some additional checks (type and size), but still allow the u-boot scripts and commands to modify the variables in the hash table (for filesize, ipaddr etc.) at boot time.
regards, Claudius
For example: https://patchwork.ozlabs.org/patch/1158770/
Thanks, Claudius
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

Hi Claudius,
Hi Lukasz,
On 07/09/2019 00.23, Lukasz Majewski wrote:
Hi Claudius,
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment. This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
I think that Wolfgang had a long discussion with Takahiro AKASHI (both CC'ed) about similar problem with u-boot envs.
Were there any conclusions here?
I don't know if there was any conclusion (or patches).
For me this 'flags' feature looks more and more like its was not build to save guard the loading from unsigned and untrusted external environments. I think what we would need here is some sort of variable whitelist with some additional checks (type and size), but still allow the u-boot scripts and commands to modify the variables in the hash table (for filesize, ipaddr etc.) at boot time.
Maybe Takahiro could shed some light on his work and you could discuss if your both work could be aligned?
regards, Claudius
For example: https://patchwork.ozlabs.org/patch/1158770/
Thanks, Claudius
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

On Mon, Sep 09, 2019 at 02:04:50PM +0200, Lukasz Majewski wrote:
Hi Claudius,
Hi Lukasz,
On 07/09/2019 00.23, Lukasz Majewski wrote:
Hi Claudius,
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment. This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
I think that Wolfgang had a long discussion with Takahiro AKASHI (both CC'ed) about similar problem with u-boot envs.
Were there any conclusions here?
I don't know if there was any conclusion (or patches).
No. As a matter of fact, I gave up my idea of modifying flags (attributes) features of U-Boot environment.
For me this 'flags' feature looks more and more like its was not build to save guard the loading from unsigned and untrusted external environments. I think what we would need here is some sort of variable whitelist with some additional checks (type and size), but still allow the u-boot scripts and commands to modify the variables in the hash table (for filesize, ipaddr etc.) at boot time.
Maybe Takahiro could shed some light on his work and you could discuss if your both work could be aligned?
Instead, I'm proposing 'multiple contexts' to be allowed for U-Boot environment[1]. The idea here is that we may have separated backing storage areas, for different variable domains with different needs in U-Boot environment. For example, in my implementation of UEFI variables, one for volatile (non-persistent) variables and another for non-volatile (persistent and auto-saved) variables. (Please note that a context is allowed *not* to have any backing storage.)
while I'm not sure yet exactly what Claudius's requirement is, please take a look at my patch below and find out if my work will fit your expectation.
[1] https://lists.denx.de/pipermail/u-boot/2019-September/382835.html
Thanks, -Takahiro Akashi
regards, Claudius
For example: https://patchwork.ozlabs.org/patch/1158770/
Thanks, Claudius
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

Hi Claudius,
On 02/09/19 16:02, Claudius Heine wrote:
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment.
But I think this is not mainlined.
This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
But '.flags' shoudl also be set as write once, else it is possible to rewrite the .flags variable making all environment read-write.
Heiko's patch is a work-around to get a signed environment. What I had for is to provide a signed environment (outside U-Boot with libubootenv), and U-Boot just verifies as it does for a kernel image - U-Boot does not need a private key, but U-Boot loses "saveenv" and the environment can be changed only from user space.
Regards, Stefano

Hi Stefano,
On 09/09/2019 13.26, Stefano Babic wrote:
Hi Claudius,
On 02/09/19 16:02, Claudius Heine wrote:
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment.
But I think this is not mainlined.
Correct.
This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
But '.flags' shoudl also be set as write once, else it is possible to rewrite the .flags variable making all environment read-write.
Heiko's patch is a work-around to get a signed environment. What I had for is to provide a signed environment (outside U-Boot with libubootenv), and U-Boot just verifies as it does for a kernel image - U-Boot does not need a private key, but U-Boot loses "saveenv" and the environment can be changed only from user space.
Interesting, however loosing 'saveenv' from within u-boot would very inconvenient though. If the environment signature is invalid, would you end up without one or load the internal one as fallback? If you load the internal environment, can it query the external environment verification state to handle this case and restore the external environment somehow?
regards, Claudius

On 09/09/19 14:54, Claudius Heine wrote:
Hi Stefano,
On 09/09/2019 13.26, Stefano Babic wrote:
Hi Claudius,
On 02/09/19 16:02, Claudius Heine wrote:
Hi,
I am currently looking into variable flags in order to make some variables read-only for secure boot.
The idea is that the u-boot binary is signed, while the environment file/partition is not. So the built-in default environment of u-boot can be trusted, while the external environment cannot. The assumption is that those flags can be used to customize the validation when the external environment is loaded or scripts/commands are executed.
From the '/README' I gather that the access attributes can be any of "any", "read-only", "write-once" or "change-default".
I first tried to restrict the variables by choosing 'read-only', but apparently this applies to the internal environment as well, and now those variables are not loaded from the internal environment.
Then I tried 'write-once', this worked now as expected from within u-boot, but I could modify the environment from the linux userspace via fw_setenv and those changes appear in u-boot as well. The same for 'change-default'.
Is there another way to fill the internal environment variable hash table, so that 'read-only' works as expected?
Heiko wrote some patches that change the behavior of the environment loading so that the internal environment is loaded first before the external environment.
But I think this is not mainlined.
Correct.
This way 'write-once' should work as expected, but I think 'read-only' should work that way already and we are missing something here.
But '.flags' shoudl also be set as write once, else it is possible to rewrite the .flags variable making all environment read-write.
Heiko's patch is a work-around to get a signed environment. What I had for is to provide a signed environment (outside U-Boot with libubootenv), and U-Boot just verifies as it does for a kernel image - U-Boot does not need a private key, but U-Boot loses "saveenv" and the environment can be changed only from user space.
Interesting, however loosing 'saveenv' from within u-boot would very inconvenient though.
Yes, but saveenv means that the environment must be signed and u-boot must know the private key, with all consequences. I guess it could go just with TPM support.
If the environment signature is invalid, would you end up without one or load the internal one as fallback?
The internal is always the falloback - and because if you need this feature, you have secure boot, U-Boot is signed and then the internal environment is signed, too.
If you load the internal environment, can it query the external environment verification state to handle this case and restore the external environment somehow?
If I understand the question, I think yes. When external environment is loaded, it could be verified with a public key. And if verified, this becomes the environment.
Regards, Stefano
participants (4)
-
AKASHI Takahiro
-
Claudius Heine
-
Lukasz Majewski
-
Stefano Babic