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

Reply via email to