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