php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #7290 AF_UNIX connect segfaults + sockets.c read is not binary safe (why?)
Submitted: 2000-10-17 13:46 UTC Modified: 2001-06-02 20:59 UTC
From: gp at iws dot it Assigned:
Status: Closed Package: Sockets related
PHP Version: 4.0.3pl1 OS: Any
Private report: No CVE-ID: None
 [2000-10-17 13:46 UTC] gp at iws dot it
I patched php-4.0.4pl1/ext/sockets/sockets.c
in order to solve these problems.
If you want I can send you the patch.
I will be happy to use PHP but it has severe
problems with sockets (fsockopen , fread etc. dont behave well).


Thank you

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-10-19 09:51 UTC] gp at iws dot it
I apologize if my arguments are not pertinent. Hope to not bother anybody. I'm a php newbie.

I attach below  the patch I made to fix the problems I found. I added a function named readfully in order to have
a php function able to read exactly n bytes from a 
stream. I think it is wery useful to have one. 


Cheers,

diff -u php-4.0.3pl1/ext/sockets/php_sockets.h php-4.0.3pl1-gp1/ext/sockets/php_sockets.h
--- php-4.0.3pl1/ext/sockets/php_sockets.h	Thu Sep  7 14:32:47 2000
+++ php-4.0.3pl1-gp1/ext/sockets/php_sockets.h	Thu Oct 19 15:10:22 2000
@@ -49,6 +49,7 @@
 PHP_FUNCTION(close);
 PHP_FUNCTION(write);
 PHP_FUNCTION(read);
+PHP_FUNCTION(readfully);
 PHP_FUNCTION(getsockname);
 PHP_FUNCTION(getpeername);
 PHP_FUNCTION(socket);
diff -u php-4.0.3pl1/ext/sockets/sockets.c php-4.0.3pl1-gp1/ext/sockets/sockets.c
--- php-4.0.3pl1/ext/sockets/sockets.c	Sat Sep 16 01:44:30 2000
+++ php-4.0.3pl1-gp1/ext/sockets/sockets.c	Thu Oct 19 15:14:26 2000
@@ -27,6 +27,7 @@
 #include "ext/standard/info.h"
 #include "php_sockets.h"
 
+#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -91,7 +92,8 @@
 	PHP_FE(listen, 				NULL)	/* OK */
 	PHP_FE(close, 				NULL)	/* OK */
 	PHP_FE(write, 				NULL)	/* OK */
-	PHP_FE(read, 				second_arg_force_ref)	/* OK */+	PHP_FE(read,                         second_arg_force_ref)	/* OK */+	PHP_FE(readfully,                    second_arg_force_ref)	/* OK */ #if 0
 /* 
  * If and when asynchronous context switching is avaliable, 
@@ -646,6 +648,70 @@
 }
 /* }}} */
 
+/* G.Gallo - gp@iws.it - 20001017
+ * The two following function are the implementation of 
+ * a binary safe read from a socket. It is modeled after
+ * the readFully java method.
+ */
+size_t 
+_php_readfully(int fd, char *buf, size_t len) {
+    struct timeval tv;
+    fd_set rfds;
+    size_t n;
+    char *pb = buf;
+
+    tv.tv_sec = 600;
+    tv.tv_usec = 0;
+    FD_ZERO(&rfds);
+    FD_SET(fd, &rfds);
+    while (len) {
+        if (select(fd + 1, &rfds, NULL, NULL, &tv) == -1)
+            return -2;
+        if (FD_ISSET(fd, &rfds)) {
+            if ((n = read(fd, pb, len)) < 0 || (n == 0 && len > 0))
+                return -1;
+            len -= n;
+            pb += n;
+        } else
+            return -1;
+    }
+    return 0;
+}
+PHP_FUNCTION(readfully)
+{
+	zval **fd, **buf, **length;
+	char *tmpbuf;
+	int ret,rc;
+
+	if (ZEND_NUM_ARGS() != 3 || 
+	    zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
+		WRONG_PARAM_COUNT;
+	}
+	v_convert_to_long_ex(2, fd, length);
+	convert_to_string_ex(buf);+
+	tmpbuf = emalloc(Z_LVAL_PP(length)*sizeof(char));
+	if (tmpbuf == NULL) {
+		php_error(E_WARNING, "Couldn't allocate memory from %s()", get_active_function_name());
+		RETURN_FALSE;
+	}
+	
+	rc = _php_readfully(Z_LVAL_PP(fd), tmpbuf, ret = Z_LVAL_PP(length));
+	if (rc == 0) {
+		Z_STRVAL_PP(buf) = emalloc(ret * sizeof(char));
+		memcpy(Z_STRVAL_PP(buf),tmpbuf,ret);
+		Z_STRLEN_PP(buf) = ret;
+		
+		efree(tmpbuf);
+
+		RETURN_LONG(ret);
+	} else {
+		efree(tmpbuf);
+		RETURN_LONG(-errno);
+	}
+}
+/* }}} */
+
 /* {{{ proto int getsockname(int fd, string &addr, int &port)
    Given an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the local side of a socket */
 
@@ -931,9 +997,11 @@
 			break;
 		}
 	case AF_UNIX: {
-			sun = (struct sockaddr_un *)&sa;
-			snprintf(sun->sun_path, 108, "%s", Z_STRVAL_PP(addr));
-			ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) sun, SUN_LEN(sun));
+                        struct sockaddr_un sun;
+                        memset((char *)&sun,0,sizeof(sun));
+                        sun.sun_family = AF_UNIX;
+                        strncpy(sun.sun_path,Z_STRVAL_PP(addr),108);
+			ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) &sun, SUN_LEN(&sun));
 			break;
 	}
 	default:

 [2001-06-02 20:59 UTC] sniper@php.net
This should be fixed with PHP 4.0.6, please try the 
latest release candidate:

http://www.php.net/~andi/php-4.0.6RC2.tar.gz

And note that using the undocumented 4th parameter
will make it behave like the system read():

read($sock, $buff, $length, PHP_BINARY_READ)

-Jani

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 01:01:28 2024 UTC