summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-03-22 07:23:48 +0000
committerUlrich Drepper <drepper@redhat.com>2002-03-22 07:23:48 +0000
commit41b69f94eec13a17720aa399d53dc3d54c4b915a (patch)
treea71cc9d85db536b5c16664aca76efb629eeec0e7
parent07bbb0657bc249f10b86ec28f4ba862d5df9057e (diff)
downloadglibc-41b69f94eec13a17720aa399d53dc3d54c4b915a.tar.gz
Update from mainline.
-rw-r--r--nscd/grpcache.c104
-rw-r--r--nscd/hstcache.c178
-rw-r--r--nscd/pwdcache.c102
3 files changed, 337 insertions, 47 deletions
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index 93a7a0d86d..ce84668900 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -1,5 +1,5 @@
/* Cache handling for group lookup.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -21,6 +21,7 @@
#include <errno.h>
#include <error.h>
#include <grp.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
@@ -28,6 +29,7 @@
#include <string.h>
#include <unistd.h>
#include <libintl.h>
+#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
@@ -204,14 +206,15 @@ addgrbyname (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 256;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct group resultbuf;
struct group *grp;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
- dbg_log (_("Haven't found \"%s\" in group cache!"), (char *)key);
+ if (__builtin_expect (debug_level > 0, 0))
+ dbg_log (_("Haven't found \"%s\" in group cache!"), (char *) key);
if (secure[grpdb])
{
@@ -222,15 +225,47 @@ addgrbyname (struct database *db, int fd, request_header *req,
while (__getgrnam_r (key, &resultbuf, buffer, buflen, &grp) != 0
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ grp = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[grpdb])
seteuid (oldeuid);
cache_addgr (db, fd, req, key, grp, uid);
+
+ if (use_malloc)
+ free (buffer);
}
@@ -242,14 +277,25 @@ addgrbygid (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 256;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct group resultbuf;
struct group *grp;
- gid_t gid = atol (key);
uid_t oldeuid = 0;
+ char *ep;
+ gid_t gid = strtoul ((char *)key, &ep, 10);
+ bool use_malloc = false;
+
+ if (*(char *) key == '\0' || *ep != '\0') /* invalid numeric gid */
+ {
+ if (debug_level > 0)
+ dbg_log (_("Invalid numeric gid \"%s\"!"), (char *) key);
- if (debug_level > 0)
+ errno = EINVAL;
+ return;
+ }
+
+ if (__builtin_expect (debug_level > 0, 0))
dbg_log (_("Haven't found \"%d\" in group cache!"), gid);
if (secure[grpdb])
@@ -261,13 +307,45 @@ addgrbygid (struct database *db, int fd, request_header *req,
while (__getgrgid_r (gid, &resultbuf, buffer, buflen, &grp) != 0
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ grp = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[grpdb])
seteuid (oldeuid);
cache_addgr (db, fd, req, key, grp, uid);
+
+ if (use_malloc)
+ free (buffer);
}
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index c7cdc4deb4..8866293b6c 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -1,5 +1,5 @@
/* Cache handling for host lookup.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -22,6 +22,7 @@
#include <errno.h>
#include <error.h>
#include <netdb.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -31,6 +32,7 @@
#include <libintl.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
+#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
@@ -289,14 +291,15 @@ addhstbyname (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 512;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct hostent resultbuf;
struct hostent *hst;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
- dbg_log (_("Haven't found \"%s\" in hosts cache!"), (char *)key);
+ if (__builtin_expect (debug_level > 0, 0))
+ dbg_log (_("Haven't found \"%s\" in hosts cache!"), (char *) key);
if (secure[hstdb])
{
@@ -309,15 +312,47 @@ addhstbyname (struct database *db, int fd, request_header *req,
&& h_errno == NETDB_INTERNAL
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ hst = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[hstdb])
seteuid (oldeuid);
cache_addhst (db, fd, req, key, hst, uid);
+
+ if (use_malloc)
+ free (buffer);
}
@@ -329,13 +364,14 @@ addhstbyaddr (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 512;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct hostent resultbuf;
struct hostent *hst;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
+ if (__builtin_expect (debug_level > 0, 0))
{
char buf[INET_ADDRSTRLEN];
dbg_log (_("Haven't found \"%s\" in hosts cache!"),
@@ -353,15 +389,47 @@ addhstbyaddr (struct database *db, int fd, request_header *req,
&& h_errno == NETDB_INTERNAL
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ hst = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[hstdb])
seteuid (oldeuid);
cache_addhst (db, fd, req, key, hst, uid);
+
+ if (use_malloc)
+ free (buffer);
}
@@ -373,13 +441,14 @@ addhstbynamev6 (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 512;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct hostent resultbuf;
struct hostent *hst;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
+ if (__builtin_expect (debug_level > 0, 0))
{
char buf[INET6_ADDRSTRLEN];
@@ -398,15 +467,47 @@ addhstbynamev6 (struct database *db, int fd, request_header *req,
&& h_errno == NETDB_INTERNAL
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ hst = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[hstdb])
seteuid (oldeuid);
cache_addhst (db, fd, req, key, hst, uid);
+
+ if (use_malloc)
+ free (buffer);
}
@@ -418,13 +519,14 @@ addhstbyaddrv6 (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 512;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct hostent resultbuf;
struct hostent *hst;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
+ if (__builtin_expect (debug_level > 0, 0))
{
char buf[INET6_ADDRSTRLEN];
dbg_log (_("Haven't found \"%s\" in hosts cache!"),
@@ -442,13 +544,45 @@ addhstbyaddrv6 (struct database *db, int fd, request_header *req,
&& h_errno == NETDB_INTERNAL
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ hst = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[hstdb])
seteuid (oldeuid);
cache_addhst (db, fd, req, key, hst, uid);
+
+ if (use_malloc)
+ free (buffer);
}
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 94d8bd2d55..9d88c88a37 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -1,5 +1,5 @@
/* Cache handling for passwd lookup.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -21,6 +21,7 @@
#include <errno.h>
#include <error.h>
#include <pwd.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -28,6 +29,7 @@
#include <time.h>
#include <unistd.h>
#include <libintl.h>
+#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
@@ -200,14 +202,15 @@ addpwbyname (struct database *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 256;
- char *buffer = alloca (buflen);
+ int buflen = 1024;
+ char *buffer = (char *) alloca (buflen);
struct passwd resultbuf;
struct passwd *pwd;
uid_t oldeuid = 0;
+ bool use_malloc = false;
- if (debug_level > 0)
- dbg_log (_("Haven't found \"%s\" in password cache!"), (char *)key);
+ if (__builtin_expect (debug_level > 0, 0))
+ dbg_log (_("Haven't found \"%s\" in password cache!"), (char *) key);
if (secure[pwddb])
{
@@ -218,15 +221,47 @@ addpwbyname (struct database *db, int fd, request_header *req,
while (__getpwnam_r (key, &resultbuf, buffer, buflen, &pwd) != 0
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ pwd = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[pwddb])
seteuid (oldeuid);
cache_addpw (db, fd, req, key, pwd, c_uid);
+
+ if (use_malloc)
+ free (buffer);
}
@@ -239,13 +274,24 @@ addpwbyuid (struct database *db, int fd, request_header *req,
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
int buflen = 256;
- char *buffer = alloca (buflen);
+ char *buffer = (char *) alloca (buflen);
struct passwd resultbuf;
struct passwd *pwd;
- uid_t uid = atol (key);
uid_t oldeuid = 0;
+ char *ep;
+ uid_t uid = strtoul ((char *) key, &ep, 10);
+ bool use_malloc = false;
+
+ if (*(char *) key == '\0' || *ep != '\0') /* invalid numeric uid */
+ {
+ if (debug_level > 0)
+ dbg_log (_("Invalid numeric uid \"%s\"!"), (char *) key);
- if (debug_level > 0)
+ errno = EINVAL;
+ return;
+ }
+
+ if (__builtin_expect (debug_level > 0, 0))
dbg_log (_("Haven't found \"%d\" in password cache!"), uid);
if (secure[pwddb])
@@ -257,13 +303,45 @@ addpwbyuid (struct database *db, int fd, request_header *req,
while (__getpwuid_r (uid, &resultbuf, buffer, buflen, &pwd) != 0
&& errno == ERANGE)
{
+ char *old_buffer = buffer;
errno = 0;
- buflen += 256;
- buffer = alloca (buflen);
+ buflen += 1024;
+
+ if (__builtin_expect (buflen > 32768, 0))
+ {
+ buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
+ if (buffer == NULL)
+ {
+ /* We ran out of memory. We cannot do anything but
+ sending a negative response. In reality this should
+ never happen. */
+ pwd = NULL;
+ buffer = old_buffer;
+ break;
+ }
+ use_malloc = true;
+ }
+ else
+ {
+ buffer = (char *) alloca (buflen);
+#if _STACK_GROWS_DOWN
+ if (buffer + buflen == old_buffer)
+ buflen = 2 * buflen - 1024;
+#elif _STACK_GROWS_UP
+ if (old_buffer + buflen - 1024 == buffer)
+ {
+ buffer = old_buffer;
+ buflen = 2 * buflen - 1024;
+ }
+#endif
+ }
}
if (secure[pwddb])
seteuid (oldeuid);
cache_addpw (db, fd, req, key, pwd, c_uid);
+
+ if (use_malloc)
+ free (buffer);
}