On Fri, Jan 30, 2015 at 03:57:12PM -0700, Todd C. Miller wrote: > On Fri, 30 Jan 2015 22:55:06 +0100, Alexander Bluhm wrote: > > > sosetopt() calls m_free() and then it is called again. So it is a > > double free. > > Whoops, I didn't notice that the non-error case also falls thought > to the "bad" label. We could just do what sys_setsockopt() does > and zero out m after calling sosetopt().
Let's take this fix. OK bluhm@ > > - todd > > Index: sys/compat/linux/linux_socket.c > =================================================================== > RCS file: /cvs/src/sys/compat/linux/linux_socket.c,v > retrieving revision 1.59 > diff -u -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 22:56:40 -0000 > @@ -969,10 +969,8 @@ > if (lsa.optval != NULL) { > m = m_get(M_WAIT, MT_SOOPTS); > error = copyin(lsa.optval, mtod(m, caddr_t), lsa.optlen); > - if (error) { > - (void) m_free(m); > + if (error) > goto bad; > - } > m->m_len = lsa.optlen; > } > so = (struct socket *)fp->f_data; > @@ -984,7 +982,10 @@ > goto bad; > } > error = sosetopt(so, level, name, m); > + m = NULL; > bad: > + if (m) > + m_free(m); > FRELE(fp, p); > return (error); > }