summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2017-11-16 09:47:00 +0100
committerAmar Tumballi <amarts@redhat.com>2017-11-24 16:54:44 +0000
commitf3a8953e6a72631dc29958e996388ffed2f5940a (patch)
treec0a1de0651f3985374f85131485f4a61bacf5f58
parentd395387f601c9fb57a5fd9f19385b4de3c870de8 (diff)
libglusterfs: fix the call_stack_set_group() function
- call_stack_set_group() will take the ownership of passed buffer from caller; - to indicate the change, its signature is changed from including the buffer directly to take a pointer to it; - either the content of the buffer is copied to the groups_small embedded buffer of the call stack, or the buffer is set as groups_large member of the call stack; - the groups member of the call stack is set to, respectively, groups_small or groups_large, according to the memory management conventions of the call stack; - the buffer address is overwritten with junk to effectively prevent the caller from using it further on. Also move call_stack_set_group to stack.c from stack.h to prevent "defined but not used [-Wunused-function]" warnings (not using it anymore in call_stack_alloc_group() implementation, which saved us from this so far). protocol/server: refactor gid_resolve() In gid_resolve there are two cases: either the gid_cache_lookup() call returns a value or not. The result is caputured in the agl variable, and throughout the function, each particular stage of the implementation comes with an agl and a no-agl variant. In most cases this is explicitly indicated via an if (agl) { ... } else { ... } but some of this branching are expressed via goto constructs (obfuscating the fact we stated above, that is, each particular stage having an agl/no-agl variant). In the current refactor, we bring the agl conditional to the top, and present the agl/non-agl implementations sequentially. Also we take the opportunity to clean up and fix the agl case: - remove the spurious gl.gl_list = agl->gl_list; setting, as gl is not used in the agl caae - populate the group list of call stack from agl, fixing thus referred BUG. Also fixes BUG: 1513920 Change-Id: I61f4574ba21969f7661b9ff0c9dce202b874025d BUG: 1513928 Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r--libglusterfs/src/stack.c20
-rw-r--r--libglusterfs/src/stack.h14
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c2
-rw-r--r--xlators/protocol/server/src/server-helpers.c65
4 files changed, 57 insertions, 44 deletions
diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c
index bf905ca0b0e..61c779b0453 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -63,6 +63,26 @@ create_frame (xlator_t *xl, call_pool_t *pool)
}
void
+call_stack_set_groups (call_stack_t *stack, int ngrps, gid_t **groupbuf_p)
+{
+ /* We take the ownership of the passed group buffer. */
+
+ if (ngrps <= SMALL_GROUP_COUNT) {
+ memcpy (stack->groups_small, *groupbuf_p,
+ sizeof (gid_t) * ngrps);
+ stack->groups = stack->groups_small;
+ GF_FREE (*groupbuf_p);
+ } else {
+ stack->groups_large = *groupbuf_p;
+ stack->groups = stack->groups_large;
+ }
+
+ stack->ngrps = ngrps;
+ /* Set a canary. */
+ *groupbuf_p = (void *)0xdeadf00d;
+}
+
+void
gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
{
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index ac395fcc4b0..251a5c25e85 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -390,26 +390,21 @@ STACK_RESET (call_stack_t *stack)
} while (0)
-static void
-call_stack_set_groups (call_stack_t *stack, int ngrps, gid_t *groupbuf)
-{
- stack->groups = groupbuf;
- stack->ngrps = ngrps;
-}
-
static inline int
call_stack_alloc_groups (call_stack_t *stack, int ngrps)
{
if (ngrps <= SMALL_GROUP_COUNT) {
- call_stack_set_groups (stack, ngrps, stack->groups_small);
+ stack->groups = stack->groups_small;
} else {
stack->groups_large = GF_CALLOC (ngrps, sizeof (gid_t),
gf_common_mt_groups_t);
if (!stack->groups_large)
return -1;
- call_stack_set_groups (stack, ngrps, stack->groups_large);
+ stack->groups = stack->groups_large;
}
+ stack->ngrps = ngrps;
+
return 0;
}
@@ -507,6 +502,7 @@ copy_frame (call_frame_t *frame)
return newframe;
}
+void call_stack_set_groups (call_stack_t *stack, int ngrps, gid_t **groupbuf_p);
void gf_proc_dump_pending_frames(call_pool_t *call_pool);
void gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool,
dict_t *dict);
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 3fc6b16c41f..c59ff772cb8 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -181,7 +181,7 @@ frame_fill_groups (call_frame_t *frame)
return;
}
- call_stack_set_groups (frame->root, ngroups, mygroups);
+ call_stack_set_groups (frame->root, ngroups, &mygroups);
} else {
ret = snprintf (filename, sizeof filename, "/proc/%d/status",
frame->root->pid);
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 35f6cd00564..7ff5f16e7f0 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -31,13 +31,24 @@ gid_resolve (server_conf_t *conf, call_stack_t *root)
struct passwd *result;
gid_t *mygroups = NULL;
gid_list_t gl;
- const gid_list_t *agl;
int ngroups;
+ const gid_list_t *agl;
agl = gid_cache_lookup (&conf->gid_cache, root->uid, 0, 0);
if (agl) {
root->ngrps = agl->gl_count;
- goto fill_groups;
+
+ if (root->ngrps > 0) {
+ ret = call_stack_alloc_groups (root, agl->gl_count);
+ if (ret == 0) {
+ memcpy (root->groups, agl->gl_list,
+ sizeof (gid_t) * agl->gl_count);
+ }
+ }
+
+ gid_cache_release (&conf->gid_cache, agl);
+
+ return ret;
}
ret = getpwuid_r (root->uid, &mypw, mystrs, sizeof(mystrs), &result);
@@ -66,42 +77,28 @@ gid_resolve (server_conf_t *conf, call_stack_t *root)
}
root->ngrps = (uint16_t) ngroups;
-fill_groups:
- if (agl) {
- /* the gl is not complete, we only use gl.gl_list later on */
- gl.gl_list = agl->gl_list;
- } else {
- /* setup a full gid_list_t to add it to the gid_cache */
- gl.gl_id = root->uid;
- gl.gl_uid = root->uid;
- gl.gl_gid = root->gid;
- gl.gl_count = root->ngrps;
-
- gl.gl_list = GF_MALLOC (root->ngrps * sizeof(gid_t),
- gf_common_mt_groups_t);
- if (gl.gl_list)
- memcpy (gl.gl_list, mygroups,
- sizeof(gid_t) * root->ngrps);
- else {
- GF_FREE (mygroups);
- return -1;
- }
+ /* setup a full gid_list_t to add it to the gid_cache */
+ gl.gl_id = root->uid;
+ gl.gl_uid = root->uid;
+ gl.gl_gid = root->gid;
+ gl.gl_count = root->ngrps;
+
+ gl.gl_list = GF_MALLOC (root->ngrps * sizeof(gid_t),
+ gf_common_mt_groups_t);
+ if (gl.gl_list)
+ memcpy (gl.gl_list, mygroups,
+ sizeof(gid_t) * root->ngrps);
+ else {
+ GF_FREE (mygroups);
+ return -1;
}
- if (root->ngrps == 0) {
- ret = 0;
- goto out;
+ if (root->ngrps > 0) {
+ call_stack_set_groups (root, root->ngrps, &mygroups);
}
- call_stack_set_groups (root, root->ngrps, mygroups);
-
-out:
- if (agl) {
- gid_cache_release (&conf->gid_cache, agl);
- } else {
- if (gid_cache_add (&conf->gid_cache, &gl) != 1)
- GF_FREE (gl.gl_list);
- }
+ if (gid_cache_add (&conf->gid_cache, &gl) != 1)
+ GF_FREE (gl.gl_list);
return ret;
}