This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 4/4] Remove broken posix_fallocate, posix_falllocate64 fallback code [BZ#15661]


The previous implementation could result in silent data corruption,
and this has been observed to happen with application code.
---
 ChangeLog                                          |  18 ++++
 NEWS                                               |  22 ++--
 sysdeps/posix/posix_fallocate.c                    |  93 -----------------
 sysdeps/posix/posix_fallocate64.c                  | 113 ---------------------
 .../sysv/linux/mips/mips64/n32/posix_fallocate.c   |   8 +-
 .../sysv/linux/mips/mips64/n32/posix_fallocate64.c |   9 +-
 sysdeps/unix/sysv/linux/posix_fallocate.c          |   8 +-
 sysdeps/unix/sysv/linux/posix_fallocate64.c        |  26 +++--
 .../unix/sysv/linux/wordsize-64/posix_fallocate.c  |  10 +-
 9 files changed, 56 insertions(+), 251 deletions(-)
 delete mode 100644 sysdeps/posix/posix_fallocate.c
 delete mode 100644 sysdeps/posix/posix_fallocate64.c

diff --git a/ChangeLog b/ChangeLog
index b927022..9219d8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2015-04-24  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ#15661]
+	* sysdeps/posix/posix_fallocate.c: Remove.
+	* sysdeps/posix/posix_fallocate64.c: Likewise.
+	* sysdeps/unix/sysv/linux/posix_fallocate.c (posix_fallocate):
+	Remove internal_fallocate function and fallback.
+	* sysdeps/unix/sysv/linux/posix_fallocate64.c
+	(__posix_fallocate64_l64): Likewise.  Establish aliases previously
+	defined in sysdeps/posix/posix_fallocate64.c.
+	* sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate.c
+	(posix_fallocate): Remove internal_fallocate function and
+	fallback.
+	* sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate64.c
+	(__posix_fallocate64_l64): Likewise.
+	* sysdeps/unix/sysv/linux/wordsize-64/posix_fallocate.c
+	(posix_fallocate): Likewise.
+
+2015-04-24  Florian Weimer  <fweimer@redhat.com>
+
 	* sysdeps/unix/sysv/linux/posix_fallocate.c (posix_fallocate):
 	Assume __ASSUME_FALLOCATE is always true.
 	* sysdeps/unix/sysv/linux/posix_fallocate64.c
diff --git a/NEWS b/NEWS
index ccc4d13..016629f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,14 +9,14 @@ Version 2.22
 
 * The following bugs are resolved with this release:
 
-  4719, 6792, 13064, 14094, 14841, 14906, 15319, 15467, 15790, 15969, 16351,
-  16512, 16560, 16783, 16850, 17090, 17195, 17269, 17523, 17542, 17569,
-  17588, 17596, 17620, 17621, 17628, 17631, 17711, 17776, 17779, 17792,
-  17836, 17912, 17916, 17930, 17932, 17944, 17949, 17964, 17965, 17967,
-  17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
-  18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18068,
-  18080, 18093, 18100, 18104, 18110, 18111, 18128, 18138, 18185, 18197,
-  18206, 18210, 18211, 18247, 18287.
+  4719, 6792, 13064, 14094, 14841, 14906, 15319, 15467, 15661, 15790, 15969,
+  16351, 16512, 16560, 16783, 16850, 17090, 17195, 17269, 17523, 17542,
+  17569, 17588, 17596, 17620, 17621, 17628, 17631, 17711, 17776, 17779,
+  17792, 17836, 17912, 17916, 17930, 17932, 17944, 17949, 17964, 17965,
+  17967, 17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020,
+  18029, 18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047,
+  18068, 18080, 18093, 18100, 18104, 18110, 18111, 18128, 18138, 18185,
+  18197, 18206, 18210, 18211, 18247, 18287.
 
 * A buffer overflow in gethostbyname_r and related functions performing DNS
   requests has been fixed.  If the NSS functions were called with a
@@ -25,6 +25,12 @@ Version 2.22
   potentially arbitrary code execution, using crafted, but syntactically
   valid DNS responses.  (CVE-2015-1781)
 
+* The fallback emulation of posix_fallocate and posix_fallocate64 was
+  removed because it could result in silent data corruption on file systems
+  which do not implement fallocate support in the kernel.  posix_fallocate
+  and posix_fallocate64 will now fail and return ENOTSUP if the file system
+  does not support fallocate operations.
+
 * A powerpc and powerpc64 optimization for TLS, similar to TLS descriptors
   for LD and GD on x86 and x86-64, has been implemented.  You will need
   binutils-2.24 or later to enable this optimization.
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c
deleted file mode 100644
index d15d603..0000000
--- a/sysdeps/posix/posix_fallocate.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (C) 2000-2015 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-
-/* Reserve storage for the data of the file associated with FD.  */
-
-int
-posix_fallocate (int fd, __off_t offset, __off_t len)
-{
-  struct stat64 st;
-  struct statfs f;
-
-  /* `off_t' is a signed type.  Therefore we can determine whether
-     OFFSET + LEN is too large if it is a negative value.  */
-  if (offset < 0 || len < 0)
-    return EINVAL;
-  if (offset + len < 0)
-    return EFBIG;
-
-  /* First thing we have to make sure is that this is really a regular
-     file.  */
-  if (__fxstat64 (_STAT_VER, fd, &st) != 0)
-    return EBADF;
-  if (S_ISFIFO (st.st_mode))
-    return ESPIPE;
-  if (! S_ISREG (st.st_mode))
-    return ENODEV;
-
-  if (len == 0)
-    {
-      if (st.st_size < offset)
-	{
-	  int ret = __ftruncate (fd, offset);
-
-	  if (ret != 0)
-	    ret = errno;
-	  return ret;
-	}
-      return 0;
-    }
-
-  /* We have to know the block size of the filesystem to get at least some
-     sort of performance.  */
-  if (__fstatfs (fd, &f) != 0)
-    return errno;
-
-  /* Try to play safe.  */
-  if (f.f_bsize == 0)
-    f.f_bsize = 512;
-
-  /* Write something to every block.  */
-  for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize)
-    {
-      len -= f.f_bsize;
-
-      if (offset < st.st_size)
-	{
-	  unsigned char c;
-	  ssize_t rsize = __pread (fd, &c, 1, offset);
-
-	  if (rsize < 0)
-	    return errno;
-	  /* If there is a non-zero byte, the block must have been
-	     allocated already.  */
-	  else if (rsize == 1 && c != 0)
-	    continue;
-	}
-
-      if (__pwrite (fd, "", 1, offset) != 1)
-	return errno;
-    }
-
-  return 0;
-}
diff --git a/sysdeps/posix/posix_fallocate64.c b/sysdeps/posix/posix_fallocate64.c
deleted file mode 100644
index b845df7..0000000
--- a/sysdeps/posix/posix_fallocate64.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (C) 2000-2015 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-
-/* Reserve storage for the data of the file associated with FD.  */
-
-int
-__posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
-{
-  struct stat64 st;
-  struct statfs64 f;
-
-  /* `off64_t' is a signed type.  Therefore we can determine whether
-     OFFSET + LEN is too large if it is a negative value.  */
-  if (offset < 0 || len < 0)
-    return EINVAL;
-  if (offset + len < 0)
-    return EFBIG;
-
-  /* First thing we have to make sure is that this is really a regular
-     file.  */
-  if (__fxstat64 (_STAT_VER, fd, &st) != 0)
-    return EBADF;
-  if (S_ISFIFO (st.st_mode))
-    return ESPIPE;
-  if (! S_ISREG (st.st_mode))
-    return ENODEV;
-
-  if (len == 0)
-    {
-      if (st.st_size < offset)
-	{
-	  int ret = __ftruncate64 (fd, offset);
-
-	  if (ret != 0)
-	    ret = errno;
-	  return ret;
-	}
-      return 0;
-    }
-
-  /* We have to know the block size of the filesystem to get at least some
-     sort of performance.  */
-  if (__fstatfs64 (fd, &f) != 0)
-    return errno;
-
-  /* Try to play safe.  */
-  if (f.f_bsize == 0)
-    f.f_bsize = 512;
-
-  /* Write something to every block.  */
-  for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize)
-    {
-      len -= f.f_bsize;
-
-      if (offset < st.st_size)
-	{
-	  unsigned char c;
-	  ssize_t rsize = __libc_pread64 (fd, &c, 1, offset);
-
-	  if (rsize < 0)
-	    return errno;
-	  /* If there is a non-zero byte, the block must have been
-	     allocated already.  */
-	  else if (rsize == 1 && c != 0)
-	    continue;
-	}
-
-      if (__libc_pwrite64 (fd, "", 1, offset) != 1)
-	return errno;
-    }
-
-  return 0;
-}
-
-#undef __posix_fallocate64_l64
-#include <shlib-compat.h>
-#include <bits/wordsize.h>
-
-#if __WORDSIZE == 32 && SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
-
-int
-attribute_compat_text_section
-__posix_fallocate64_l32 (int fd, off64_t offset, size_t len)
-{
-  return __posix_fallocate64_l64 (fd, offset, len);
-}
-
-versioned_symbol (libc, __posix_fallocate64_l64, posix_fallocate64,
-		  GLIBC_2_3_3);
-compat_symbol (libc, __posix_fallocate64_l32, posix_fallocate64, GLIBC_2_2);
-#else
-strong_alias (__posix_fallocate64_l64, posix_fallocate64);
-#endif
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate.c b/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate.c
index a9c8d73..5d926f5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate.c
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate.c
@@ -18,10 +18,6 @@
 #include <fcntl.h>
 #include <sysdep.h>
 
-#define posix_fallocate static internal_fallocate
-#include <sysdeps/posix/posix_fallocate.c>
-#undef posix_fallocate
-
 /* Reserve storage for the data of the file associated with FD.  */
 int
 posix_fallocate (int fd, __off_t offset, __off_t len)
@@ -31,7 +27,5 @@ posix_fallocate (int fd, __off_t offset, __off_t len)
 
   if (! INTERNAL_SYSCALL_ERROR_P (res, err))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res, err) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return internal_fallocate (fd, offset, len);
+  return INTERNAL_SYSCALL_ERRNO (res, err);
 }
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate64.c b/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate64.c
index 503e918..5d3a636 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate64.c
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fallocate64.c
@@ -18,11 +18,6 @@
 #include <fcntl.h>
 #include <sysdep.h>
 
-extern int __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len);
-#define __posix_fallocate64_l64 static internal_fallocate64
-#include <sysdeps/posix/posix_fallocate64.c>
-#undef __posix_fallocate64_l64
-
 /* Reserve storage for the data of the file associated with FD.  */
 int
 __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
@@ -32,7 +27,5 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
 
   if (! INTERNAL_SYSCALL_ERROR_P (res, err))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res, err) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return internal_fallocate64 (fd, offset, len);
+  return INTERNAL_SYSCALL_ERRNO (res, err);
 }
diff --git a/sysdeps/unix/sysv/linux/posix_fallocate.c b/sysdeps/unix/sysv/linux/posix_fallocate.c
index 4587029..b6124db 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate.c
@@ -18,10 +18,6 @@
 #include <fcntl.h>
 #include <sysdep.h>
 
-#define posix_fallocate static internal_fallocate
-#include <sysdeps/posix/posix_fallocate.c>
-#undef posix_fallocate
-
 /* Reserve storage for the data of the file associated with FD.  */
 int
 posix_fallocate (int fd, __off_t offset, __off_t len)
@@ -33,7 +29,5 @@ posix_fallocate (int fd, __off_t offset, __off_t len)
 
   if (! INTERNAL_SYSCALL_ERROR_P (res, err))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res, err) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return internal_fallocate (fd, offset, len);
+  return INTERNAL_SYSCALL_ERRNO (res, err);
 }
diff --git a/sysdeps/unix/sysv/linux/posix_fallocate64.c b/sysdeps/unix/sysv/linux/posix_fallocate64.c
index 771e59c..97c5a57 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate64.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate64.c
@@ -15,14 +15,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <bits/wordsize.h>
 #include <fcntl.h>
+#include <shlib-compat.h>
 #include <sysdep.h>
 
-extern int __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len);
-#define __posix_fallocate64_l64 static internal_fallocate64
-#include <sysdeps/posix/posix_fallocate64.c>
-#undef __posix_fallocate64_l64
-
 /* Reserve storage for the data of the file associated with FD.  */
 int
 __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
@@ -36,7 +33,20 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
 
   if (! INTERNAL_SYSCALL_ERROR_P (res, err))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res, err) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return internal_fallocate64 (fd, offset, len);
+  return INTERNAL_SYSCALL_ERRNO (res, err);
+}
+
+#if __WORDSIZE == 32 && SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
+int
+attribute_compat_text_section
+__posix_fallocate64_l32 (int fd, off64_t offset, size_t len)
+{
+  return __posix_fallocate64_l64 (fd, offset, len);
 }
+
+versioned_symbol (libc, __posix_fallocate64_l64, posix_fallocate64,
+		  GLIBC_2_3_3);
+compat_symbol (libc, __posix_fallocate64_l32, posix_fallocate64, GLIBC_2_2);
+#else
+strong_alias (__posix_fallocate64_l64, posix_fallocate64);
+#endif
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/posix_fallocate.c b/sysdeps/unix/sysv/linux/wordsize-64/posix_fallocate.c
index 8ae8a29..992d8cb 100644
--- a/sysdeps/unix/sysv/linux/wordsize-64/posix_fallocate.c
+++ b/sysdeps/unix/sysv/linux/wordsize-64/posix_fallocate.c
@@ -16,13 +16,10 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
+#include <errno.h>
 #include <kernel-features.h>
 #include <sysdep.h>
 
-#define posix_fallocate static internal_fallocate
-#include <sysdeps/posix/posix_fallocate.c>
-#undef posix_fallocate
-
 /* The alpha architecture introduced the fallocate system call in
    2.6.33-rc1, so we still need the fallback code.  */
 #if !defined __ASSUME_FALLOCATE && defined __NR_fallocate
@@ -56,11 +53,10 @@ posix_fallocate (int fd, __off_t offset, __off_t len)
 	__have_fallocate = -1;
       else
 # endif
-	if (INTERNAL_SYSCALL_ERRNO (res, err) != EOPNOTSUPP)
-	  return INTERNAL_SYSCALL_ERRNO (res, err);
+	return INTERNAL_SYSCALL_ERRNO (res, err);
     }
 #endif
 
-  return internal_fallocate (fd, offset, len);
+  return ENOSYS;
 }
 weak_alias (posix_fallocate, posix_fallocate64)
-- 
2.1.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]