summaryrefslogtreecommitdiffstats
path: root/hw/9pfs
diff options
context:
space:
mode:
authorKeno Fischer2018-06-07 12:17:22 +0200
committerGreg Kurz2018-06-07 12:17:22 +0200
commitaca6897fba149a2a650dcdf5a5e1ae828371f4aa (patch)
tree19182be4a0de142101c0618944c1af0c5d5b99d1 /hw/9pfs
parent9p: Properly check/translate flags in unlinkat (diff)
downloadqemu-aca6897fba149a2a650dcdf5a5e1ae828371f4aa.tar.gz
qemu-aca6897fba149a2a650dcdf5a5e1ae828371f4aa.tar.xz
qemu-aca6897fba149a2a650dcdf5a5e1ae828371f4aa.zip
9p: xattr: Properly translate xattrcreate flags
As with unlinkat, these flags come from the client and need to be translated to their host values. The protocol values happen to match linux, but that need not be true in general. Signed-off-by: Keno Fischer <keno@juliacomputing.com> Signed-off-by: Greg Kurz <groug@kaod.org>
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/9p.c17
-rw-r--r--hw/9pfs/9p.h4
2 files changed, 19 insertions, 2 deletions
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index c842ec555e..eef289e394 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3327,7 +3327,7 @@ out_nofid:
static void coroutine_fn v9fs_xattrcreate(void *opaque)
{
- int flags;
+ int flags, rflags = 0;
int32_t fid;
uint64_t size;
ssize_t err = 0;
@@ -3344,6 +3344,19 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
}
trace_v9fs_xattrcreate(pdu->tag, pdu->id, fid, name.data, size, flags);
+ if (flags & ~(P9_XATTR_CREATE | P9_XATTR_REPLACE)) {
+ err = -EINVAL;
+ goto out_nofid;
+ }
+
+ if (flags & P9_XATTR_CREATE) {
+ rflags |= XATTR_CREATE;
+ }
+
+ if (flags & P9_XATTR_REPLACE) {
+ rflags |= XATTR_REPLACE;
+ }
+
if (size > XATTR_SIZE_MAX) {
err = -E2BIG;
goto out_nofid;
@@ -3365,7 +3378,7 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
xattr_fidp->fs.xattr.copied_len = 0;
xattr_fidp->fs.xattr.xattrwalk_fid = false;
xattr_fidp->fs.xattr.len = size;
- xattr_fidp->fs.xattr.flags = flags;
+ xattr_fidp->fs.xattr.flags = rflags;
v9fs_string_init(&xattr_fidp->fs.xattr.name);
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
xattr_fidp->fs.xattr.value = g_malloc0(size);
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index bad8ee719c..8883761b2c 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -169,6 +169,10 @@ typedef struct V9fsConf
char *fsdev_id;
} V9fsConf;
+/* 9p2000.L xattr flags (matches Linux values) */
+#define P9_XATTR_CREATE 1
+#define P9_XATTR_REPLACE 2
+
typedef struct V9fsXattr
{
uint64_t copied_len;