FWIW, it would be wise to propagate the fix to the stable branch(es). I guess people use compat-linux.
Le 31/01/2015 00:33, Alexander Bluhm a écrit : > 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); >> } > >