From 27c377dd04f40e4d0a7e11daad059939e94d9367 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 4 Mar 2008 01:54:09 +0000 Subject: [BZ #5818] * nscd/connections.c (dbs): Add initializers for .suggested_module. (verify_persistent_db): Remove one unnecessary test and add a new one for bad configuration. (nscd_init): Improve error reported when persistent database cannot be reused. * nscd/nscd.h (DEFAULT_SUGGESTED_MODULE): Define. * nscd/nscd_conf.c (nscd_parse_file): Provide default values for .suggested_module and .max_db_size and case config file says the values are zero. * nscd/nscd_helper.c (get_mapping): Fail if hash table module is zero. --- nscd/connections.c | 46 +++++++++++++++++++++++++--------------------- nscd/nscd.h | 5 ++++- nscd/nscd_conf.c | 7 ++++--- nscd/nscd_helper.c | 6 ++++-- 4 files changed, 37 insertions(+), 27 deletions(-) (limited to 'nscd') diff --git a/nscd/connections.c b/nscd/connections.c index 8140e96..5da5e5f 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -1,6 +1,5 @@ /* Inner loops of cache daemon. - Copyright (C) 1998-2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1998-2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -112,7 +111,8 @@ struct database_dyn dbs[lastdb] = .propagate = 1, .shared = 0, .max_db_size = DEFAULT_MAX_DB_SIZE, - .reset_res = 0, + .suggested_module = DEFAULT_SUGGESTED_MODULE, + .reset_res = 0, .filename = "/etc/passwd", .db_filename = _PATH_NSCD_PASSWD_DB, .disabled_iov = &pwd_iov_disabled, @@ -131,6 +131,7 @@ struct database_dyn dbs[lastdb] = .propagate = 1, .shared = 0, .max_db_size = DEFAULT_MAX_DB_SIZE, + .suggested_module = DEFAULT_SUGGESTED_MODULE, .reset_res = 0, .filename = "/etc/group", .db_filename = _PATH_NSCD_GROUP_DB, @@ -150,6 +151,7 @@ struct database_dyn dbs[lastdb] = .propagate = 0, /* Not used. */ .shared = 0, .max_db_size = DEFAULT_MAX_DB_SIZE, + .suggested_module = DEFAULT_SUGGESTED_MODULE, .reset_res = 1, .filename = "/etc/hosts", .db_filename = _PATH_NSCD_HOSTS_DB, @@ -169,6 +171,7 @@ struct database_dyn dbs[lastdb] = .propagate = 0, /* Not used. */ .shared = 0, .max_db_size = DEFAULT_MAX_DB_SIZE, + .suggested_module = DEFAULT_SUGGESTED_MODULE, .reset_res = 0, .filename = "/etc/services", .db_filename = _PATH_NSCD_SERVICES_DB, @@ -346,7 +349,7 @@ verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr) struct database_pers_head head_copy = *head; /* Check that the header that was read matches the head in the database. */ - if (readhead != NULL && memcmp (head, readhead, sizeof (*head)) != 0) + if (memcmp (head, readhead, sizeof (*head)) != 0) return 0; /* First some easy tests: make sure the database header is sane. */ @@ -356,6 +359,7 @@ verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr) This should cover daylight saving time changes. */ || head->timestamp > now + 60 * 60 + 60 || (head->gc_cycle & 1) + || head->module == 0 || (size_t) head->module > INT32_MAX / sizeof (ref_t) || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t) || head->first_free < 0 @@ -506,6 +510,7 @@ nscd_init (void) int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS); if (fd != -1) { + char *msg = NULL; struct stat64 st; void *mem; size_t total; @@ -514,23 +519,26 @@ nscd_init (void) sizeof (head))); if (n != sizeof (head) || fstat64 (fd, &st) != 0) { + fail_db_errno: + /* The code is single-threaded at this point so + using strerror is just fine. */ + msg = strerror (errno); fail_db: dbg_log (_("invalid persistent database file \"%s\": %s"), - dbs[cnt].db_filename, strerror (errno)); + dbs[cnt].db_filename, msg); unlink (dbs[cnt].db_filename); } else if (head.module == 0 && head.data_size == 0) { - /* The file has been created, but the head has not been - initialized yet. Remove the old file. */ - unlink (dbs[cnt].db_filename); + /* The file has been created, but the head has not + been initialized yet. */ + msg = _("uninitialized header"); + goto fail_db; } else if (head.header_size != (int) sizeof (head)) { - dbg_log (_("invalid persistent database file \"%s\": %s"), - dbs[cnt].db_filename, - _("header size does not match")); - unlink (dbs[cnt].db_filename); + msg = _("header size does not match"); + goto fail_db; } else if ((total = (sizeof (head) + roundup (head.module * sizeof (ref_t), @@ -539,10 +547,8 @@ nscd_init (void) > st.st_size || total < sizeof (head)) { - dbg_log (_("invalid persistent database file \"%s\": %s"), - dbs[cnt].db_filename, - _("file size does not match")); - unlink (dbs[cnt].db_filename); + msg = _("file size does not match"); + goto fail_db; } /* Note we map with the maximum size allowed for the database. This is likely much larger than the @@ -554,14 +560,12 @@ nscd_init (void) PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) - goto fail_db; + goto fail_db_errno; else if (!verify_persistent_db (mem, &head, cnt)) { munmap (mem, total); - dbg_log (_("invalid persistent database file \"%s\": %s"), - dbs[cnt].db_filename, - _("verification failed")); - unlink (dbs[cnt].db_filename); + msg = _("verification failed"); + goto fail_db; } else { diff --git a/nscd/nscd.h b/nscd/nscd.h index cd6fe15..ec2d945 100644 --- a/nscd/nscd.h +++ b/nscd/nscd.h @@ -1,4 +1,4 @@ -/* Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 +/* Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1998. @@ -120,6 +120,9 @@ struct database_dyn /* Number of bytes of data we initially reserve for each hash table bucket. */ #define DEFAULT_DATASIZE_PER_BUCKET 1024 +/* Default module of hash table. */ +#define DEFAULT_SUGGESTED_MODULE 211 + /* Number of seconds between two cache pruning runs if we do not have better information when it is really needed. */ diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c index 0d5a5f2..9d0ef0e 100644 --- a/nscd/nscd_conf.c +++ b/nscd/nscd_conf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1998, 2000, 2003-2006, 2007 Free Software Foundation, Inc. +/* Copyright (c) 1998, 2000, 2003-2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1998. @@ -140,7 +140,8 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) { int idx = find_db (arg1); if (idx >= 0) - dbs[idx].suggested_module = atol (arg2); + dbs[idx].suggested_module + = atol (arg2) ?: DEFAULT_SUGGESTED_MODULE; } else if (strcmp (entry, "enable-cache") == 0) { @@ -168,7 +169,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) { int idx = find_db (arg1); if (idx >= 0) - dbs[idx].max_db_size = atol (arg2); + dbs[idx].max_db_size = atol (arg2) ?: DEFAULT_MAX_DB_SIZE; } else if (strcmp (entry, "logfile") == 0) set_logfile (arg1); diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c index 8665352..9828a46 100644 --- a/nscd/nscd_helper.c +++ b/nscd/nscd_helper.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1998-2002,2003,2004,2005,2006,2007 - Free Software Foundation, Inc. +/* Copyright (C) 1998-2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -339,6 +338,9 @@ get_mapping (request_type type, const char *key, if (__builtin_expect (head->version != DB_VERSION, 0) || __builtin_expect (head->header_size != sizeof (*head), 0) + /* Catch some misconfiguration. The server should catch + them now but some older versions did not. */ + || __builtin_expect (head->module == 0, 0) /* This really should not happen but who knows, maybe the update thread got stuck. */ || __builtin_expect (! head->nscd_certainly_running -- cgit v1.1