diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-01 12:36:33 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-01 12:38:05 -0400 |
commit | d25feadebbf05d6fce55cfee1e3c8f928903f543 (patch) | |
tree | e3c4342442c9014e70c5874eb340c6a0cb133beb | |
parent | 010b8dd4f6e8e3c3d2e44ff589ff61cbf64b952a (diff) | |
download | tor-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_450 | 5 | ||||
-rw-r--r-- | src/common/compat.c | 16 |
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; } |