From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

Fixed path resolution in futimesat and sys_utimensat functions

When another filesystem is mounted at /tmp or similar mount point
functions futimesat and utimensat do not resolve absolute path
properly and cause relevant unit tests to fail. This patch addresses this bugs
by making sure the mount point is also prepended to the path.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
Message-Id: <1517397781-8383-1-git-send-email-jwkozac...@gmail.com>

---
diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -1802,6 +1802,7 @@ int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
     struct stat st;
     struct file *fp;
     int error;
+    char *absolute_path;

     if ((pathname && pathname[0] == '/') || dirfd == AT_FDCWD)
         return utimes(pathname, times);
@@ -1825,17 +1826,19 @@ int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
     if (error)
         goto out_errno;

+    /* build absolute path */
+    absolute_path = (char*)malloc(PATH_MAX);
+    strlcpy(absolute_path, fp->f_dentry->d_mount->m_path, PATH_MAX);
+    strlcat(absolute_path, fp->f_dentry->d_path, PATH_MAX);
+
     if (pathname) {
-        auto length = strlen(fp->f_dentry->d_path) + strlen(pathname) + 2;
-        auto absolute_path = (char*)malloc(length);
- snprintf(absolute_path, length, "%s/%s", fp->f_dentry->d_path, pathname);
-        error = utimes(absolute_path, times);
-        free(absolute_path);
-    } else {
-        // TODO: it's really ugly how we convert the fd to path, and utimes
-        // will need to look up this path again.
-        error = utimes(fp->f_dentry->d_path, times);
+        strlcat(absolute_path, "/", PATH_MAX);
+        strlcat(absolute_path, pathname, PATH_MAX);
     }
+
+    error = utimes(absolute_path, times);
+    free(absolute_path);
+
     fdrop(fp);

     if (error)
diff --git a/fs/vfs/vfs_syscalls.cc b/fs/vfs/vfs_syscalls.cc
--- a/fs/vfs/vfs_syscalls.cc
+++ b/fs/vfs/vfs_syscalls.cc
@@ -1353,6 +1353,8 @@ sys_utimensat(int dirfd, const char *pathname, const struct timespec times[2], i
            ap = std::string(fp->f_dentry->d_path) + "/" + pathname;
        else
            ap = fp->f_dentry->d_path;
+
+       ap = std::string(fp->f_dentry->d_mount->m_path) + "/" + ap;
     }

     /* FIXME: Add support for AT_SYMLINK_NOFOLLOW */

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to