On Fri, Jan 30, 2015 at 02:34:42PM -0700, Todd C. Miller wrote:
> I think the simplest fix is to just move the m_free to the bad:
> label.
sosetopt() calls m_free() and then it is called again. So it is a
double free.
I would move the so->so_proto check between the if (name == -1) and
the if (lsa.optlen > MLEN) block. There m has not been allocated.
Untested as I do not have an i386 right now.
bluhm
Index: sys/compat/linux/linux_socket.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/compat/linux/linux_socket.c,v
retrieving revision 1.59
diff -u -p -r1.59 linux_socket.c
--- sys/compat/linux/linux_socket.c 21 Jan 2015 13:47:45 -0000 1.59
+++ sys/compat/linux/linux_socket.c 30 Jan 2015 21:51:05 -0000
@@ -962,6 +962,14 @@ linux_setsockopt(p, v, retval)
error = EINVAL;
goto bad;
}
+ so = (struct socket *)fp->f_data;
+ if (so->so_proto && level == IPPROTO_TCP && name == TCP_NODELAY &&
+ so->so_proto->pr_domain->dom_family == AF_LOCAL &&
+ so->so_proto->pr_protocol == PF_LOCAL) {
+ /* ignore it */
+ error = 0;
+ goto bad;
+ }
if (lsa.optlen > MLEN) {
error = EINVAL;
goto bad;
@@ -974,14 +982,6 @@ linux_setsockopt(p, v, retval)
goto bad;
}
m->m_len = lsa.optlen;
- }
- so = (struct socket *)fp->f_data;
- if (so->so_proto && level == IPPROTO_TCP && name == TCP_NODELAY &&
- so->so_proto->pr_domain->dom_family == AF_LOCAL &&
- so->so_proto->pr_protocol == PF_LOCAL) {
- /* ignore it */
- error = 0;
- goto bad;
}
error = sosetopt(so, level, name, m);
bad: