9ae3f9
From 56c8ef4a64506c64aeb95d5a2c38d7107f90ac3a Mon Sep 17 00:00:00 2001
9ae3f9
From: Xavi Hernandez <xhernandez@redhat.com>
9ae3f9
Date: Tue, 5 Feb 2019 16:57:52 +0100
9ae3f9
Subject: [PATCH 442/449] fuse: correctly handle setxattr values
9ae3f9
9ae3f9
The setxattr function receives a pointer to raw data, which may not be
9ae3f9
null-terminated. When this data needs to be interpreted as a string, an
9ae3f9
explicit null termination needs to be added before using the value.
9ae3f9
9ae3f9
Upstream patch https://review.gluster.org/#/c/glusterfs/+/22157
9ae3f9
> Change-Id: Id110f9b215b22786da5782adec9449ce38d0d563
9ae3f9
> updates: bz#1193929
9ae3f9
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
9ae3f9
9ae3f9
Note: this change is not addressing the issue of bz 1787310,
9ae3f9
indeed it is prerequisite for other changes that do.
9ae3f9
9ae3f9
BUG: 1787310
9ae3f9
Change-Id: I56417b130eb2a1f388108456c905a577eb658793
9ae3f9
Signed-off-by: Csaba Henk <csaba@redhat.com>
9ae3f9
Reviewed-on: https://code.engineering.redhat.com/gerrit/202758
9ae3f9
Tested-by: RHGS Build Bot <nigelb@redhat.com>
9ae3f9
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
9ae3f9
---
9ae3f9
 libglusterfs/src/glusterfs/xlator.h  |  2 +-
9ae3f9
 libglusterfs/src/xlator.c            | 28 +++++++++++++++++++++++++---
9ae3f9
 xlators/mount/fuse/src/fuse-bridge.c | 20 ++++++++++++++++----
9ae3f9
 3 files changed, 42 insertions(+), 8 deletions(-)
9ae3f9
9ae3f9
diff --git a/libglusterfs/src/glusterfs/xlator.h b/libglusterfs/src/glusterfs/xlator.h
9ae3f9
index db04c4d..8650ccc 100644
9ae3f9
--- a/libglusterfs/src/glusterfs/xlator.h
9ae3f9
+++ b/libglusterfs/src/glusterfs/xlator.h
9ae3f9
@@ -1043,7 +1043,7 @@ xlator_mem_acct_init(xlator_t *xl, int num_types);
9ae3f9
 void
9ae3f9
 xlator_mem_acct_unref(struct mem_acct *mem_acct);
9ae3f9
 int
9ae3f9
-is_gf_log_command(xlator_t *trans, const char *name, char *value);
9ae3f9
+is_gf_log_command(xlator_t *trans, const char *name, char *value, size_t size);
9ae3f9
 int
9ae3f9
 glusterd_check_log_level(const char *value);
9ae3f9
 int
9ae3f9
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
9ae3f9
index 6bd4f09..108b96a 100644
9ae3f9
--- a/libglusterfs/src/xlator.c
9ae3f9
+++ b/libglusterfs/src/xlator.c
9ae3f9
@@ -1278,8 +1278,21 @@ xlator_destroy(xlator_t *xl)
9ae3f9
     return 0;
9ae3f9
 }
9ae3f9
 
9ae3f9
+static int32_t
9ae3f9
+gf_bin_to_string(char *dst, size_t size, void *src, size_t len)
9ae3f9
+{
9ae3f9
+    if (len >= size) {
9ae3f9
+        return EINVAL;
9ae3f9
+    }
9ae3f9
+
9ae3f9
+    memcpy(dst, src, len);
9ae3f9
+    dst[len] = 0;
9ae3f9
+
9ae3f9
+    return 0;
9ae3f9
+}
9ae3f9
+
9ae3f9
 int
