file: write through symlinks on uci commit
authorJo-Philipp Wich <jo@mein.io>
Thu, 31 Mar 2016 00:06:12 +0000 (02:06 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 31 Mar 2016 00:06:14 +0000 (02:06 +0200)
The rename() syscall operates on the destination path directly, therfore
resolve the real path before doing the rename to not clobber the destination
in case it is a symlink pointing to another file.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
file.c

diff --git a/file.c b/file.c
index 35755d83ad8c04dc016d1045e9c3ae4f44b0354c..7e1e4e6f0ddcdbb545c4e83efda52fb33031374a 100644 (file)
--- a/file.c
+++ b/file.c
@@ -800,9 +800,13 @@ done:
        free(name);
        free(path);
        uci_close_stream(f1);
-       if (do_rename && rename(filename, p->path)) {
-               unlink(filename);
-               UCI_THROW(ctx, UCI_ERR_IO);
+       if (do_rename) {
+               path = realpath(p->path, NULL);
+               if (!path || rename(filename, path)) {
+                       unlink(filename);
+                       UCI_THROW(ctx, UCI_ERR_IO);
+               }
+               free(path);
        }
        free(filename);
        if (ctx->err)