]>
Commit | Line | Data |
---|---|---|
bb330e25 AF |
1 | Index: glibc-2.12-2-gc4ccff1/nscd/grpcache.c |
2 | =================================================================== | |
3 | --- glibc-2.12-2-gc4ccff1.orig/nscd/grpcache.c | |
4 | +++ glibc-2.12-2-gc4ccff1/nscd/grpcache.c | |
5 | @@ -178,7 +178,8 @@ cache_addgr (struct database_dyn *db, in | |
6 | char *cp; | |
7 | const size_t key_len = strlen (key); | |
8 | const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1; | |
9 | - char *buf = alloca (buf_len); | |
10 | + size_t alloca_used = 0; | |
11 | + char *buf = alloca_account (buf_len, alloca_used); | |
12 | ssize_t n; | |
13 | size_t cnt; | |
14 | ||
15 | @@ -190,7 +191,8 @@ cache_addgr (struct database_dyn *db, in | |
16 | /* Determine the length of all members. */ | |
17 | while (grp->gr_mem[gr_mem_cnt]) | |
18 | ++gr_mem_cnt; | |
19 | - gr_mem_len = (uint32_t *) alloca (gr_mem_cnt * sizeof (uint32_t)); | |
20 | + gr_mem_len = (uint32_t *) alloca_account (gr_mem_cnt * sizeof (uint32_t), | |
21 | + alloca_used); | |
22 | for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt) | |
23 | { | |
24 | gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1; | |
25 | @@ -205,10 +207,10 @@ cache_addgr (struct database_dyn *db, in | |
26 | change. Allocate memory on the cache since it is likely | |
27 | discarded anyway. If it turns out to be necessary to have a | |
28 | new record we can still allocate real memory. */ | |
29 | - bool alloca_used = false; | |
30 | + bool dataset_in_stack_or_freed = false; | |
31 | dataset = NULL; | |
32 | ||
33 | - if (he == NULL) | |
34 | + if (he == NULL || ! __libc_use_alloca (alloca_used + total + n)) | |
35 | dataset = (struct dataset *) mempool_alloc (db, total + n, 1); | |
36 | ||
37 | if (dataset == NULL) | |
38 | @@ -216,10 +218,10 @@ cache_addgr (struct database_dyn *db, in | |
39 | /* We cannot permanently add the result in the moment. But | |
40 | we can provide the result as is. Store the data in some | |
41 | temporary memory. */ | |
42 | - dataset = (struct dataset *) alloca (total + n); | |
43 | + dataset = (struct dataset *) alloca_account (total + n, alloca_used); | |
44 | ||
45 | /* We cannot add this record to the permanent database. */ | |
46 | - alloca_used = true; | |
47 | + dataset_in_stack_or_freed = true; | |
48 | } | |
49 | ||
50 | dataset->head.allocsize = total + n; | |
51 | @@ -273,6 +275,14 @@ cache_addgr (struct database_dyn *db, in | |
52 | allocated on the stack and need not be freed. */ | |
53 | dh->timeout = dataset->head.timeout; | |
54 | ++dh->nreloads; | |
55 | + | |
56 | + /* If the new record was not allocated on the stack, then it must | |
57 | + be freed. Note that it can no longer be used. */ | |
58 | + if (! dataset_in_stack_or_freed) | |
59 | + { | |
60 | + free (dataset); | |
61 | + dataset_in_stack_or_freed = true; | |
62 | + } | |
63 | } | |
64 | else | |
65 | { | |
66 | @@ -288,7 +298,7 @@ cache_addgr (struct database_dyn *db, in | |
67 | key_copy = (char *) newp + (key_copy - (char *) dataset); | |
68 | ||
69 | dataset = memcpy (newp, dataset, total + n); | |
70 | - alloca_used = false; | |
71 | + dataset_in_stack_or_freed = false; | |
72 | } | |
73 | ||
74 | /* Mark the old record as obsolete. */ | |
75 | @@ -303,7 +313,7 @@ cache_addgr (struct database_dyn *db, in | |
76 | assert (fd != -1); | |
77 | ||
78 | #ifdef HAVE_SENDFILE | |
79 | - if (__builtin_expect (db->mmap_used, 1) && !alloca_used) | |
80 | + if (__builtin_expect (db->mmap_used, 1) && !dataset_in_stack_or_freed) | |
81 | { | |
82 | assert (db->wr_fd != -1); | |
83 | assert ((char *) &dataset->resp > (char *) db->data); | |
84 | @@ -330,7 +340,7 @@ cache_addgr (struct database_dyn *db, in | |
85 | ||
86 | /* Add the record to the database. But only if it has not been | |
87 | stored on the stack. */ | |
88 | - if (! alloca_used) | |
89 | + if (! dataset_in_stack_or_freed) | |
90 | { | |
91 | /* If necessary, we also propagate the data to disk. */ | |
92 | if (db->persistent) |