qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH -V3 23/32] vritio-9p: Fix chmod bug with directory


From: Aneesh Kumar K.V
Subject: [Qemu-devel] [PATCH -V3 23/32] vritio-9p: Fix chmod bug with directory
Date: Thu, 25 Mar 2010 22:13:31 +0530

chmod 0777 <dir>  fails with EIO.
This is a result of wrong check in server code.
Server code is trying to check if the file type is not being changed by
making sure that fidp->dir is not NULL.
But the fidp->dir is set only on opendir/createdir.

This patch gives proper check to all special files.

Signed-off-by: Venkateswararao Jujjuri <address@hidden>
Signed-off-by: Aneesh Kumar K.V <address@hidden>
---
 hw/virtio-9p.c |   56 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 9aa4b72..e519605 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -298,11 +298,12 @@ static int free_fid(V9fsState *s, int32_t fid)
 #define P9_STAT_MODE_SETGID    0x00040000
 #define P9_STAT_MODE_SETVTX    0x00010000
 
-#define P9_STAT_MODE_SPECIAL   (P9_STAT_MODE_NAMED_PIPE | \
-                                P9_STAT_MODE_SYMLINK | \
-                                P9_STAT_MODE_LINK | \
-                                P9_STAT_MODE_DEVICE)
-
+#define P9_STAT_MODE_TYPE_BITS (P9_STAT_MODE_DIR |             \
+                               P9_STAT_MODE_SYMLINK |          \
+                               P9_STAT_MODE_LINK |             \
+                                P9_STAT_MODE_DEVICE |          \
+                                P9_STAT_MODE_NAMED_PIPE |      \
+                                P9_STAT_MODE_SOCKET)
 
 /* This is the algorithm from ufs in spfs */
 static void stat_to_qid(const struct stat *stbuf, V9fsQID *qidp)
@@ -1842,6 +1843,7 @@ typedef struct V9fsWstatState
     int16_t unused;
     V9fsStat v9stat;
     V9fsFidState *fidp;
+    struct stat stbuf;
     V9fsString nname;
 } V9fsWstatState;
 
@@ -2034,6 +2036,37 @@ static int donttouch_stat(V9fsStat *stat)
                return 0;
 }
 
+static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
+{
+    uint32_t v9_mode;
+
+    if (err == -1) {
+        err = -errno;
+        goto out;
+    }
+
+    v9_mode = stat_to_v9mode(&vs->stbuf);
+
+    if ((vs->v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=
+        (v9_mode & P9_STAT_MODE_TYPE_BITS)) {
+            /* Attempting to change the type */
+            err = -EIO;
+            goto out;
+    }
+
+    if (posix_chmod(s, &vs->fidp->path, v9mode_to_mode(vs->v9stat.mode,
+                    &vs->v9stat.extension))) {
+            err = -errno;
+     }
+    v9fs_wstat_post_chmod(s, vs, err);
+    return;
+
+out:
+    v9fs_stat_free(&vs->v9stat);
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs);
+}
+
 static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
@@ -2060,16 +2093,9 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
     }
 
     if (vs->v9stat.mode != -1) {
-        if (vs->v9stat.mode & P9_STAT_MODE_DIR && vs->fidp->dir == NULL) {
-            err = -EIO;
-            goto out;
-        }
-
-        if (posix_chmod(s, &vs->fidp->path,
-                    v9mode_to_mode(vs->v9stat.mode,
-                        &vs->v9stat.extension))) {
-            err = -errno;
-        }
+        err = posix_lstat(s, &vs->fidp->path, &vs->stbuf);
+        v9fs_wstat_post_lstat(s, vs, err);
+        return;
     }
 
     v9fs_wstat_post_chmod(s, vs, err);
-- 
1.7.0.2.323.g0d092





reply via email to

[Prev in Thread] Current Thread [Next in Thread]