aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--string/strnlen.c44
-rw-r--r--sunrpc/auth_unix.c14
-rw-r--r--sunrpc/svc_tcp.c4
-rw-r--r--sunrpc/svc_udp.c3
-rw-r--r--sunrpc/svc_unix.c4
-rw-r--r--sunrpc/xdr_rec.c12
-rw-r--r--sysdeps/generic/strnlen.c157
-rw-r--r--sysdeps/i386/i486/bits/string.h12
9 files changed, 197 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index 783c73f3ef..6f854b6936 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2001-08-22 Jakub Jelinek <jakub@redhat.com>
+
+ * sunrpc/xdr_rec.c (xdrrec_create): Fix buf sizes before allocating
+ buf. Free resources on failure.
+ * sunrpc/svc_unix.c (svcunix_create): Free resources on failure.
+ (makefd_xprt): Likewise.
+ * sunrpc/svc_udp.c (svcudp_bufcreate): Likewise.
+ * sunrpc/svc_tcp.c (svctcp_create, makefd_xprt): Likewise.
+ * sunrpc/auth_unix.c (authunix_create): Likewise.
+
+2001-08-21 Jakub Jelinek <jakub@redhat.com>
+
+ * string/strnlen.c: Remove.
+ * sysdeps/generic/strnlen.c: New.
+ * sysdeps/i386/i486/bits/string.h (strnlen): Remove.
+
2001-08-21 Roland McGrath <roland@frob.com>
* sysdeps/mach/i386/machine-sp.h (__thread_stack_pointer): Define this
diff --git a/string/strnlen.c b/string/strnlen.c
deleted file mode 100644
index a777b35ca9..0000000000
--- a/string/strnlen.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Find the length of STRING, but scan at most MAXLEN characters.
- Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <string.h>
-
-/* Find the length of S, but scan at most MAXLEN characters. If no
- '\0' terminator is found in that many characters, return MAXLEN. */
-
-size_t
-__strnlen (const char *s, size_t maxlen)
-{
- size_t len = 0;
-
- while (s[len] != '\0' && maxlen > 0)
- {
- if (s[++len] == '\0' || --maxlen == 0)
- return len;
- if (s[++len] == '\0' || --maxlen == 0)
- return len;
- if (s[++len] == '\0' || --maxlen == 0)
- return len;
- ++len;
- --maxlen;
- }
-
- return len;
-}
-weak_alias (__strnlen, strnlen)
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
index 50f955146c..bcfa0c931f 100644
--- a/sunrpc/auth_unix.c
+++ b/sunrpc/auth_unix.c
@@ -108,6 +108,7 @@ authunix_create (char *machname, uid_t uid, gid_t gid, int len,
au = (struct audata *) mem_alloc (sizeof (*au));
if (auth == NULL || au == NULL)
{
+no_memory:
#ifdef USE_IN_LIBIO
if (_IO_fwide (stderr, 0) > 0)
(void) __fwprintf (stderr, L"%s",
@@ -115,6 +116,8 @@ authunix_create (char *machname, uid_t uid, gid_t gid, int len,
else
#endif
(void) fputs (_("authunix_create: out of memory\n"), stderr);
+ mem_free (auth, sizeof (*auth));
+ mem_free (au, sizeof (*au));
return NULL;
}
auth->ah_ops = &auth_unix_ops;
@@ -143,16 +146,7 @@ authunix_create (char *machname, uid_t uid, gid_t gid, int len,
au->au_origcred.oa_flavor = AUTH_UNIX;
au->au_origcred.oa_base = mem_alloc ((u_int) len);
if (au->au_origcred.oa_base == NULL)
- {
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stderr, 0) > 0)
- (void) __fwprintf (stderr, L"%s",
- _("authunix_create: out of memory\n"));
- else
-#endif
- (void) fputs (_("authunix_create: out of memory\n"), stderr);
- return NULL;
- }
+ goto no_memory;
memcpy(au->au_origcred.oa_base, mymem, (u_int) len);
/*
diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c
index 2fffdf5b5c..cda2484b6f 100644
--- a/sunrpc/svc_tcp.c
+++ b/sunrpc/svc_tcp.c
@@ -183,6 +183,8 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
else
#endif
(void) fputs (_("svctcp_create: out of memory\n"), stderr);
+ mem_free (r, sizeof (*r));
+ mem_free (xprt, sizeof (SVCXPRT));
return NULL;
}
r->sendsize = sendsize;
@@ -225,6 +227,8 @@ makefd_xprt (int fd, u_int sendsize, u_int recvsize)
else
#endif
(void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr);
+ mem_free (xprt, sizeof (SVCXPRT));
+ mem_free (cd, sizeof (struct tcp_conn));
return NULL;
}
cd->strm_stat = XPRT_IDLE;
diff --git a/sunrpc/svc_udp.c b/sunrpc/svc_udp.c
index f8ea76c0b8..17c4977e96 100644
--- a/sunrpc/svc_udp.c
+++ b/sunrpc/svc_udp.c
@@ -156,6 +156,9 @@ svcudp_bufcreate (sock, sendsz, recvsz)
else
#endif
(void) fputs (_("svcudp_create: out of memory\n"), stderr);
+ mem_free (xprt, sizeof (SVCXPRT));
+ mem_free (su, sizeof (*su));
+ mem_free (buf, ((MAX (sendsz, recvsz) + 3) / 4) * 4);
return NULL;
}
su->su_iosz = ((MAX (sendsz, recvsz) + 3) / 4) * 4;
diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
index 99e5a2a781..72bc9c2dda 100644
--- a/sunrpc/svc_unix.c
+++ b/sunrpc/svc_unix.c
@@ -179,6 +179,8 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
else
#endif
fputs (_("svcunix_create: out of memory\n"), stderr);
+ mem_free (r, sizeof (*r));
+ mem_free (xprt, sizeof (SVCXPRT));
return NULL;
}
r->sendsize = sendsize;
@@ -221,6 +223,8 @@ makefd_xprt (int fd, u_int sendsize, u_int recvsize)
else
#endif
(void) fputs (_("svc_unix: makefd_xprt: out of memory\n"), stderr);
+ mem_free (xprt, sizeof (SVCXPRT));
+ mem_free (cd, sizeof (struct unix_conn));
return NULL;
}
cd->strm_stat = XPRT_IDLE;
diff --git a/sunrpc/xdr_rec.c b/sunrpc/xdr_rec.c
index 65ffa3799e..941afa35de 100644
--- a/sunrpc/xdr_rec.c
+++ b/sunrpc/xdr_rec.c
@@ -146,7 +146,11 @@ xdrrec_create (XDR *xdrs, u_int sendsize,
{
RECSTREAM *rstrm = (RECSTREAM *) mem_alloc (sizeof (RECSTREAM));
caddr_t tmp;
- char *buf = mem_alloc (sendsize + recvsize + BYTES_PER_XDR_UNIT);
+ char *buf;
+
+ sendsize = fix_buf_size (sendsize);
+ recvsize = fix_buf_size (recvsize);
+ buf = mem_alloc (sendsize + recvsize + BYTES_PER_XDR_UNIT);
if (rstrm == NULL || buf == NULL)
{
@@ -156,6 +160,8 @@ xdrrec_create (XDR *xdrs, u_int sendsize,
else
#endif
(void) fputs (_("xdrrec_create: out of memory\n"), stderr);
+ mem_free (rstrm, sizeof (RECSTREAM));
+ mem_free (buf, sendsize + recvsize + BYTES_PER_XDR_UNIT);
/*
* This is bad. Should rework xdrrec_create to
* return a handle, and in this case return NULL
@@ -165,8 +171,8 @@ xdrrec_create (XDR *xdrs, u_int sendsize,
/*
* adjust sizes and allocate buffer quad byte aligned
*/
- rstrm->sendsize = sendsize = fix_buf_size (sendsize);
- rstrm->recvsize = recvsize = fix_buf_size (recvsize);
+ rstrm->sendsize = sendsize;
+ rstrm->recvsize = recvsize;
rstrm->the_buffer = buf;
tmp = rstrm->the_buffer;
if ((size_t)tmp % BYTES_PER_XDR_UNIT)
diff --git a/sysdeps/generic/strnlen.c b/sysdeps/generic/strnlen.c
new file mode 100644
index 0000000000..f1b6760247
--- /dev/null
+++ b/sysdeps/generic/strnlen.c
@@ -0,0 +1,157 @@
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ Copyright (C) 1991, 1993, 1997, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ Based on strlen written by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se);
+ commentary by Jim Blandy (jimb@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <stdlib.h>
+
+/* Find the length of S, but scan at most MAXLEN characters. If no
+ '\0' terminator is found in that many characters, return MAXLEN. */
+size_t
+__strnlen (const char *str, size_t maxlen)
+{
+ const char *char_ptr, *end_ptr = str + maxlen;
+ const unsigned long int *longword_ptr;
+ unsigned long int longword, magic_bits, himagic, lomagic;
+
+ if (maxlen == 0)
+ return 0;
+
+ /* Handle the first few characters by reading one character at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = str; ((unsigned long int) char_ptr
+ & (sizeof (longword) - 1)) != 0;
+ ++char_ptr)
+ if (*char_ptr == '\0')
+ {
+ if (char_ptr > end_ptr)
+ char_ptr = end_ptr;
+ return char_ptr - str;
+ }
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to 8-byte longwords. */
+
+ longword_ptr = (unsigned long int *) char_ptr;
+
+ /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
+ the "holes." Note that there is a hole just to the left of
+ each byte, with an extra at the end:
+
+ bits: 01111110 11111110 11111110 11111111
+ bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+ The 1-bits make sure that carries propagate to the next 0-bit.
+ The 0-bits provide holes for carries to fall into. */
+ magic_bits = 0x7efefeffL;
+ himagic = 0x80808080L;
+ lomagic = 0x01010101L;
+ if (sizeof (longword) > 4)
+ {
+ /* 64-bit version of the magic. */
+ /* Do the shift in two steps to avoid a warning if long has 32 bits. */
+ magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
+ himagic = ((himagic << 16) << 16) | himagic;
+ lomagic = ((lomagic << 16) << 16) | lomagic;
+ }
+ if (sizeof (longword) > 8)
+ abort ();
+
+ /* Instead of the traditional loop which tests each character,
+ we will test a longword at a time. The tricky part is testing
+ if *any of the four* bytes in the longword in question are zero. */
+ while (longword_ptr < (unsigned long int *) end_ptr)
+ {
+ /* We tentatively exit the loop if adding MAGIC_BITS to
+ LONGWORD fails to change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-30 is set, there will be a carry
+ into bit 31, so all of the hole bits will be changed.
+
+ The one misfire occurs when bits 24-30 are clear and bit
+ 31 is set; in this case, the hole at bit 31 is not
+ changed. If we had access to the processor carry flag,
+ we could close this loophole by putting the fourth hole
+ at bit 32!
+
+ So it ignores everything except 128's, when they're aligned
+ properly. */
+
+ longword = *longword_ptr++;
+
+ if ((longword - lomagic) & himagic)
+ {
+ /* Which of the bytes was the zero? If none of them were, it was
+ a misfire; continue the search. */
+
+ const char *cp = (const char *) (longword_ptr - 1);
+
+ char_ptr = cp;
+ if (cp[0] == 0)
+ break;
+ char_ptr = cp + 1;
+ if (cp[1] == 0)
+ break;
+ char_ptr = cp + 2;
+ if (cp[2] == 0)
+ break;
+ char_ptr = cp + 3;
+ if (cp[3] == 0)
+ break;
+ if (sizeof (longword) > 4)
+ {
+ char_ptr = cp + 4;
+ if (cp[4] == 0)
+ break;
+ char_ptr = cp + 5;
+ if (cp[5] == 0)
+ break;
+ char_ptr = cp + 6;
+ if (cp[6] == 0)
+ break;
+ char_ptr = cp + 7;
+ if (cp[7] == 0)
+ break;
+ }
+ }
+ char_ptr = end_ptr;
+ }
+
+ if (char_ptr > end_ptr)
+ char_ptr = end_ptr;
+ return char_ptr - str;
+}
+weak_alias (__strnlen, strnlen)
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index bbe39adab7..07757ec389 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -540,18 +540,6 @@ __strlen_g (__const char *__str)
}
-
-#if defined __USE_GNU
-#define _HAVE_STRING_ARCH_strnlen 1
-__STRING_INLINE size_t
-strnlen (__const char *__string, size_t __maxlen)
-{
- __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
- return __end ? (size_t) (__end - __string) : __maxlen;
-}
-#endif
-
-
/* Copy SRC to DEST. */
#define _HAVE_STRING_ARCH_strcpy 1
#define strcpy(dest, src) \