This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 4/4] Remove broken posix_fallocate, posix_falllocate64 fallback code [BZ#15661]
- From: Florian Weimer <fweimer at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Fri, 24 Apr 2015 14:53:35 +0200
- Subject: [PATCH 4/4] Remove broken posix_fallocate, posix_falllocate64 fallback code [BZ#15661]
- Authentication-results: sourceware.org; auth=none
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