hurd: writev: Get rid of alloca

Use a scratch_buffer rather than alloca to avoid potential stack
overflows.

Checked on i686-gnu and x86_64-linux-gnu
Message-Id: <20230608155844.976554-1-josimmon@redhat.com>
This commit is contained in:
Joe Simmons-Talbott 2023-06-08 11:58:43 -04:00 committed by Samuel Thibault
parent 01dd2875f8
commit cf30aa43a5

View File

@ -19,19 +19,13 @@
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <scratch_buffer.h>
#include <stdbool.h>
#include <sys/param.h>
#include <sys/uio.h>
#include <errno.h>
static void
ifree (char **ptrp)
{
free (*ptrp);
}
/* Write data pointed by the buffers described by VECTOR, which
is a vector of COUNT 'struct iovec's, to file descriptor FD.
The data is written in the order specified.
@ -53,22 +47,17 @@ __writev (int fd, const struct iovec *vector, int count)
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. */
char *buffer;
char *malloced_buffer __attribute__ ((__cleanup__ (ifree))) = NULL;
if (__libc_use_alloca (bytes))
buffer = (char *) __alloca (bytes);
else
{
malloced_buffer = buffer = (char *) malloc (bytes);
if (buffer == NULL)
/* XXX I don't know whether it is acceptable to try writing
the data in chunks. Probably not so we just fail here. */
return -1;
}
/* Allocate a temporary buffer to hold the data. Use a scratch_buffer
since it's faster for small buffer sizes but can handle larger
allocations as well. */
struct scratch_buffer buf;
scratch_buffer_init (&buf);
if (!scratch_buffer_set_array_size (&buf, 1, bytes))
/* XXX I don't know whether it is acceptable to try writing
the data in chunks. Probably not so we just fail here. */
return -1;
char *buffer = buf.data;
/* Copy the data into BUFFER. */
size_t to_copy = bytes;
@ -86,6 +75,8 @@ __writev (int fd, const struct iovec *vector, int count)
ssize_t bytes_written = __write (fd, buffer, bytes);
scratch_buffer_free (&buf);
return bytes_written;
}
libc_hidden_def (__writev)