9ae3f9
-is_gf_log_command(xlator_t *this, const char *name, char *value)
9ae3f9
+is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size)
9ae3f9
 {
9ae3f9
     xlator_t *trav = NULL;
9ae3f9
     char key[1024] = {
9ae3f9
@@ -1291,7 +1304,11 @@ is_gf_log_command(xlator_t *this, const char *name, char *value)
9ae3f9
     glusterfs_ctx_t *ctx = NULL;
9ae3f9
 
9ae3f9
     if (!strcmp("trusted.glusterfs.syslog", name)) {
9ae3f9
-        ret = gf_string2boolean(value, &syslog_flag);
9ae3f9
+        ret = gf_bin_to_string(key, sizeof(key), value, size);
9ae3f9
+        if (ret != 0) {
9ae3f9
+            goto out;
9ae3f9
+        }
9ae3f9
+        ret = gf_string2boolean(key, &syslog_flag);
9ae3f9
         if (ret) {
9ae3f9
             ret = EOPNOTSUPP;
9ae3f9
             goto out;
9ae3f9
@@ -1307,7 +1324,12 @@ is_gf_log_command(xlator_t *this, const char *name, char *value)
9ae3f9
     if (fnmatch("trusted.glusterfs*set-log-level", name, FNM_NOESCAPE))
9ae3f9
         goto out;
9ae3f9
 
9ae3f9
-    log_level = glusterd_check_log_level(value);
9ae3f9
+    ret = gf_bin_to_string(key, sizeof(key), value, size);
9ae3f9
+    if (ret != 0) {
9ae3f9
+        goto out;
9ae3f9
+    }
9ae3f9
+
9ae3f9
+    log_level = glusterd_check_log_level(key);
9ae3f9
     if (log_level == -1) {
9ae3f9
         ret = EOPNOTSUPP;
9ae3f9
         goto out;
9ae3f9
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
9ae3f9
index 2e7584c..cfad2b4 100644
9ae3f9
--- a/xlators/mount/fuse/src/fuse-bridge.c
9ae3f9
+++ b/xlators/mount/fuse/src/fuse-bridge.c
9ae3f9
@@ -4112,7 +4112,7 @@ fuse_setxattr(xlator_t *this, fuse_in_header_t *finh, void *msg,
9ae3f9
 
9ae3f9
     /* Check if the command is for changing the log
9ae3f9
        level of process or specific xlator */
9ae3f9
-    ret = is_gf_log_command(this, name, value);
9ae3f9
+    ret = is_gf_log_command(this, name, value, fsi->size);
9ae3f9
     if (ret >= 0) {
9ae3f9
         op_errno = ret;
9ae3f9
         goto done;
9ae3f9
@@ -4159,11 +4159,23 @@ fuse_setxattr(xlator_t *this, fuse_in_header_t *finh, void *msg,
9ae3f9
          * fixups to make sure that's the case.  To avoid nasty
9ae3f9
          * surprises, allocate an extra byte and add a NUL here.
9ae3f9
          */
9ae3f9
-        dict_value = memdup(value, fsi->size + 1);
9ae3f9
+        dict_value = GF_MALLOC(fsi->size + 1, gf_common_mt_char);
9ae3f9
+        if (dict_value == NULL) {
9ae3f9
+            gf_log("glusterfs-fuse", GF_LOG_ERROR,
9ae3f9
+                   "%" PRIu64 ": SETXATTR value allocation failed",
9ae3f9
+                   finh->unique);
9ae3f9
+            op_errno = ENOMEM;
9ae3f9
+            goto done;
9ae3f9
+        }
9ae3f9
+        memcpy(dict_value, value, fsi->size);
9ae3f9
         dict_value[fsi->size] = '\0';
9ae3f9
     }
9ae3f9
-    dict_set(state->xattr, newkey,
9ae3f9
-             data_from_dynptr((void *)dict_value, fsi->size));
9ae3f9
+    ret = dict_set_dynptr(state->xattr, newkey, dict_value, fsi->size);
9ae3f9
+    if (ret < 0) {
9ae3f9
+        op_errno = -ret;
9ae3f9
+        GF_FREE(dict_value);
9ae3f9
+        goto done;
9ae3f9
+    }
9ae3f9
 
9ae3f9
     state->flags = fsi->flags;
9ae3f9
     state->name = newkey;
9ae3f9
-- 
9ae3f9
1.8.3.1
9ae3f9