Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[BZ #13761]
        * nscd/grpcache.c (cache_addgr): Rename alloca_used to
        dataset_temporary.  Track alloca usage into alloca_used.
        If dataset is large allocate and release it via malloc/free.
  • Loading branch information
Jeff Law committed Nov 29, 2012
1 parent 111db5b commit 2af1b32
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 19 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
@@ -1,3 +1,10 @@
2012-11-28 Jeff Law <law@redhat.com>

[BZ #13761]
* nscd/grpcache.c (cache_addgr): Rename alloca_used to
dataset_temporary. Track alloca usage into alloca_used.
If dataset is large allocate and release it via malloc/free.

2012-06-04 Florian Weimer <fweimer@redhat.com>

* debug/test-strcpy_chk.c: Mention __chk_fail ABI test.
Expand Down
22 changes: 11 additions & 11 deletions NEWS
Expand Up @@ -12,17 +12,17 @@ Version 2.17
1349, 3439, 3479, 3665, 5044, 5246, 5298, 5400, 6530, 6778, 6808, 9685,
9914, 10014, 10038, 10631, 10873, 11438, 11607, 11638, 11741, 12140,
13412, 13542, 13601, 13603, 13604, 13629, 13679, 13696, 13698, 13717,
13741, 13759, 13763, 13881, 13939, 13950, 13952, 13966, 14042, 14047,
14090, 14150, 14151, 14152, 14154, 14157, 14166, 14173, 14195, 14237,
14251, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336, 14337,
14347, 14349, 14368, 14376, 14417, 14447, 14459, 14476, 14477, 14501,
14505, 14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544,
14545, 14557, 14562, 14568, 14576, 14579, 14583, 14587, 14595, 14602,
14610, 14621, 14638, 14645, 14648, 14652, 14660, 14661, 14669, 14672,
14683, 14694, 14716, 14719, 14743, 14767, 14783, 14784, 14785, 14793,
14796, 14797, 14801, 14803, 14805, 14807, 14811, 14815, 14821, 14822,
14824, 14828, 14831, 14835, 14838, 14856, 14863, 14865, 14866, 14868,
14869, 14871, 14879, 14889.
13741, 13759, 13761, 13763, 13881, 13939, 13950, 13952, 13966, 14042,
14047, 14090, 14150, 14151, 14152, 14154, 14157, 14166, 14173, 14195,
14237, 14251, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336,
14337, 14347, 14349, 14368, 14376, 14417, 14447, 14459, 14476, 14477,
14501, 14505, 14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543,
14544, 14545, 14557, 14562, 14568, 14576, 14579, 14583, 14587, 14595,
14602, 14610, 14621, 14638, 14645, 14648, 14652, 14660, 14661, 14669,
14672, 14683, 14694, 14716, 14719, 14743, 14767, 14783, 14784, 14785,
14793, 14796, 14797, 14801, 14803, 14805, 14807, 14811, 14815, 14821,
14822, 14824, 14828, 14831, 14835, 14838, 14856, 14863, 14865, 14866,
14868, 14869, 14871, 14879, 14889.

* CVE-2011-4609 svc_run() produces high cpu usage when accept fails with
EMFILE has been fixed (Bugzilla #14889).
Expand Down
33 changes: 25 additions & 8 deletions nscd/grpcache.c
Expand Up @@ -177,7 +177,8 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
char *cp;
const size_t key_len = strlen (key);
const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1;
char *buf = alloca (buf_len);
size_t alloca_used = 0;
char *buf = alloca_account (buf_len, alloca_used);
ssize_t n;
size_t cnt;

Expand All @@ -189,7 +190,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
/* Determine the length of all members. */
while (grp->gr_mem[gr_mem_cnt])
++gr_mem_cnt;
gr_mem_len = (uint32_t *) alloca (gr_mem_cnt * sizeof (uint32_t));
gr_mem_len = alloca_account (gr_mem_cnt * sizeof (uint32_t), alloca_used);
for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt)
{
gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1;
Expand All @@ -204,7 +205,8 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
bool alloca_used = false;
bool dataset_temporary = false;
bool dataset_malloced = false;
dataset = NULL;

if (he == NULL)
Expand All @@ -215,10 +217,20 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
dataset = (struct dataset *) alloca (total + n);
if (! __libc_use_alloca (alloca_used + total + n))
{
dataset = malloc (total + n);
/* Perhaps we should log a message that we were unable
to allocate memory for a large request. */
if (dataset == NULL)
goto out;
dataset_malloced = true;
}
else
dataset = alloca_account (total + n, alloca_used);

/* We cannot add this record to the permanent database. */
alloca_used = true;
dataset_temporary = true;
}

dataset->head.allocsize = total + n;
Expand Down Expand Up @@ -272,6 +284,11 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
allocated on the stack and need not be freed. */
dh->timeout = dataset->head.timeout;
++dh->nreloads;

/* If the new record was allocated via malloc, then we must free
it here. */
if (dataset_malloced)
free (dataset);
}
else
{
Expand All @@ -287,7 +304,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
key_copy = (char *) newp + (key_copy - (char *) dataset);

dataset = memcpy (newp, dataset, total + n);
alloca_used = false;
dataset_temporary = false;
}

/* Mark the old record as obsolete. */
Expand All @@ -302,7 +319,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
assert (fd != -1);

#ifdef HAVE_SENDFILE
if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
if (__builtin_expect (db->mmap_used, 1) && ! dataset_temporary)
{
assert (db->wr_fd != -1);
assert ((char *) &dataset->resp > (char *) db->data);
Expand All @@ -329,7 +346,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,

/* Add the record to the database. But only if it has not been
stored on the stack. */
if (! alloca_used)
if (! dataset_temporary)
{
/* If necessary, we also propagate the data to disk. */
if (db->persistent)
Expand Down

0 comments on commit 2af1b32

Please sign in to comment.