Skip to content

Commit

Permalink
* posix/bits/unistd.h (confstr, getgroups, ttyname_r, gethostname,
Browse files Browse the repository at this point in the history
	getdomainname): Add __NTH.
	* stdlib/bits/stdlib.h (ptsname_r, wctomb, mbstowcs, wcstombs):
	Likewise.
	(realpath): Likewise.  Use __const instead of const.  Add __restrict
	keywords.
	* socket/bits/socket2.h (recvfrom): Add __restrict keyword to __buf.
	* wcsmbs/bits/wchar2.h (wmemcpy, wmemmove, wmempcpy, wmemset,
	wcscpy, wcpcpy, wcsncpy, wcpncpy, wcscat, wcsncat, vswprintf, wcrtomb,
	mbsrtowcs, wcsrtombs, mbsnrtowcs, wcsnrtombs): Add __NTH.
	* string/bits/string3.h (__memset_ichk): Likewise.
	(__memcpy_ichk, __memmove_ichk, __mempcpy_ichk, __strcpy_ichk,
	__stpcpy_ichk, __strncpy_ichk, stpncpy, __strcat_ichk,
	__strncat_ichk): Likewise.  Use __const instead of const.
	(__stpncpy_chk): Use __const instead of const.
	(__stpncpy_alias): Use __REDIRECT_NTH instead of __REDIRECT.

2005-08-08  Ulrich Drepper  <drepper@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>

	* nscd/mem.c (BLOCK_ALIGN_LOG, BLOCK_ALIGN, BLOCK_ALIGN_M1): Move
	definitions to...
	* nscd/nscd.h (BLOCK_ALIGN_LOG, BLOCK_ALIGN, BLOCK_ALIGN_M1): ...here.
	* nscd/connections.c (usekey): New enum.
	(check_use, verify_persistent_db): New functions.
	(nscd_init): If persistent database is corrupted, unlink it and
	recreate rather than falling back to non-persistent database.
	Call verify_persistent_db.  Avoid overflows in total computation.

2005-08-08  Ulrich Drepper  <drepper@redhat.com>

	* iconvdata/utf-16.c (PREPARE_LOOP): Minor cleanups to make code
	better readable.  Avoid passing var to loop function, it's not
	necessary at all.
  • Loading branch information
Ulrich Drepper committed Aug 8, 2005
1 parent 6c49b46 commit dc4bb1c
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 87 deletions.
37 changes: 37 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
2005-08-08 Jakub Jelinek <jakub@redhat.com>

* posix/bits/unistd.h (confstr, getgroups, ttyname_r, gethostname,
getdomainname): Add __NTH.
* stdlib/bits/stdlib.h (ptsname_r, wctomb, mbstowcs, wcstombs):
Likewise.
(realpath): Likewise. Use __const instead of const. Add __restrict
keywords.
* socket/bits/socket2.h (recvfrom): Add __restrict keyword to __buf.
* wcsmbs/bits/wchar2.h (wmemcpy, wmemmove, wmempcpy, wmemset,
wcscpy, wcpcpy, wcsncpy, wcpncpy, wcscat, wcsncat, vswprintf, wcrtomb,
mbsrtowcs, wcsrtombs, mbsnrtowcs, wcsnrtombs): Add __NTH.
* string/bits/string3.h (__memset_ichk): Likewise.
(__memcpy_ichk, __memmove_ichk, __mempcpy_ichk, __strcpy_ichk,
__stpcpy_ichk, __strncpy_ichk, stpncpy, __strcat_ichk,
__strncat_ichk): Likewise. Use __const instead of const.
(__stpncpy_chk): Use __const instead of const.
(__stpncpy_alias): Use __REDIRECT_NTH instead of __REDIRECT.

2005-08-08 Ulrich Drepper <drepper@redhat.com>
Jakub Jelinek <jakub@redhat.com>

* nscd/mem.c (BLOCK_ALIGN_LOG, BLOCK_ALIGN, BLOCK_ALIGN_M1): Move
definitions to...
* nscd/nscd.h (BLOCK_ALIGN_LOG, BLOCK_ALIGN, BLOCK_ALIGN_M1): ...here.
* nscd/connections.c (usekey): New enum.
(check_use, verify_persistent_db): New functions.
(nscd_init): If persistent database is corrupted, unlink it and
recreate rather than falling back to non-persistent database.
Call verify_persistent_db. Avoid overflows in total computation.

2005-08-08 Ulrich Drepper <drepper@redhat.com>

* iconvdata/utf-16.c (PREPARE_LOOP): Minor cleanups to make code
better readable. Avoid passing var to loop function, it's not
necessary at all.

