summaryrefslogtreecommitdiff
path: root/nscd
diff options
context:
space:
mode:
Diffstat (limited to 'nscd')
-rw-r--r--nscd/grpcache.c5
-rw-r--r--nscd/hstcache.c42
-rw-r--r--nscd/initgrcache.c6
-rw-r--r--nscd/mem.c9
-rw-r--r--nscd/nscd_getserv_r.c2
-rw-r--r--nscd/pwdcache.c20
-rw-r--r--nscd/servicescache.c2
7 files changed, 59 insertions, 27 deletions
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index e391dc3984..c49c0e1906 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -190,7 +190,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
gr_mem_len_total += gr_mem_len[gr_mem_cnt];
}
- written = total = (sizeof (struct dataset)
+ written = total = (offsetof (struct dataset, strdata)
+ gr_mem_cnt * sizeof (uint32_t)
+ gr_name_len + gr_passwd_len + gr_mem_len_total);
@@ -252,6 +252,9 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
char *key_copy = cp + key_offset;
assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
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, &notfound, total,
- MSG_NOSIGNAL));
+ if (fd != -1 &&
+ TEMP_FAILURE_RETRY (send (fd, &notfound, 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/initgrcache.c b/nscd/initgrcache.c
index 3355df5164..c5693c6be5 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -246,7 +246,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
else
{
- written = total = sizeof (struct dataset) + start * sizeof (int32_t);
+ written = total = (offsetof (struct dataset, strdata)
+ + start * sizeof (int32_t));
/* If we refill the cache, first assume the reconrd did not
change. Allocate memory on the cache since it is likely
@@ -307,6 +308,9 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
/* Finally the user name. */
memcpy (cp, key, req->key_len);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
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)
{
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
index 3cd5a24298..b1ad7e2e43 100644
--- a/nscd/nscd_getserv_r.c
+++ b/nscd/nscd_getserv_r.c
@@ -53,7 +53,7 @@ __nscd_getservbyport_r (int port, const char *proto,
portstr[sizeof (portstr) - 1] = '\0';
char *cp = _itoa_word (port, portstr + sizeof (portstr) - 1, 10, 0);
- return nscd_getserv_r (portstr, portstr + sizeof (portstr) - cp, proto,
+ return nscd_getserv_r (cp, portstr + sizeof (portstr) - cp, proto,
GETSERVBYPORT, result_buf, buf, buflen, result);
}
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 4a0cabd240..782b101371 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -185,7 +185,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
n = snprintf (buf, buf_len, "%d%c%n%s", pwd->pw_uid, '\0',
&key_offset, (char *) key) + 1;
- written = total = (sizeof (struct dataset) + pw_name_len + pw_passwd_len
+ written = total = (offsetof (struct dataset, strdata)
+ + pw_name_len + pw_passwd_len
+ pw_gecos_len + pw_dir_len + pw_shell_len);
/* If we refill the cache, first assume the reconrd did not
@@ -247,16 +248,28 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
char *key_copy = cp + key_offset;
assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
{
assert (fd == -1);
- if (total + n == dh->allocsize
- && total - offsetof (struct dataset, resp) == dh->recsize
+#if 0
+ if (dataset->head.datasize == dh->allocsize
+ && dataset->head.recsize == dh->recsize
&& memcmp (&dataset->resp, dh->data,
dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#else
+ if (dataset->head.allocsize != dh->allocsize)
+ goto nnn;
+ if (dataset->head.recsize != dh->recsize)
+ goto nnn;
+ if(memcmp (&dataset->resp, dh->data,
+ dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#endif
{
/* The data has not changed. We will just bump the
timeout value. Note that the new record has been
@@ -266,6 +279,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
}
else
{
+ nnn:;
/* We have to create a new record. Just allocate
appropriate memory and copy it. */
struct dataset *newp
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index c952fa12c8..44f12a3c69 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -173,7 +173,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
total += s_aliases_len[cnt];
}
- total += (sizeof (struct dataset)
+ total += (offsetof (struct dataset, strdata)
+ s_name_len
+ s_proto_len
+ s_aliases_cnt * sizeof (uint32_t));