diff options
author | Michael Adam <obnox@samba.org> | 2015-03-31 12:30:06 +0200 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-03-31 23:08:23 -0700 |
commit | 562cdace9152add786f156e38dc3fbc8805a69b7 (patch) | |
tree | 758c327eb3ba017ebdcd8add5d423e8f104e45ec /xlators/features | |
parent | f5e4c943cf520c6ec2df3c231fef9ae4116097b8 (diff) |
features/trash: fix storing/wiping of eliminate path (coverity)
Functions store_eliminate_path() and wipe_eliminate_path() take
eliminate as a plain pointer not pointer to pointer. Hence
store_eliminate_path fails to hand the allocated and filled
eliminate data out to the caller (in particular leaking memory),
and wipe_eliminate_path() fails to NULL the freed eliminate path.
This leads to several leak and access after free errors found
by Coverity. This patch fixes the issue by handing in eliminate
by reference and in the case of wipe_eliminate path, also NULLing
out the free'd pointer.
This fixes the following coverity IDs:
CID 1288759
CID 1288790
Change-Id: I7520ae42c5f6e369a145bea67b4ff95b75d2ae73
BUG: 789278
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-on: http://review.gluster.org/10068
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anoop C S <achiraya@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/features')
-rw-r--r-- | xlators/features/trash/src/trash.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c index d0e48506d4a..fb9ca9a0ee5 100644 --- a/xlators/features/trash/src/trash.c +++ b/xlators/features/trash/src/trash.c @@ -173,7 +173,7 @@ check_whether_eliminate_path (trash_elim_path *trav, const char *path) * Stores the eliminate path into internal eliminate path structure */ int -store_eliminate_path (char *str, trash_elim_path *eliminate) +store_eliminate_path (char *str, trash_elim_path **eliminate) { trash_elim_path *trav = NULL; char *component = NULL; @@ -181,6 +181,11 @@ store_eliminate_path (char *str, trash_elim_path *eliminate) int ret = 0; char *strtokptr = NULL; + if (eliminate == NULL) { + ret = EINVAL; + goto out; + } + component = strtok_r (str, ",", &strtokptr); while (component) { trav = GF_CALLOC (1, sizeof (*trav), @@ -203,8 +208,8 @@ store_eliminate_path (char *str, trash_elim_path *eliminate) gf_log ("trash", GF_LOG_DEBUG, "out of memory"); goto out; } - trav->next = eliminate; - eliminate = trav; + trav->next = *eliminate; + *eliminate = trav; component = strtok_r (NULL, ",", &strtokptr); } out: @@ -259,13 +264,20 @@ out: * recursive call */ void -wipe_eliminate_path (trash_elim_path *trav) +wipe_eliminate_path (trash_elim_path **trav) { - if (trav) { - wipe_eliminate_path (trav->next); - GF_FREE (trav->path); - GF_FREE (trav); + if (trav == NULL) { + return; } + + if (*trav == NULL) { + return; + } + + wipe_eliminate_path (&(*trav)->next); + GF_FREE ((*trav)->path); + GF_FREE (*trav); + *trav = NULL; } /** @@ -1967,7 +1979,7 @@ reconfigure (xlator_t *this, dict_t *options) "no option specified for 'eliminate', using NULL"); } else { if (priv->eliminate) - wipe_eliminate_path (priv->eliminate); + wipe_eliminate_path (&priv->eliminate); tmp_str = gf_strdup (tmp); if (!tmp_str) { @@ -1975,7 +1987,7 @@ reconfigure (xlator_t *this, dict_t *options) ret = ENOMEM; goto out; } - ret = store_eliminate_path (tmp_str, priv->eliminate); + ret = store_eliminate_path (tmp_str, &priv->eliminate); } @@ -2256,7 +2268,7 @@ init (xlator_t *this) ret = ENOMEM; goto out; } - ret = store_eliminate_path (tmp_str, priv->eliminate); + ret = store_eliminate_path (tmp_str, &priv->eliminate); } tmp = NULL; @@ -2326,7 +2338,7 @@ out: if (priv->brick_path) GF_FREE (priv->brick_path); if (priv->eliminate) - wipe_eliminate_path (priv->eliminate); + wipe_eliminate_path (&priv->eliminate); GF_FREE (priv); } mem_pool_destroy (this->local_pool); @@ -2353,7 +2365,7 @@ fini (xlator_t *this) if (priv->brick_path) GF_FREE (priv->brick_path); if (priv->eliminate) - wipe_eliminate_path (priv->eliminate); + wipe_eliminate_path (&priv->eliminate); GF_FREE (priv); } mem_pool_destroy (this->local_pool); |