Currently, the lockfile used by fw_printenv / fw_setenv is created
with permissions 0666 minus umask, i.e. typically it ends up with 0644
permissions.
But, since it is created in a world-readable directory [/run since
aeb40f1166e ("tools: env: use /run to store lockfile")], that means
that any unprivileged user can subsequently open that file for
reading, place a flock(2), and never unlock it, which is effectively a
DOS.
For example, on boards that use RAUC and store the BOOT_x metadata in
the U-Boot environment, the lock file would typically be created early
in boot when the the rauc-mark-good service records that the current
slot succesfully booted. If a malicious user then permanently locks
that file, any subsequent attempt to install new firmware via RAUC
would fail, as would anything else using fw_setenv/fw_printenv.
Trivial POC (in two terminal windows):
$ id -u ; flock -x /run/fw_printenv.lock sleep 15
1919
# id -u ; time fw_printenv > /dev/null
0
real 0m13.786s
user 0m0.007s
sys 0m0.000s
Signed-off-by: Rasmus Villemoes <[email protected]>
---
tools/env/fw_env_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c
index 0b201b9e624..116a39ea909 100644
--- a/tools/env/fw_env_main.c
+++ b/tools/env/fw_env_main.c
@@ -250,7 +250,7 @@ int main(int argc, char *argv[])
env_opts.lockname, CMD_PRINTENV);
}
- lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (-1 == lockfd) {
fprintf(stderr, "Error opening lock file %s\n", lockname);
return EXIT_FAILURE;
--
2.55.0