Bugzilla bug 106496: PR_NewTCPSocketPair should check the source of the
authorwtc%netscape.com
Wed, 23 Jan 2002 02:41:13 +0000
changeset 2185 3bc9c7516d260b57c9ffc513424750b93ff51dee
parent 2184 fdb9c6e8df5c7a94d45abba188ce1b4412a13867
child 2186 bf4948fab8b3291aca6ef95e7cf4c946eff030b1
push idunknown
push userunknown
push dateunknown
bugs106496
Bugzilla bug 106496: PR_NewTCPSocketPair should check the source of the connection.
pr/src/io/prsocket.c
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -1464,17 +1464,17 @@ failed:
         closesocket(osfd[1]);
     }
     return PR_FAILURE;
 #else /* not Unix or NT */
     /*
      * default implementation
      */
     PRFileDesc *listenSock;
-    PRNetAddr selfAddr;
+    PRNetAddr selfAddr, peerAddr;
     PRUint16 port;
 
     f[0] = f[1] = NULL;
     listenSock = PR_NewTCPSocket();
     if (listenSock == NULL) {
         goto failed;
     }
     PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
@@ -1502,30 +1502,46 @@ failed:
      * This is the behavior of the BSD socket code.  If
      * connect does not return until accept is called, we
      * will need to create another thread to call connect.
      */
     if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
             == PR_FAILURE) {
         goto failed;
     }
-    f[1] = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket f[0].
+     */
+    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
     if (f[1] == NULL) {
         goto failed;
     }
+    if (peerAddr.inet.port != selfAddr.inet.port) {
+        /* the connection we accepted is not from f[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
     PR_Close(listenSock);
     return PR_SUCCESS;
 
 failed:
     if (listenSock) {
         PR_Close(listenSock);
     }
     if (f[0]) {
         PR_Close(f[0]);
     }
+    if (f[1]) {
+        PR_Close(f[1]);
+    }
     return PR_FAILURE;
 #endif
 }
 
 PR_IMPLEMENT(PRInt32)
 PR_FileDesc2NativeHandle(PRFileDesc *fd)
 {
     if (fd) {