Subject: Re: race in skb_splice_bits?

From: Ben Hutchings <[email-masked]>
Date: Tue, 27 May 2008 12:08:41 +0100

Evgeniy Polyakov wrote:
> On Tue, May 27, 2008 at 03:25:23AM +0300, Octavian Purdila ([email-masked]) wrote:
> >
> > Hi,
> >
> > The following socket lock dropping in skb_splice_bits seems to open a race
> > condition which causes an invalid kernel access:
> >
> > >        if (spd.nr_pages) {
> > >                int ret;
> > >
> > >                /*
> > >                 * Drop the socket lock, otherwise we have reverse
> > >                 * locking dependencies between sk_lock and i_mutex
> > >                 * here as compared to sendfile(). We enter here
> > >                 * with the socket lock held, and splice_to_pipe() will
> > >                 * grab the pipe inode lock. For sendfile() emulation,
> > >                 * we call into ->sendpage() with the i_mutex lock held
> > >                 * and networking will grab the socket lock.
> > >                 */
>
> What about sock_hold() here?
> It will prevent from socket freeing and read/write to it will
> immediately return with error if socket was closed by another thread.
<snip>

We know the socket isn't going to go away because somewhere up the call
stack someone has to be holding the socket in order to lock it.  However,
the skb may (and evidently sometimes does) go away during splice_to_pipe()
so we can't look up the socket through it.

However, from Octavian's later mail it seems we can't let the skb go away
at all.  So some wider changes seem to be required.

Ben.

--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.