kern/167612: [portalfs] The portal file system gets stuck inside portal_open(). ("1 extra fds")

Jukka A. Ukkonen jau at iki.fi
Thu May 10 15:40:13 UTC 2012


The following reply was made to PR kern/167612; it has been noted by GNATS.

From: "Jukka A. Ukkonen" <jau at iki.fi>
To: bug-followup at FreeBSD.org, jau at iki.fi
Cc:  
Subject: kern/167612: [portalfs] The portal file system gets stuck inside
 portal_open(). ("1 extra fds")
Date: Thu, 10 May 2012 18:33:49 +0300

 This is a multi-part message in MIME format.
 --------------060204070501010607040700
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 
 This really was an alignment issue.
 
 The old code was not in sync with the alignment done in
 
 the CMSG_* macros.
 
 
 Find a patch attached.
 
 --jau
 
 
 
 --------------060204070501010607040700
 Content-Type: text/plain; charset=UTF-8;
  name="portal_vnops.c.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="portal_vnops.c.diff"
 
 --- portal_vnops.c.orig	2012-05-08 18:43:17.000000000 +0300
 +++ portal_vnops.c	2012-05-10 17:07:55.000000000 +0300
 @@ -397,19 +397,47 @@
  	 * than a single mbuf in it.  What to do?
  	 */
  	cmsg = mtod(cm, struct cmsghdr *);
 -	newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int);
 +
 +	/*
 +	 * Just in case the sender no longer does what we expect
 +	 * and sends something else before or in the worst case
 +	 * instead of the file descriptor we expect...
 +	 */
 +
 +	if ((cmsg->cmsg_level != SOL_SOCKET)
 +	    || (cmsg->cmsg_type != SCM_RIGHTS)) {
 +		error = ECONNREFUSED;
 +		goto bad;
 +	}
 +
 +	/*
 +	 * Use the flippin' CMSG_DATA() macro to make sure we use
 +	 * the same alignment as the sender.
 +	 * Otherwise things go pear shape very easily.
 +	 * The bad news is that even faulty code may work on some
 +	 * CPU architectures.
 +	 */
 +
 +	ip = (int *) CMSG_DATA (cmsg);
 +
 +	newfds = (cmsg->cmsg_len - 
 +		  ((unsigned char *) ip -
 +		   (unsigned char *) cmsg)) / sizeof (int);
 +
  	if (newfds == 0) {
  		error = ECONNREFUSED;
  		goto bad;
  	}
 +
  	/*
  	 * At this point the rights message consists of a control message
  	 * header, followed by a data region containing a vector of
  	 * integer file descriptors.  The fds were allocated by the action
  	 * of receiving the control message.
  	 */
 -	ip = (int *) (cmsg + 1);
 +
  	fd = *ip++;
 +
  	if (newfds > 1) {
  		/*
  		 * Close extra fds.
 
 --------------060204070501010607040700--


More information about the freebsd-fs mailing list