aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--sysdeps/generic/dl-sysdep.c4
-rw-r--r--sysdeps/posix/readv.c42
3 files changed, 52 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 7edb033..ead120d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2002-01-31 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/posix/readv.c: Don't use alloca if the memory requirements
+ are too high.
+
+2002-01-31 Andreas Schwab <schwab@suse.de>
+
+ * sysdeps/posix/readv.c: Check for ssize_t overflow.
+
+2002-01-31 Andreas Schwab <schwab@suse.de>
+
+ * sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Fix leftover
+ reference to _dl_pagesize.
+
2002-01-30 Ulrich Drepper <drepper@redhat.com>
* Versions.def [ld]: Add GLIBC_2.3.
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index 2954b33..f8b8ac1 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -168,8 +168,8 @@ _dl_sysdep_start (void **start_argptr,
__libc_enable_secure = uid != euid || gid != egid;
#ifndef HAVE_AUX_PAGESIZE
- if (_dl_pagesize == 0)
- _dl_pagesize = __getpagesize ();
+ if (GL(dl_pagesize) == 0)
+ GL(dl_pagesize) = __getpagesize ();
#endif
#ifdef DL_SYSDEP_INIT
diff --git a/sysdeps/posix/readv.c b/sysdeps/posix/readv.c
index 6349e24..89fe1af 100644
--- a/sysdeps/posix/readv.c
+++ b/sysdeps/posix/readv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1996, 1997, 2002 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
@@ -19,6 +19,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <sys/param.h>
#include <sys/uio.h>
/* Read data from file descriptor FD, and put the result in the
@@ -33,17 +36,41 @@ __readv (fd, vector, count)
int count;
{
char *buffer;
+ char *buffer_start;
size_t bytes;
int bytes_read;
int i;
+ bool use_malloc = false;
/* Find the total number of bytes to be read. */
bytes = 0;
for (i = 0; i < count; ++i)
- bytes += vector[i].iov_len;
+ {
+ /* Check for ssize_t overflow. */
+ if (SSIZE_MAX - bytes < vector[i].iov_len)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ bytes += vector[i].iov_len;
+ }
+
+ /* Allocate a temporary buffer to hold the data. We should normally
+ use alloca since it's faster and does not require synchronization
+ with other threads. But we cannot if the amount of memory
+ required is too large. Use 512k as the limit. */
+ if (bytes < 512 * 1024)
+ buffer = (char *) __alloca (bytes);
+ else
+ {
+ buffer = (char *) malloc (bytes);
+ if (buffer == NULL)
+ /* XXX I don't know whether it is acceptable to try reading
+ the data in chunks. Probably not so we just fail here. */
+ return -1;
- /* Allocate a temporary buffer to hold the data. */
- buffer = (char *) __alloca (bytes);
+ use_malloc = true;
+ }
/* Read the data. */
bytes_read = __read (fd, buffer, bytes);
@@ -52,10 +79,10 @@ __readv (fd, vector, count)
/* Copy the data from BUFFER into the memory specified by VECTOR. */
bytes = bytes_read;
+ buffer_start = buffer;
for (i = 0; i < count; ++i)
{
-#define min(a, b) ((a) > (b) ? (b) : (a))
- size_t copy = min (vector[i].iov_len, bytes);
+ size_t copy = MIN (vector[i].iov_len, bytes);
(void) memcpy ((void *) vector[i].iov_base, (void *) buffer, copy);
@@ -65,6 +92,9 @@ __readv (fd, vector, count)
break;
}
+ if (use_malloc)
+ free (buffer_start);
+
return bytes_read;
}
#ifndef __readv