179 lines
5.9 KiB
Diff
179 lines
5.9 KiB
Diff
|
From 5a7b70c87c5ba03a122db0372e87ecb550ee4b38 Mon Sep 17 00:00:00 2001
|
||
|
From: Andreas Schwab <schwab@suse.de>
|
||
|
Date: Tue, 4 Dec 2012 16:14:13 +0100
|
||
|
Subject: [PATCH] Properly check for short writes when sending the response in
|
||
|
nscd
|
||
|
|
||
|
* nscd/grpcache.c (cache_addgr): Properly check for short write.
|
||
|
* nscd/initgrcache.c (addinitgroupsX): Likewise.
|
||
|
* nscd/pwdcache.c (cache_addpw): Likewise.
|
||
|
* nscd/servicescache.c (cache_addserv): Likewise. Don't write
|
||
|
more than recsize.
|
||
|
---
|
||
|
nscd/grpcache.c | 6 +++++-
|
||
|
nscd/initgrcache.c | 7 ++++++-
|
||
|
nscd/pwdcache.c | 8 ++++++--
|
||
|
nscd/servicescache.c | 12 ++++++++----
|
||
|
4 files changed, 25 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
|
||
|
index f0dad4d..696162f 100644
|
||
|
--- a/nscd/grpcache.c
|
||
|
+++ b/nscd/grpcache.c
|
||
|
@@ -75,6 +75,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||
|
const void *key, struct group *grp, uid_t owner,
|
||
|
struct hashentry *const he, struct datahead *dh, int errval)
|
||
|
{
|
||
|
+ bool all_written = true;
|
||
|
ssize_t total;
|
||
|
ssize_t written;
|
||
|
time_t t = time (NULL);
|
||
|
@@ -342,6 +343,9 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||
|
# endif
|
||
|
#endif
|
||
|
written = writeall (fd, &dataset->resp, dataset->head.recsize);
|
||
|
+
|
||
|
+ if (written != dataset->head.recsize)
|
||
|
+ all_written = false;
|
||
|
}
|
||
|
|
||
|
/* Add the record to the database. But only if it has not been
|
||
|
@@ -401,7 +405,7 @@ cache_addgr (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 255b121..13ee86e 100644
|
||
|
--- a/nscd/initgrcache.c
|
||
|
+++ b/nscd/initgrcache.c
|
||
|
@@ -171,10 +171,12 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||
|
nip = nip->next;
|
||
|
}
|
||
|
|
||
|
+ bool all_written;
|
||
|
ssize_t total;
|
||
|
ssize_t written;
|
||
|
time_t timeout;
|
||
|
out:
|
||
|
+ all_written = true;
|
||
|
timeout = MAX_TIMEOUT_VALUE;
|
||
|
if (!any_success)
|
||
|
{
|
||
|
@@ -379,6 +381,9 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||
|
# endif
|
||
|
#endif
|
||
|
written = writeall (fd, &dataset->resp, dataset->head.recsize);
|
||
|
+
|
||
|
+ if (written != dataset->head.recsize)
|
||
|
+ all_written = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -405,7 +410,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||
|
|
||
|
free (groups);
|
||
|
|
||
|
- 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/pwdcache.c b/nscd/pwdcache.c
|
||
|
index a8ea407..d6b91ef 100644
|
||
|
--- a/nscd/pwdcache.c
|
||
|
+++ b/nscd/pwdcache.c
|
||
|
@@ -81,6 +81,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||
|
const void *key, struct passwd *pwd, uid_t owner,
|
||
|
struct hashentry *const he, struct datahead *dh, int errval)
|
||
|
{
|
||
|
+ bool all_written = true;
|
||
|
ssize_t total;
|
||
|
ssize_t written;
|
||
|
time_t t = time (NULL);
|
||
|
@@ -306,7 +307,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||
|
+ db->head->data_size));
|
||
|
written = sendfileall (fd, db->wr_fd,
|
||
|
(char *) &dataset->resp
|
||
|
- - (char *) db->head, dataset->head.recsize );
|
||
|
+ - (char *) db->head, dataset->head.recsize);
|
||
|
# ifndef __ASSUME_SENDFILE
|
||
|
if (written == -1 && errno == ENOSYS)
|
||
|
goto use_write;
|
||
|
@@ -318,6 +319,9 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||
|
# endif
|
||
|
#endif
|
||
|
written = writeall (fd, &dataset->resp, dataset->head.recsize);
|
||
|
+
|
||
|
+ if (written != dataset->head.recsize)
|
||
|
+ all_written = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -377,7 +381,7 @@ cache_addpw (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/servicescache.c b/nscd/servicescache.c
|
||
|
index 0e7520d..917daa4 100644
|
||
|
--- a/nscd/servicescache.c
|
||
|
+++ b/nscd/servicescache.c
|
||
|
@@ -65,6 +65,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
|
||
|
const void *key, struct servent *serv, uid_t owner,
|
||
|
struct hashentry *const he, struct datahead *dh, int errval)
|
||
|
{
|
||
|
+ bool all_written = true;
|
||
|
ssize_t total;
|
||
|
ssize_t written;
|
||
|
time_t t = time (NULL);
|
||
|
@@ -290,14 +291,14 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
|
||
|
{
|
||
|
assert (db->wr_fd != -1);
|
||
|
assert ((char *) &dataset->resp > (char *) db->data);
|
||
|
- assert ((char *) &dataset->resp - (char *) db->head
|
||
|
+ assert ((char *) dataset - (char *) db->head
|
||
|
+ total
|
||
|
<= (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);
|
||
|
+ - (char *) db->head, dataset->head.recsize);
|
||
|
# ifndef __ASSUME_SENDFILE
|
||
|
if (written == -1 && errno == ENOSYS)
|
||
|
goto use_write;
|
||
|
@@ -308,7 +309,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
|
||
|
use_write:
|
||
|
# endif
|
||
|
#endif
|
||
|
- written = writeall (fd, &dataset->resp, total);
|
||
|
+ written = writeall (fd, &dataset->resp, dataset->head.recsize);
|
||
|
+
|
||
|
+ if (written != dataset->head.recsize)
|
||
|
+ all_written = false;
|
||
|
}
|
||
|
|
||
|
/* Add the record to the database. But only if it has not been
|
||
|
@@ -332,7 +336,7 @@ cache_addserv (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__,
|
||
|
--
|
||
|
1.8.0.1
|
||
|
|