From patchwork Fri Apr 24 12:53:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 464216 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D7022140150 for ; Fri, 24 Apr 2015 23:46:08 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=sourceware.org header.i=@sourceware.org header.b=Ws83C0sd; dkim-adsp=none (unprotected policy); dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:date:subject:to:message-id; q=dns; s= default; b=uPkukJbq1ViaQcEfKGFb4US4lQ7USH7tHBojgtd1/18irdS6EtAxi n3ckbx3Y8wjqA2cgbVbT8lQHMfupmm9dXvFx5fMfE/iZjncXjDIvYgM0d3Rf0LPg Q8k07muf84AicAt9X6bP21r8hbfQBpSnSk/diXI/wsvAqwI8Ii3T30= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:date:subject:to:message-id; s=default; bh=e9vDxeUWg5dLTGAId8FA9n4BV3c=; b=Ws83C0sdnIovyNftEIzlWMfDFsSs N3nxP7bJ1hv+ojIcG6WyxhqfaKI3bXnhW1EStSIU+armG1ZuS8vHn7rDvd9vv/g1 0ywg6wrbZi+ZuS2vvRGSg58sMRF8OkTDbHmsDTCiCN2YqLbUelVmUQMilfnHubVT v7wwdltcDrLvtTc= Received: (qmail 119269 invoked by alias); 24 Apr 2015 13:45:26 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 118625 invoked by uid 89); 24 Apr 2015 13:45:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_50, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com From: Florian Weimer Date: Fri, 24 Apr 2015 14:53:35 +0200 Subject: [PATCH 4/4] Remove broken posix_fallocate, posix_falllocate64 fallback code [BZ#15661] To: libc-alpha@sourceware.org Message-Id: <20150424134516.6795441F484D0@oldenburg.str.redhat.com> 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 + [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 + * 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 - . */ - -#include -#include -#include -#include -#include - -/* 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 - . */ - -#include -#include -#include -#include -#include - -/* 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 -#include - -#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 #include -#define posix_fallocate static internal_fallocate -#include -#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 #include -extern int __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len); -#define __posix_fallocate64_l64 static internal_fallocate64 -#include -#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 #include -#define posix_fallocate static internal_fallocate -#include -#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 . */ +#include #include +#include #include -extern int __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len); -#define __posix_fallocate64_l64 static internal_fallocate64 -#include -#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 @@ . */ #include +#include #include #include -#define posix_fallocate static internal_fallocate -#include -#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)