summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2013-03-18 19:14:24 +0530
committerAnand Avati <avati@redhat.com>2013-04-12 10:07:23 -0700
commit30b4337d11d361cc8e0122bdb0d2ced09243813a (patch)
tree9ff065b2794b0998161bf2b5ace4e2fa094209e7
parent9b28ecc98dd5c773bf078e2e4d4752fa10c0daba (diff)
rpc: before freeing the volume options object, delete it from the list
* Suppose there is an xlator option which is considered by the xlator only if the source was built with debug mode enabled (the only example in the current code base is run-with-valgrind option for glusterd), then giving that option would make the process crash if the source was not built with debug mode enabled. Reason: In rpc, after getting the options symbol dynamically, it was stored in the newly allocated volume options structure and the structure's list head was added to the xlator's volume_options list. But while freeing the structure the list was not deleted. Thus when the list was traversed, already freed structure was accessed leading to segfault. Change-Id: I3e9e51dd2099e34b206199eae7ba44d9d88a86ad BUG: 922877 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/4687 Reviewed-by: Amar Tumballi <amarts@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-on: http://review.gluster.org/4818 Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
-rw-r--r--libglusterfs/src/xlator.c1
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c12
2 files changed, 7 insertions, 6 deletions
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index 22c81f81b88..3fb6eeebb09 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -264,6 +264,7 @@ xlator_dynload (xlator_t *xl)
gf_log (xl->name, GF_LOG_TRACE,
"Strict option validation not enforced -- neglecting");
}
+ INIT_LIST_HEAD (&vol_opt->list);
list_add_tail (&vol_opt->list, &xl->volume_options);
fill_defaults (xl);
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index 695261a71d9..c146fb63816 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -145,6 +145,7 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0;
volume_opt_list_t *vol_opt = NULL;
gf_boolean_t bind_insecure = _gf_false;
+ xlator_t *this = NULL;
GF_VALIDATE_OR_GOTO("rpc-transport", options, fail);
GF_VALIDATE_OR_GOTO("rpc-transport", ctx, fail);
@@ -292,26 +293,26 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
goto fail;
}
+ this = THIS;
vol_opt->given_opt = dlsym (handle, "options");
if (vol_opt->given_opt == NULL) {
gf_log ("rpc-transport", GF_LOG_DEBUG,
"volume option validation not specified");
} else {
INIT_LIST_HEAD (&vol_opt->list);
- list_add_tail (&vol_opt->list, &(THIS->volume_options));
- if (xlator_options_validate_list (THIS, options, vol_opt,
+ list_add_tail (&vol_opt->list, &(this->volume_options));
+ if (xlator_options_validate_list (this, options, vol_opt,
NULL)) {
gf_log ("rpc-transport", GF_LOG_ERROR,
"volume option validation failed");
goto fail;
}
- vol_opt = NULL;
}
trans->options = options;
pthread_mutex_init (&trans->lock, NULL);
- trans->xl = THIS;
+ trans->xl = this;
ret = trans->init (trans);
if (ret != 0) {
@@ -324,8 +325,6 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
GF_FREE (name);
- GF_FREE (vol_opt);
-
return return_trans;
fail:
@@ -340,6 +339,7 @@ fail:
GF_FREE (name);
+ list_del_init (&vol_opt->list);
GF_FREE (vol_opt);
return NULL;