aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-07-01 12:36:33 -0400
committerNick Mathewson <nickm@torproject.org>2011-07-01 12:38:05 -0400
commitd25feadebbf05d6fce55cfee1e3c8f928903f543 (patch)
treee3c4342442c9014e70c5874eb340c6a0cb133beb
parent010b8dd4f6e8e3c3d2e44ff589ff61cbf64b952a (diff)
downloadtor-d25feadebbf05d6fce55cfee1e3c8f928903f543.tar
tor-d25feadebbf05d6fce55cfee1e3c8f928903f543.tar.gz
Fix insanely large stack_allocation in log_credential_status
I'm not one to insist on C's miserly stack limits, but allocating a 256K array on the stack is too much even for me. Bugfix on 0.2.1.7-alpha. Found by coverity. Fixes CID # 450.
-rw-r--r--changes/cid_4505
-rw-r--r--src/common/compat.c16
2 files changed, 19 insertions, 2 deletions
diff --git a/changes/cid_450 b/changes/cid_450
new file mode 100644
index 000000000..2045fca23
--- /dev/null
+++ b/changes/cid_450
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Don't stack-allocate the list of supplementary GIDs when we're
+ about to log them. Stack-allocating NGROUPS_MAX gid_t elements
+ could take up to 256K, which is way too much stack. Found by
+ Coverity; CID #450. Bugfix on 0.2.1.7-alpha.
diff --git a/src/common/compat.c b/src/common/compat.c
index 39651084a..9533c115b 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1080,7 +1080,8 @@ log_credential_status(void)
/* Read, effective and saved GIDs */
gid_t rgid, egid, sgid;
/* Supplementary groups */
- gid_t sup_gids[NGROUPS_MAX + 1];
+ gid_t *sup_gids = NULL;
+ int sup_gids_size;
/* Number of supplementary groups */
int ngids;
@@ -1126,9 +1127,19 @@ log_credential_status(void)
#endif
/* log supplementary groups */
- if ((ngids = getgroups(NGROUPS_MAX + 1, sup_gids)) < 0) {
+ sup_gids_size = 64;
+ sup_gids = tor_malloc(sizeof(gid_t) * 64);
+ while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 &&
+ errno == EINVAL &&
+ sup_gids_size < NGROUPS_MAX) {
+ sup_gids_size *= 2;
+ sup_gids = tor_realloc(sup_gids, sizeof(gid_t) * sup_gids_size);
+ }
+
+ if (ngids < 0) {
log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s",
strerror(errno));
+ tor_free(sup_gids);
return -1;
} else {
int i, retval = 0;
@@ -1158,6 +1169,7 @@ log_credential_status(void)
tor_free(cp);
});
smartlist_free(elts);
+ tor_free(sup_gids);
return retval;
}