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 (profile)
Status: Closed Package: *General Issues
PHP Version: 4.3.3 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mattias at sudac dot org
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 02:01:28 2024 UTC