]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
posix: Fix generic p{read,write}v buffer allocation (BZ#22457)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 22 Nov 2017 20:02:20 +0000 (18:02 -0200)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 24 Nov 2017 14:16:15 +0000 (12:16 -0200)
As described in BZ#22457 an interpose malloc can free an invalid
pointer for fallback preadv implementation.  Fortunately this is
just and issue on microblaze-linux-gnu running kernels older than
3.15.  This patch fixes it by calling mmap/unmap instead of
posix_memalign/ free.

Checked on microblaze-linux-gnu check with run-built-tests=no and
by using the sysdeps/posix implementation on x86_64-linux-gnu (just
for sanity test where it shown no regression).

[BZ #22457]
* sysdeps/posix/preadv_common.c (PREADV): Use mmap/munmap instead of
posix_memalign/free.
* sysdeps/posix/pwritev_common.c (PWRITEV): Likewise.

ChangeLog
sysdeps/posix/preadv_common.c
sysdeps/posix/pwritev_common.c

index e60983a50f04300c266b0f85fbe32228ccf0977b..6791c51308edc57477836a705025c5f231f489ee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-24  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+       [BZ #22457]
+       * sysdeps/posix/preadv_common.c (PREADV): Use mmap/munmap instead of
+       posix_memalign/free.
+       * sysdeps/posix/pwritev_common.c (PWRITEV): Likewise.
+
 2017-11-22  Mike FABIAN  <mfabian@redhat.com>
 
        [BZ #22469]
index 37efdc0ec0223494e3770d2d0b07f44e9f1c3c2a..76cf261a5c1b92bf9f7732ae2738dc5b0090af1e 100644 (file)
@@ -24,6 +24,7 @@
 #include <malloc.h>
 
 #include <ldsodefs.h>
+#include <libc-pointer-arith.h>
 
 /* Read data from file descriptor FD at the given position OFFSET
    without change the file pointer, and put the result in the buffers
@@ -54,8 +55,9 @@ PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
      but 1. it is system specific (not meant in generic implementation), and
      2. it would make the implementation more complex, and 3. it will require
      another syscall (fcntl).  */
-  void *buffer = NULL;
-  if (__posix_memalign (&buffer, GLRO(dl_pagesize), bytes) != 0)
+  void *buffer = __mmap (NULL, bytes, PROT_READ | PROT_WRITE,
+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (__glibc_unlikely (buffer == MAP_FAILED))
     return -1;
 
   ssize_t bytes_read = PREAD (fd, buffer, bytes, offset);
@@ -78,6 +80,6 @@ PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
     }
 
 end:
-  free (buffer);
+  __munmap (buffer, bytes);
   return bytes_read;
 }
index 03830650e4c4f7beb0bc5002d88ae2cb2dd57f2b..3528fd896b0a426ced9d0d068e1841ce21de17da 100644 (file)
@@ -24,6 +24,7 @@
 #include <malloc.h>
 
 #include <ldsodefs.h>
+#include <libc-pointer-arith.h>
 
 /* Write data pointed by the buffers described by IOVEC, which is a
    vector of COUNT 'struct iovec's, to file descriptor FD at the given
@@ -54,8 +55,9 @@ PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
      but 1. it is system specific (not meant in generic implementation), and
      2. it would make the implementation more complex, and 3. it will require
      another syscall (fcntl).  */
-  void *buffer = NULL;
-  if (__posix_memalign (&buffer, GLRO(dl_pagesize), bytes) != 0)
+  void *buffer = __mmap (NULL, bytes, PROT_WRITE,
+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (__glibc_unlikely (buffer == MAP_FAILED))
     return -1;
 
   /* Copy the data from BUFFER into the memory specified by VECTOR.  */
@@ -66,7 +68,7 @@ PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
 
   ssize_t ret = PWRITE (fd, buffer, bytes, offset);
 
-  free (buffer);
+  __munmap (buffer, bytes);
 
   return ret;
 }