Date: Thu, 10 May 2012 15:40:13 GMT From: "Jukka A. Ukkonen" <jau@iki.fi> To: freebsd-fs@FreeBSD.org Subject: kern/167612: [portalfs] The portal file system gets stuck inside portal_open(). ("1 extra fds") Message-ID: <201205101540.q4AFeDdX067834@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/167612; it has been noted by GNATS. From: "Jukka A. Ukkonen" <jau@iki.fi> To: bug-followup@FreeBSD.org, jau@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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205101540.q4AFeDdX067834>