Bug #71384 [Opn->Csd]: fread() does not detect file access error

From: Date: Thu, 25 Jul 2019 09:07:08 +0000
Subject: Bug #71384 [Opn->Csd]: fread() does not detect file access error
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-221935@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71384&edit=1 ID: 71384 Updated by: nikic@php.net Reported by: salsi at icosaedro dot it Summary: fread() does not detect file access error -Status: Open +Status: Closed Type: Bug Package: Streams related Operating System: Slackware 14.1 PHP Version: master-Git-2016-01-15 (Git) -Assigned To: +Assigned To: nikic Block user comment: N Private report: N New Comment: This will generate a fread(): read of 8192 bytes failed with errno=5 Input/output error notice (promoted to ErrorException in your example) in PHP 7.4. Previous Comments: ------------------------------------------------------------------------ [2017-12-09 11:02:03] salsi at icosaedro dot it Related To: Bug #71417 ------------------------------------------------------------------------ [2017-12-09 10:47:47] salsi at icosaedro dot it Related To: Bug #71384 ------------------------------------------------------------------------ [2017-12-09 10:47:44] salsi at icosaedro dot it Bug #71384 [Opn]: fread() does not detect file access error https://bugs.php.net/bug.php?id=71384&edit=2 Maybe it worth to summarize the general issue emerged from an old thread I started back in 2016-01-21 on the developers' mailing list with subject "Severe safety fail in file access and stream filters" https://www.mail-archive.com/internals@lists.php.net/msg83033.html There, several bugs related to the I/O layer are listed involving files, sockets and filtered streams, which are still all open: + Missing error verification after fwrite() https://bugs.php.net/bug.php?id=39598 + fread() does not detects decoding errors from filter bzip2.decompress https://bugs.php.net/bug.php?id=71263 + fread() does not detect file access error https://bugs.php.net/bug.php?id=71384 + fread() does not detect decoding errors from filter zlib.inflate https://bugs.php.net/bug.php?id=71417 + require* and include* do not detect input/output error https://bugs.php.net/bug.php?id=71385 ...and maybe much more spread here and there among the libraries, possibly including data base connections and more. Yasuo Ohgaki found that the the origin of the issue has a common denominator, that is errors do not propagate from the libc to the PHP streams interface and get lost with unpredictable results: > Plain file stream reads data by php_stdiop_read() > > http://lxr.php.net/xref/PHP_5_6/main/streams/plain_wrapper.c#338 > As you can see there is no way to return errors from it. We need > errno like error handling for PHP streams to propagate errors as well > as more robust code for unexpected. Julien Pauli tells there is no a simple fix, and the whole streams library should be re-designed from scratch: > I think what we should do is sit around the table with people > interested (Daniel Lowrey may be one of them), and plan a full rewrite > of streams for PHP next major (PHP 8). ------------------------------------------------------------------------ [2017-12-07 17:15:01] ab@php.net fopen() should have failed in first place, but this check is missing in the php code. Thanks. ------------------------------------------------------------------------ [2016-01-16 15:14:30] salsi at icosaedro dot it Two sources I used to investigate this issue: - C test program, compiled with gcc under Slackware 14.1 that show how i/o error is detected reading /proc/self/mem. - PHP program that generates an ext2 disk image corrupted on pourpose on which i/o error might be tested on, as a further example. // https://bugs.php.net/bug.php?id=71384 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <unistd.h> int unbuffered() { int fd, n; char buf[10000]; fd = open("/proc/self/mem", O_RDONLY); // fd = open(__FILE__, O_RDONLY); if(fd < 0){ fprintf(stderr, "open(): %s\n", strerror(errno)); return EXIT_FAILURE; } n = read(fd, buf, 100); printf("read(): %d\n", n); if(n < 0){ fprintf(stderr, "read(): %s\n", strerror(errno)); return EXIT_FAILURE; } return (EXIT_SUCCESS); } int buffered() { FILE * f; int n; char buf[100]; f = fopen("/proc/self/mem", "r"); // f = fopen(__FILE__, "r"); if(f == NULL){ fprintf(stderr, "fopen(): %s\n", strerror(errno)); return EXIT_FAILURE; } while(1){ n = fread(buf, 1, 100, f); printf("fread(): %d\n", n); if(n <= 0){ if( ferror(f) == 0 ){ return EXIT_SUCCESS; } else { fprintf(stderr, "fread(): %s\n", strerror(errno)); return EXIT_FAILURE; } } } return EXIT_SUCCESS; } int main(int argc, char** argv) { // return unbuffered(); // Output: // read(): -1 // read(): Input/output error return buffered(); // Output: // fread(): 0 // fread() : Input / output error } <?php /** * damaged-disk.php * * Investigating https://bugs.php.net/bug.php?id=71384 * * This program creates the file "damaged-disk.img" containing the damaged * disk image of a Linux ext2 partition; the partition contains a single * file named "badfile" that can read only partially before I/O error: * * $ su * # mkdir baddisk * # mount -r damaged-disk.img baddisk * # cat baddisk/badfile * cat: baddisk/badfile: Input/output error */ $s = <<< EOT H4sICI1YmlYAA2RhbWFnZWQtZGlzawDt3TloFGEYgOF/NyvRGE3UeN/3EY3xvo23hSCIkEYb JUaEEBG1EcF4tRZ29iJiL4iVpa0gdhaCraSx0Cp+k0l01aBIjCvM88CbbJJZ9h+Yb7IzzaYE FFVz1BWNi+ZFlahUvcGivOahH2e9e9BZTgMDJ/tLg9tdf/Ogc3jT4edNjPqi7VF56PeXbs2+ 9urJ8fdP77TdPz+l/e6Y7dAv3DvV9+j25mNLn/c3djx7/KE3W1fj0N+q9+NvKv1+E6iZupTP fD7/lcF5BYphYMiNePxpACiUplovAKiV4fcB2fXvcP/y/ceH/WnwAmTH2x9fv+67a5H6f7ko CqPvZnxpr1R+Pv5Lo74Wbhnt4hhzL7LzT/tI579ymlW13fhoQtSQ8vub2X3DSdHkqCnl90en RFOjaX/w+g+z4+/lSOe/Uuqu2m56NCOaGWXrmh3Nieam/L7t/GhBtDDlt2wXVz332rHTn/9g SRRIdo5rTKVy29fH5XJbW36Mt6SGcs/Fy1dauy9e7e3Kj/nXdfWls2e6ui/0nKvpuoHRy/+X fZv/j3X5/AMFUan1AoCaMf9QXOYfisv8Q3GZfygu8w/FZf6huMw/FJf5h+Iy/1Bc5h8AAAAA AAAAAAAAAAAA/itLoqUnUloW35dHK6KV0apodbQmao3WRuui7KNB1qfBj8xKG6KN0aZoc7Ql 2hpti7ZHO6Kd0a5od7Qn2ht1RPui7KO3DkQHo0PR4ehIdHRM9xgAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKDYvgAo nTthAJABAA== EOT; file_put_contents("damaged-disk.img", gzdecode(base64_decode($s))); ?> ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=71384 -- Edit this bug report at https://bugs.php.net/bug.php?id=71384&edit=1

« previous php.bugs (#221935) next »