2005-08-07 Ulrich Drepper <drepper@redhat.com>

* elf/elf.h (DT_ALPHA_PLTRO): Use symbolic name in DT_ALPHA_PLTRO
Expand Down
36 changes: 16 additions & 20 deletions iconvdata/utf-16.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Conversion module for UTF-16.
Copyright (C) 1999, 2000-2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1999, 2000-2002, 2003, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
Expand Down Expand Up @@ -44,10 +44,9 @@
#define PREPARE_LOOP \
enum direction dir = ((struct utf16_data *) step->__data)->dir; \
enum variant var = ((struct utf16_data *) step->__data)->var; \
int swap; \
if (FROM_DIRECTION && var == UTF_16) \
if (__builtin_expect (data->__invocation_counter == 0, 0) && var == UTF_16) \
{ \
if (data->__invocation_counter == 0) \
if (FROM_DIRECTION) \
{ \
/* We have to find out which byte order the file is encoded in. */ \
if (inptr + 2 > inend) \
Expand All @@ -63,19 +62,18 @@
*inptrp = inptr += 2; \
} \
} \
} \
else if (!FROM_DIRECTION && var == UTF_16 && !data->__internal_use \
&& data->__invocation_counter == 0) \
{ \
/* Emit the Byte Order Mark. */ \
if (__builtin_expect (outbuf + 2 > outend, 0)) \
return __GCONV_FULL_OUTPUT; \
else if (!FROM_DIRECTION && !data->__internal_use) \
{ \
/* Emit the Byte Order Mark. */ \
if (__builtin_expect (outbuf + 2 > outend, 0)) \
return __GCONV_FULL_OUTPUT; \
\
put16u (outbuf, BOM); \
outbuf += 2; \
put16u (outbuf, BOM); \
outbuf += 2; \
} \
} \
swap = ((struct utf16_data *) step->__data)->swap;
#define EXTRA_LOOP_ARGS , var, swap
int swap = ((struct utf16_data *) step->__data)->swap;
#define EXTRA_LOOP_ARGS , swap


/* Direction of the transformation. */
Expand Down Expand Up @@ -267,7 +265,7 @@ gconv_end (struct __gconv_step *data)
}
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS \
, enum variant var, int swap
, int swap
#include <iconv/loop.c>


Expand Down Expand Up @@ -328,8 +326,6 @@ gconv_end (struct __gconv_step *data)
} \
else \
{ \
uint16_t u2; \
\
/* It's a surrogate character. At least the first word says \
it is. */ \
if (__builtin_expect (inptr + 4 > inend, 0)) \
Expand All @@ -341,7 +337,7 @@ gconv_end (struct __gconv_step *data)
} \
\
inptr += 2; \
u2 = get16 (inptr); \
uint16_t u2 = get16 (inptr); \
if (__builtin_expect (u2 < 0xdc00, 0) \
|| __builtin_expect (u2 > 0xdfff, 0)) \
{ \
Expand All @@ -358,7 +354,7 @@ gconv_end (struct __gconv_step *data)
}
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS \
, enum variant var, int swap
, int swap
#include <iconv/loop.c>


Expand Down
221 changes: 217 additions & 4 deletions nscd/connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,210 @@ writeall (int fd, const void *buf, size_t len)
}


enum usekey
{
use_not = 0,
/* The following three are not really used, they are symbolic constants. */
use_first = 16,
use_begin = 32,
use_end = 64,

use_he = 1,
use_he_begin = use_he | use_begin,
use_he_end = use_he | use_end,
#if SEPARATE_KEY
use_key = 2,
use_key_begin = use_key | use_begin,
use_key_end = use_key | use_end,
use_key_first = use_key_begin | use_first,
#endif
use_data = 3,
use_data_begin = use_data | use_begin,
use_data_end = use_data | use_end,
use_data_first = use_data_begin | use_first
};


static int
check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
enum usekey use, ref_t start, size_t len)
{
assert (len >= 2);

if (start > first_free || start + len > first_free
|| (start & BLOCK_ALIGN_M1))
return 0;

if (usemap[start] == use_not)
{
/* Add the start marker. */
usemap[start] = use | use_begin;
use &= ~use_first;

while (--len > 0)
if (usemap[++start] != use_not)
return 0;
else
usemap[start] = use;

/* Add the end marker. */
usemap[start] = use | use_end;
}
else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
{
/* Hash entries can't be shared. */
if (use == use_he)
return 0;

usemap[start] |= (use & use_first);
use &= ~use_first;

while (--len > 1)
if (usemap[++start] != use)
return 0;

if (usemap[++start] != (use | use_end))
return 0;
}
else
/* Points to a wrong object or somewhere in the middle. */
return 0;

return 1;
}


