Date:

Thu Oct 5 13:56:46 PDT 1995

Description

Misbehaving clients who don't adhere to protocol (e.g. someone telneting to the postmaster port and typing in garbage characters) can crash the postmaster.

The patch below helps alleviate the problem. Thanks to Robert Patrick (rp2y+@cs.cmu.edu) for supplying the fix, and Henning Schmiedehausen for discovering the problem.

Fix

Apply this patch.

===================================================================
RCS file: /usr/local/devel/pglite/cvs/src/backend/include/postgres.h,v
retrieving revision 1.7
diff -c -r1.7 postgres.h
*** 1.7	1995/05/02 00:03:44
--- src/backend/include/postgres.h	1995/10/05 18:53:01
***************
*** 558,563 ****
--- 558,564 ----
  #define STATUS_UNCATALOGUED     (-4)
  #define STATUS_REPLACED         (-5)
  #define STATUS_NOT_DONE		(-6)
+ #define STATUS_BAD_PACKET	(-7)
  #define STATUS_FOUND            (1)
  
  /*
===================================================================
RCS file: /usr/local/devel/pglite/cvs/src/backend/libpq/pqpacket.c,v
retrieving revision 1.9
diff -c -r1.9 pqpacket.c
*** 1.9	1995/07/11 20:56:42
--- src/backend/libpq/pqpacket.c	1995/10/05 18:55:48
***************
*** 67,72 ****
--- 67,73 ----
  	      PacketBuf *buf,   /* MAX_PACKET_SIZE-worth of buffer space */
  	      bool nonBlocking) /* NON_BLOCKING or BLOCKING i/o */
  {
+     PacketLen   max_size = sizeof(PacketBuf);
      PacketLen	cc;	    	/* character count -- bytes recvd */
      PacketLen	packetLen; 	/* remaining packet chars to read */
      Addr	tmp;	   	/* curr recv buf pointer */
***************
*** 97,104 ****
      }
       else {
        /* peeking into the incoming message */
! 	cc = recvfrom(port->sock, &(buf->len), hdrLen, flag, 
! 		      (struct sockaddr*) &(port->raddr), &addrLen);
  	if (cc < hdrLen) {
  	    /* if cc is negative, the system call failed */
  	    if (cc < 0) {
--- 98,105 ----
      }
       else {
        /* peeking into the incoming message */
!        cc = recvfrom(port->sock, (char *)&(buf->len), hdrLen, flag, 
!                       (struct sockaddr*) &(port->raddr), &addrLen);
  	if (cc < hdrLen) {
  	    /* if cc is negative, the system call failed */
  	    if (cc < 0) {
***************
*** 130,135 ****
--- 131,143 ----
  	     * header size).
  	     */
  	    packetLen = ntohl(buf->len);
+            /*
+             * if someone is sending us junk, close the connection
+             */
+            if (packetLen > max_size) {
+                port->nBytes = packetLen;
+                return(STATUS_BAD_PACKET);
+            }
  	    packetLen -= decr;
  	    tmp += decr - port->nBytes;
  	}
===================================================================
RCS file: /usr/local/devel/pglite/cvs/src/backend/postmaster/postmaster.c,v
retrieving revision 1.22
diff -c -r1.22 postmaster.c
*** 1.22	1995/10/04 04:17:17
--- src/backend/postmaster/postmaster.c	1995/10/05 18:58:44
***************
*** 481,486 ****
--- 481,494 ----
  			fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n",
  				progname, port->sock);
  		    break;
+                case STATUS_BAD_PACKET:
+                    /*
+                     * This is a bogus client, kill the connection 
+                     * and forget the whole thing.
+                     */
+                    if (DebugLvl)
+                        fprintf(stderr, "%s: ServerLoop:\t\tbad packet format (reported packet size of %d read on port %d\n", progname, port->nBytes, port->sock);
+                    break;
  		case STATUS_NOT_DONE:
  		    if (DebugLvl)
  			fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n",