diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | nscd/hstcache.c | 42 | ||||
-rw-r--r-- | nscd/mem.c | 9 |
3 files changed, 39 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog index 98ed0b7afb..92cda302de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-06-11 Ulrich Drepper <drepper@redhat.com> + + * nscd/mem.c (gc): Initialize obstack earlier so that if we jump + out we don't use uninitialized memory. + + * nscd/hstcache.c (cache_addhst): Send correct number of bytes to + the client. + 2008-06-10 Ulrich Drepper <drepper@redhat.com> * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Also log and diff --git a/nscd/hstcache.c b/nscd/hstcache.c index d4dd51f11a..4333917ba0 100644 --- a/nscd/hstcache.c +++ b/nscd/hstcache.c @@ -83,8 +83,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, struct hashentry *he, struct datahead *dh, int errval, int32_t ttl) { - ssize_t total; - ssize_t written; + bool all_written = true; time_t t = time (NULL); /* We allocate all data in one memory block: the iov vector, @@ -108,18 +107,17 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, if (reload_count != UINT_MAX) /* Do not reset the value if we never not reload the record. */ dh->nreloads = reload_count - 1; - - written = total = 0; } else { /* We have no data. This means we send the standard reply for this case. */ - written = total = sizeof (notfound); + ssize_t total = sizeof (notfound); - if (fd != -1) - written = TEMP_FAILURE_RETRY (send (fd, ¬found, total, - MSG_NOSIGNAL)); + if (fd != -1 && + TEMP_FAILURE_RETRY (send (fd, ¬found, total, + MSG_NOSIGNAL)) != total) + all_written = false; dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, IDX_result_data); @@ -181,6 +179,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, char *key_copy = NULL; char *cp; size_t cnt; + ssize_t total; /* Determine the number of aliases. */ h_aliases_cnt = 0; @@ -208,7 +207,6 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, + h_name_len + h_aliases_cnt * sizeof (uint32_t) + h_addr_list_cnt * hst->h_length); - written = total; /* If we refill the cache, first assume the reconrd did not change. Allocate memory on the cache since it is likely @@ -260,6 +258,9 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, dataset->resp.h_addr_list_cnt = h_addr_list_cnt; dataset->resp.error = NETDB_SUCCESS; + /* Make sure there is no gap. */ + assert ((char *) (&dataset->resp.error + 1) == dataset->strdata); + cp = dataset->strdata; cp = mempcpy (cp, hst->h_name, h_name_len); @@ -286,6 +287,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, we explicitly add the name here. */ key_copy = memcpy (cp, key, req->key_len); + assert ((char *) &dataset->resp + dataset->head.recsize == cp); + /* Now we can determine whether on refill we have to create a new record or not. */ if (he != NULL) @@ -351,20 +354,27 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, <= (sizeof (struct database_pers_head) + db->head->module * sizeof (ref_t) + db->head->data_size)); - written = sendfileall (fd, db->wr_fd, - (char *) &dataset->resp - - (char *) db->head, total); + ssize_t written = sendfileall (fd, db->wr_fd, + (char *) &dataset->resp + - (char *) db->head, + dataset->head.recsize); + if (written != dataset->head.recsize) + { # ifndef __ASSUME_SENDFILE - if (written == -1 && errno == ENOSYS) - goto use_write; + if (written == -1 && errno == ENOSYS) + goto use_write; # endif + all_written = false; + } } else # ifndef __ASSUME_SENDFILE use_write: # endif #endif - written = writeall (fd, &dataset->resp, total); + if (writeall (fd, &dataset->resp, dataset->head.recsize) + != dataset->head.recsize) + all_written = false; } /* Add the record to the database. But only if it has not been @@ -414,7 +424,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, } } - if (__builtin_expect (written != total, 0) && debug_level > 0) + if (__builtin_expect (!all_written, 0) && debug_level > 0) { char buf[256]; dbg_log (_("short write in %s: %s"), __FUNCTION__, diff --git a/nscd/mem.c b/nscd/mem.c index 96ff03f0df..e821729dab 100644 --- a/nscd/mem.c +++ b/nscd/mem.c @@ -235,6 +235,11 @@ gc (struct database_dyn *db) /* Sort the entries by their address. */ qsort (he, cnt, sizeof (struct hashentry *), sort_he); +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + struct obstack ob; + obstack_init (&ob); + /* Determine the highest used address. */ size_t high = nmark; while (high > 0 && mark[high - 1] == 0) @@ -307,10 +312,6 @@ gc (struct database_dyn *db) size_t size; struct moveinfo *next; } *moves = NULL; -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - struct obstack ob; - obstack_init (&ob); while (byte < high) { |