/* Verify data in persistent database. */
static int
verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
{
assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb);

time_t now = time (NULL);

struct database_pers_head *head = mem;
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)
return 0;

/* First some easy tests: make sure the database header is sane. */
if (head->version != DB_VERSION
|| head->header_size != sizeof (*head)
/* We allow a timestamp to be one hour ahead of the current time.
This should cover daylight saving time changes. */
|| head->timestamp > now + 60 * 60 + 60
|| (head->gc_cycle & 1)
|| (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
|| head->first_free > head->data_size
|| (head->first_free & BLOCK_ALIGN_M1) != 0
|| head->maxnentries < 0
|| head->maxnsearched < 0)
return 0;

uint8_t *usemap = calloc (head->first_free, 1);
if (usemap == NULL)
return 0;

const char *data = (char *) &head->array[roundup (head->module,
ALIGN / sizeof (ref_t))];

nscd_ssize_t he_cnt = 0;
for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
{
ref_t work = head->array[cnt];

while (work != ENDREF)
{
if (! check_use (data, head->first_free, usemap, use_he, work,
sizeof (struct hashentry)))
goto fail;

/* Now we know we can dereference the record. */
struct hashentry *here = (struct hashentry *) (data + work);

++he_cnt;

/* Make sure the record is for this type of service. */
if (here->type >= LASTREQ
|| serv2db[here->type] != &dbs[dbnr])
goto fail;

/* Validate boolean field value. */
if (here->first != false && here->first != true)
goto fail;

if (here->len < 0)
goto fail;

/* Now the data. */
if (here->packet < 0
|| here->packet > head->first_free
|| here->packet + sizeof (struct datahead) > head->first_free)
goto fail;

struct datahead *dh = (struct datahead *) (data + here->packet);

if (! check_use (data, head->first_free, usemap,
use_data | (here->first ? use_first : 0),
here->packet, dh->allocsize))
goto fail;

if (dh->allocsize < sizeof (struct datahead)
|| dh->recsize > dh->allocsize
|| (dh->notfound != false && dh->notfound != true)
|| (dh->usable != false && dh->usable != true))
goto fail;

if (here->key < here->packet + sizeof (struct datahead)
|| here->key > here->packet + dh->allocsize
|| here->key + here->len > here->packet + dh->allocsize)
{
#if SEPARATE_KEY
/* If keys can appear outside of data, this should be done
instead. But gc doesn't mark the data in that case. */
if (! check_use (data, head->first_free, usemap,
use_key | (here->first ? use_first : 0),
here->key, here->len))
#endif
goto fail;
}

work = here->next;
}
}

if (he_cnt != head->nentries)
goto fail;

/* See if all data and keys had at least one reference from
he->first == true hashentry. */
for (ref_t idx = 0; idx < head->first_free; ++idx)
{
#if SEPARATE_KEY
if (usemap[idx] == use_key_begin)
goto fail;
#endif
if (usemap[idx] == use_data_begin)
goto fail;
}

/* Finally, make sure the database hasn't changed since the first test. */
if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
goto fail;

free (usemap);
return 1;

fail:
free (usemap);
return 0;
}


/* Initialize database information structures. */
void
nscd_init (void)
Expand Down Expand Up @@ -242,7 +446,7 @@ nscd_init (void)
fail_db:
dbg_log (_("invalid persistent database file \"%s\": %s"),
dbs[cnt].db_filename, strerror (errno));
dbs[cnt].persistent = 0;
unlink (dbs[cnt].db_filename);
}
else if (head.module == 0 && head.data_size == 0)
{
Expand All @@ -255,22 +459,31 @@ nscd_init (void)
dbg_log (_("invalid persistent database file \"%s\": %s"),
dbs[cnt].db_filename,
_("header size does not match"));
dbs[cnt].persistent = 0;
unlink (dbs[cnt].db_filename);
}
else if ((total = (sizeof (head)
+ roundup (head.module * sizeof (ref_t),
ALIGN)
+ head.data_size))
> st.st_size)
> st.st_size
|| total < sizeof (head))
{
dbg_log (_("invalid persistent database file \"%s\": %s"),
dbs[cnt].db_filename,
_("file size does not match"));
dbs[cnt].persistent = 0;
unlink (dbs[cnt].db_filename);
}
else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED)
goto fail_db;
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);
}
else
{
/* Success. We have the database. */
Expand Down
Loading

0 comments on commit dc4bb1c

Please sign in to comment.