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

Reply via email to