php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #26158 Open arbitrary file descriptor with fopen
Submitted: 2003-11-06 20:26 UTC Modified: 2010-12-11 02:55 UTC
From: mattias at sudac dot org Assigned: cataphract
Status: Closed Package: *General Issues
PHP Version: 4.3.3 OS: Linux
Private report: No CVE-ID:
 [2003-11-06 20:26 UTC] mattias at sudac dot org
Description:
------------
On some operating systems (BSD?) it is possible to open a arbitrary file descriptor with fopen like this:
fopen("/dev/fd/<fd>", "r");
But on at least Linux this fails. So here is patch that makes it possible to open fd:s by useing fopen("php://<fd>", "r").

in ext/standard/php_fopen_wrapper.c:php_stream_url_wrap_php add two lines:
 } else if (!strcasecmp(path, "stderr")) {
      fd = STDERR_FILENO;
+} else
+     fd = atoi(path);

Maybe some checks are needed.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-11-07 06:44 UTC] wez@php.net
Why does fopen("/dev/fd/x", "r") fail ?

 [2003-11-07 07:46 UTC] mattias at sudac dot org
It seams to work if the file descriptor is a pipe, but it fails on network sockets.

Example:

testfd.php:
#!/usr/local/bin/php -q
<?php

echo `ls -l /dev/fd/`;

$stdin = fopen('/dev/fd/0', 'r');
$stdout = fopen('/dev/fd/1', 'w');

?>

Server:
tcpserver 127.0.0.1 8000 ./testfd.php

Client:
mattias@icebox:~$ nc localhost 8000
total 0
lrwx------    1 mattias  mattias        64 2003-11-07 13:35 0 -> socket:[2611215]
l-wx------    1 mattias  mattias        64 2003-11-07 13:35 1 -> pipe:[2611234]
lrwx------    1 mattias  mattias        64 2003-11-07 13:35 2 -> /dev/pts/3
lr-x------    1 mattias  mattias        64 2003-11-07 13:35 3 -> /proc/12706/fd
lrwx------    1 mattias  mattias        64 2003-11-07 13:35 4 -> socket:[2611215]
lrwx------    1 mattias  mattias        64 2003-11-07 13:35 5 -> socket:[2611215]
lrwx------    1 mattias  mattias        64 2003-11-07 13:35 6 -> /dev/pts/3

Warning: fopen(/dev/fd/0): failed to open stream: No such device or address in /home/mattias/projects/jssocket/tests/testfd on line 6

Warning: fopen(/dev/fd/1): failed to open stream: No such device or address in /home/mattias/projects/jssocket/tests/testfd on line 7


If we run the script without tcpserver we get this:

mattias@icebox:~$ ./testfd
total 0
lrwx------    1 mattias  mattias        64 2003-11-07 13:37 0 -> /dev/pts/3
l-wx------    1 mattias  mattias        64 2003-11-07 13:37 1 -> pipe:[2611379]
lrwx------    1 mattias  mattias        64 2003-11-07 13:37 2 -> /dev/pts/3
lr-x------    1 mattias  mattias        64 2003-11-07 13:37 3 -> /proc/12709/fd
lrwx------    1 mattias  mattias        64 2003-11-07 13:37 4 -> /dev/pts/3
lrwx------    1 mattias  mattias        64 2003-11-07 13:37 5 -> /dev/pts/3
lrwx------    1 mattias  mattias        64 2003-11-07 13:37 6 -> /dev/pts/3


Notice the difference, also notice that /dev/fd is a symlink  to /proc/self/fd:
mattias@icebox:~$ ls -l /dev/fd
lrwxrwxrwx    1 root     root           13 2001-12-21 18:29 /dev/fd -> /proc/self/fd


This is on Debian unstable, Linux 2.4.21. I noticed this when i moved a script from FreeBSD 4.8 to Linux.
 [2003-11-21 11:16 UTC] mattias at sudac dot org
I think this is unrelated to PHP and very Linux specific, I wrote a C prgoram and run it with tcpserver on FreeBSD and Linux. On FreeBSD it works fine, but on Linux i get this error:
open in: No such device or address
open out: No such device or address

I also found this, so maybe this is solved in Linux 2.6?
http://www.geocrawler.com/mail/msg.php3?msg_id=3374944&list=35

#include <unistd.h>                                                                   #include <sys/types.h>                                                                #include <sys/stat.h>                                                                 #include <fcntl.h>                                                                    
int main()
{
    int in;
    int out;
    
    in = open("/dev/fd/0", O_RDONLY);
    if(in == -1)
        perror("open in");
    
    out = open("/dev/fd/1", O_WRONLY);
    if(out == -1)
        perror("open out");

    if(out != -1)
        write(out, "test\n", 5);
    
    return 0;
}
 [2007-07-24 15:38 UTC] jani@php.net
Linux bugs are not PHP bugs..
 [2010-12-11 02:52 UTC] cataphract@php.net
Automatic comment from SVN on behalf of cataphract
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=306215
Log: - Implemented request #26158/bug #53465 (open arbitrary file descriptor with fopen)
 [2010-12-11 02:55 UTC] cataphract@php.net
-Status: Bogus +Status: Closed -Package: Feature/Change Request +Package: *General Issues -Assigned To: +Assigned To: cataphract
 [2010-12-11 02:55 UTC] cataphract@php.net
Marking as closed as this was implemented for 5.3/trunk.

See also bug #53465.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 15:02:26 2014 UTC