|
|
21ab4e |
From eb266456a714fe5c31444d3bdbfdfa744382ac50 Mon Sep 17 00:00:00 2001
|
|
|
21ab4e |
From: Poornima G <pgurusid@redhat.com>
|
|
|
21ab4e |
Date: Thu, 3 Aug 2017 17:43:22 +0530
|
|
|
21ab4e |
Subject: [PATCH 599/601] gfapi: Duplicate the buffer sent in setxattr calls
|
|
|
21ab4e |
|
|
|
21ab4e |
Issue:
|
|
|
21ab4e |
The caller of glfs_setxattr sends a buffer to set as the value.
|
|
|
21ab4e |
We create a dict in which the pointer to the value is set.
|
|
|
21ab4e |
Underlying layers like md-cache take a ref on this dict to store
|
|
|
21ab4e |
the value for a longer time. But the moment setxattr is complete,
|
|
|
21ab4e |
the caller of glfs_setxattr can free the value memory.
|
|
|
21ab4e |
|
|
|
21ab4e |
Solution:
|
|
|
21ab4e |
memcpy the setxattr value to the gluster buffer.
|
|
|
21ab4e |
|
|
|
21ab4e |
> Reviewed-on: https://review.gluster.org/17967
|
|
|
21ab4e |
> Reviewed-by: soumya k <skoduri@redhat.com>
|
|
|
21ab4e |
> Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
> Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
|
|
|
21ab4e |
> (cherry picked from commit e11296f8e52b7e3b13d21b41d4fa34baea878edf)
|
|
|
21ab4e |
|
|
|
21ab4e |
Change-Id: I58753fe702e8b7d0f6c4f058714c65d0ad5d7a0a
|
|
|
21ab4e |
BUG: 1457713
|
|
|
21ab4e |
Signed-off-by: Poornima G <pgurusid@redhat.com>
|
|
|
21ab4e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/114763
|
|
|
21ab4e |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
21ab4e |
---
|
|
|
21ab4e |
api/src/glfs-fops.c | 18 ++++++++++++++----
|
|
|
21ab4e |
api/src/glfs-handleops.c | 8 +++++++-
|
|
|
21ab4e |
api/src/glfs-internal.h | 1 -
|
|
|
21ab4e |
libglusterfs/src/dict.c | 10 ++++++++--
|
|
|
21ab4e |
libglusterfs/src/dict.h | 3 ++-
|
|
|
21ab4e |
xlators/features/bit-rot/src/bitd/bit-rot.c | 2 +-
|
|
|
21ab4e |
xlators/features/upcall/src/upcall.c | 4 ++--
|
|
|
21ab4e |
7 files changed, 34 insertions(+), 12 deletions(-)
|
|
|
21ab4e |
|
|
|
21ab4e |
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
|
|
|
21ab4e |
index 41d4795..3bba7d6 100644
|
|
|
21ab4e |
--- a/api/src/glfs-fops.c
|
|
|
21ab4e |
+++ b/api/src/glfs-fops.c
|
|
|
21ab4e |
@@ -3572,6 +3572,7 @@ glfs_setxattr_common (struct glfs *fs, const char *path, const char *name,
|
|
|
21ab4e |
struct iatt iatt = {0, };
|
|
|
21ab4e |
dict_t *xattr = NULL;
|
|
|
21ab4e |
int reval = 0;
|
|
|
21ab4e |
+ void *value_cp = NULL;
|
|
|
21ab4e |
|
|
|
21ab4e |
DECLARE_OLD_THIS;
|
|
|
21ab4e |
__GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
|
|
|
21ab4e |
@@ -3606,8 +3607,13 @@ retry:
|
|
|
21ab4e |
if (ret)
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
|
|
|
21ab4e |
- xattr = dict_for_key_value (name, value, size);
|
|
|
21ab4e |
+ value_cp = gf_memdup (value, size);
|
|
|
21ab4e |
+ GF_CHECK_ALLOC_AND_LOG (subvol->name, value_cp, ret, "Failed to"
|
|
|
21ab4e |
+ " duplicate setxattr value", out);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ xattr = dict_for_key_value (name, value_cp, size, _gf_false);
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
+ GF_FREE (value_cp);
|
|
|
21ab4e |
ret = -1;
|
|
|
21ab4e |
errno = ENOMEM;
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
@@ -3616,8 +3622,6 @@ retry:
|
|
|
21ab4e |
ret = syncop_setxattr (subvol, &loc, xattr, flags, NULL, NULL);
|
|
|
21ab4e |
DECODE_SYNCOP_ERR (ret);
|
|
|
21ab4e |
|
|
|
21ab4e |
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
|
|
|
21ab4e |
-
|
|
|
21ab4e |
out:
|
|
|
21ab4e |
loc_wipe (&loc;;
|
|
|
21ab4e |
if (xattr)
|
|
|
21ab4e |
@@ -3660,6 +3664,7 @@ pub_glfs_fsetxattr (struct glfs_fd *glfd, const char *name, const void *value,
|
|
|
21ab4e |
xlator_t *subvol = NULL;
|
|
|
21ab4e |
dict_t *xattr = NULL;
|
|
|
21ab4e |
fd_t *fd = NULL;
|
|
|
21ab4e |
+ void *value_cp = NULL;
|
|
|
21ab4e |
|
|
|
21ab4e |
DECLARE_OLD_THIS;
|
|
|
21ab4e |
__GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
|
|
|
21ab4e |
@@ -3692,8 +3697,13 @@ pub_glfs_fsetxattr (struct glfs_fd *glfd, const char *name, const void *value,
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
- xattr = dict_for_key_value (name, value, size);
|
|
|
21ab4e |
+ value_cp = gf_memdup (value, size);
|
|
|
21ab4e |
+ GF_CHECK_ALLOC_AND_LOG (subvol->name, value_cp, ret, "Failed to"
|
|
|
21ab4e |
+ " duplicate setxattr value", out);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ xattr = dict_for_key_value (name, value_cp, size, _gf_false);
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
+ GF_FREE (value_cp);
|
|
|
21ab4e |
ret = -1;
|
|
|
21ab4e |
errno = ENOMEM;
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c
|
|
|
21ab4e |
index a464b2e..88f9ab1 100644
|
|
|
21ab4e |
--- a/api/src/glfs-handleops.c
|
|
|
21ab4e |
+++ b/api/src/glfs-handleops.c
|
|
|
21ab4e |
@@ -481,6 +481,7 @@ pub_glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object,
|
|
|
21ab4e |
inode_t *inode = NULL;
|
|
|
21ab4e |
loc_t loc = {0, };
|
|
|
21ab4e |
dict_t *xattr = NULL;
|
|
|
21ab4e |
+ void *value_cp = NULL;
|
|
|
21ab4e |
|
|
|
21ab4e |
/* validate in args */
|
|
|
21ab4e |
if ((fs == NULL) || (object == NULL) ||
|
|
|
21ab4e |
@@ -517,8 +518,13 @@ pub_glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object,
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
- xattr = dict_for_key_value (name, value, size);
|
|
|
21ab4e |
+ value_cp = gf_memdup (value, size);
|
|
|
21ab4e |
+ GF_CHECK_ALLOC_AND_LOG (subvol->name, value_cp, ret, "Failed to"
|
|
|
21ab4e |
+ " duplicate setxattr value", out);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ xattr = dict_for_key_value (name, value_cp, size, _gf_false);
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
+ GF_FREE (value_cp);
|
|
|
21ab4e |
ret = -1;
|
|
|
21ab4e |
errno = ENOMEM;
|
|
|
21ab4e |
goto out;
|
|
|
21ab4e |
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
|
|
|
21ab4e |
index f78fcfd..3f4ed71 100644
|
|
|
21ab4e |
--- a/api/src/glfs-internal.h
|
|
|
21ab4e |
+++ b/api/src/glfs-internal.h
|
|
|
21ab4e |
@@ -367,7 +367,6 @@ int glfs_loc_touchup (loc_t *loc)
|
|
|
21ab4e |
void glfs_iatt_to_stat (struct glfs *fs, struct iatt *iatt, struct stat *stat);
|
|
|
21ab4e |
int glfs_loc_link (loc_t *loc, struct iatt *iatt);
|
|
|
21ab4e |
int glfs_loc_unlink (loc_t *loc);
|
|
|
21ab4e |
-dict_t *dict_for_key_value (const char *name, const char *value, size_t size);
|
|
|
21ab4e |
int glfs_getxattr_process (void *value, size_t size, dict_t *xattr,
|
|
|
21ab4e |
const char *name);
|
|
|
21ab4e |
|
|
|
21ab4e |
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
|
|
|
21ab4e |
index d0c56d5..8881173 100644
|
|
|
21ab4e |
--- a/libglusterfs/src/dict.c
|
|
|
21ab4e |
+++ b/libglusterfs/src/dict.c
|
|
|
21ab4e |
@@ -2992,7 +2992,8 @@ dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain)
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
dict_t *
|
|
|
21ab4e |
-dict_for_key_value (const char *name, const char *value, size_t size)
|
|
|
21ab4e |
+dict_for_key_value (const char *name, const char *value, size_t size,
|
|
|
21ab4e |
+ gf_boolean_t is_static)
|
|
|
21ab4e |
{
|
|
|
21ab4e |
dict_t *xattr = NULL;
|
|
|
21ab4e |
int ret = 0;
|
|
|
21ab4e |
@@ -3001,7 +3002,12 @@ dict_for_key_value (const char *name, const char *value, size_t size)
|
|
|
21ab4e |
if (!xattr)
|
|
|
21ab4e |
return NULL;
|
|
|
21ab4e |
|
|
|
21ab4e |
- ret = dict_set_static_bin (xattr, (char *)name, (void *)value, size);
|
|
|
21ab4e |
+ if (is_static)
|
|
|
21ab4e |
+ ret = dict_set_static_bin (xattr, (char *)name, (void *)value,
|
|
|
21ab4e |
+ size);
|
|
|
21ab4e |
+ else
|
|
|
21ab4e |
+ ret = dict_set_bin (xattr, (char *)name, (void *)value, size);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
if (ret) {
|
|
|
21ab4e |
dict_destroy (xattr);
|
|
|
21ab4e |
xattr = NULL;
|
|
|
21ab4e |
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
|
|
|
21ab4e |
index b0efad7..b5d9f3e 100644
|
|
|
21ab4e |
--- a/libglusterfs/src/dict.h
|
|
|
21ab4e |
+++ b/libglusterfs/src/dict.h
|
|
|
21ab4e |
@@ -257,7 +257,8 @@ gf_boolean_t
|
|
|
21ab4e |
dict_match_everything (dict_t *d, char *k, data_t *v, void *data);
|
|
|
21ab4e |
|
|
|
21ab4e |
dict_t *
|
|
|
21ab4e |
-dict_for_key_value (const char *name, const char *value, size_t size);
|
|
|
21ab4e |
+dict_for_key_value (const char *name, const char *value, size_t size,
|
|
|
21ab4e |
+ gf_boolean_t is_static);
|
|
|
21ab4e |
|
|
|
21ab4e |
gf_boolean_t
|
|
|
21ab4e |
are_dicts_equal (dict_t *one, dict_t *two,
|
|
|
21ab4e |
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
21ab4e |
index d88231b..55191da 100644
|
|
|
21ab4e |
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
21ab4e |
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
21ab4e |
@@ -421,7 +421,7 @@ br_object_read_sign (inode_t *linked_inode, fd_t *fd, br_object_t *object,
|
|
|
21ab4e |
|
|
|
21ab4e |
xattr = dict_for_key_value
|
|
|
21ab4e |
(GLUSTERFS_SET_OBJECT_SIGNATURE,
|
|
|
21ab4e |
- (void *)sign, signature_size (SHA256_DIGEST_LENGTH));
|
|
|
21ab4e |
+ (void *)sign, signature_size (SHA256_DIGEST_LENGTH), _gf_true);
|
|
|
21ab4e |
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
gf_msg (this->name, GF_LOG_ERROR, 0, BRB_MSG_SET_SIGN_FAILED,
|
|
|
21ab4e |
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
|
|
|
21ab4e |
index a9d3c8a..0f1d980 100644
|
|
|
21ab4e |
--- a/xlators/features/upcall/src/upcall.c
|
|
|
21ab4e |
+++ b/xlators/features/upcall/src/upcall.c
|
|
|
21ab4e |
@@ -1876,7 +1876,7 @@ up_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
|
|
|
21ab4e |
|
|
|
21ab4e |
EXIT_IF_UPCALL_OFF (this, out);
|
|
|
21ab4e |
|
|
|
21ab4e |
- xattr = dict_for_key_value (name, "", 1);
|
|
|
21ab4e |
+ xattr = dict_for_key_value (name, "", 1, _gf_true);
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
op_errno = ENOMEM;
|
|
|
21ab4e |
goto err;
|
|
|
21ab4e |
@@ -1964,7 +1964,7 @@ up_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
21ab4e |
|
|
|
21ab4e |
EXIT_IF_UPCALL_OFF (this, out);
|
|
|
21ab4e |
|
|
|
21ab4e |
- xattr = dict_for_key_value (name, "", 1);
|
|
|
21ab4e |
+ xattr = dict_for_key_value (name, "", 1, _gf_true);
|
|
|
21ab4e |
if (!xattr) {
|
|
|
21ab4e |
op_errno = ENOMEM;
|
|
|
21ab4e |
goto err;
|
|
|
21ab4e |
--
|
|
|
21ab4e |
1.8.3.1
|
|
|
21ab4e |
|