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);
>> }
>
>