1 /* Overflow tests for stat, statfs, and lseek functions. 2 Copyright (C) 2020-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <sys/stat.h> 20 #include <sys/statfs.h> 21 22 /* Test for overflows of structures where we ask the kernel to fill them 23 in with standard 64-bit syscalls but return them through APIs that 24 only expose the low 32 bits of some fields. */ 25 lseek_overflow(loff_t res)26static inline off_t lseek_overflow (loff_t res) 27 { 28 off_t retval = (off_t) res; 29 if (retval == res) 30 return retval; 31 32 __set_errno (EOVERFLOW); 33 return (off_t) -1; 34 } 35 stat_overflow(struct stat * buf)36static inline int stat_overflow (struct stat *buf) 37 { 38 #if defined __INO_T_MATCHES_INO64_T || !STAT_IS_KERNEL_STAT 39 return 0; 40 #else 41 if (buf->__st_ino_pad == 0 && buf->__st_size_pad == 0 42 && buf->__st_blocks_pad == 0) 43 return 0; 44 45 __set_errno (EOVERFLOW); 46 return -1; 47 #endif 48 } 49 50 /* Note that f_files and f_ffree may validly be a sign-extended -1. */ statfs_overflow(struct statfs * buf)51static inline int statfs_overflow (struct statfs *buf) 52 { 53 #if __STATFS_MATCHES_STATFS64 || !STAT_IS_KERNEL_STAT 54 return 0; 55 #else 56 if (buf->__f_blocks_pad == 0 && buf->__f_bfree_pad == 0 57 && buf->__f_bavail_pad == 0 58 && (buf->__f_files_pad == 0 59 || (buf->f_files == -1U && buf->__f_files_pad == -1)) 60 && (buf->__f_ffree_pad == 0 61 || (buf->f_ffree == -1U && buf->__f_ffree_pad == -1))) 62 return 0; 63 64 __set_errno (EOVERFLOW); 65 return -1; 66 #endif 67 } 68