On Tue, Jul 18, 2017 at 09:03:00AM +0200, Martin Pieuchot wrote:
> Diff below extends the scope of the socket lock.  It has been previously
> introduced in sys_connect(), first as NET_LOCK() then renamed, where old
> splsofnet() were used.  But we now need to "move the line up" in order to
> protect fields currently relying on the KERNEL_LOCK().

We were also discussing to move the lock down to the network stack.
Eventually we need locks for the sockets and a lock for the stack.
The first must move up and the latter down.  As we have only one
lock at the moment, I am fine with the upward direction for now.

> Moving the line up means that soconnect() and soconnect2() will now
> assert for the socket lock.

The soconnect2() is only used for local sockets that run with the
kernel lock.  So we could not lock this function.  I guess your
goal is per socket locks, so your change is fine.

> @@ -373,9 +373,10 @@ sys_connect(struct proc *p, void *v, reg
>       if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       so = fp->f_data;
> +     s = solock(so);
>       if (so->so_state & SS_ISCONNECTING) {
> -             FRELE(fp, p);
> -             return (EALREADY);
> +             error = EALREADY;
> +             goto out;
>       }
>       error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
>           MT_SONAME);
> @@ -393,11 +394,8 @@ sys_connect(struct proc *p, void *v, reg
>       if (isdnssocket(so)) {
>               u_int namelen = nam->m_len;
>               error = dns_portcheck(p, so, mtod(nam, void *), &namelen);
> -             if (error) {
> -                     FRELE(fp, p);
> -                     m_freem(nam);
> -                     return (error);
> -             }
> +             if (error)
> +                     goto out;
>               nam->m_len = namelen;
>       }
>  

Now we have a mixture fo goto bad and goto out.  I think everything
before soconnect() should goto out.  Please change the error handling
of sockargs() and pledge_socket() to goto out.

> @@ -135,6 +135,11 @@ fifo_open(void *v)
>                       return (error);
>               }
>               fip->fi_readsock = rso;
> +             /*
> +              * XXXSMP
> +              * We only lock `wso' because AF_LOCAL sockets are
> +              * still relying on the KERNEL_LOCK().
> +              */
>               if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0)) != 0) {
>                       (void)soclose(rso);
>                       free(fip, M_VNODE, sizeof *fip);

Could you move this comment before the solock(wso) line?

> @@ -168,11 +179,12 @@ fifo_open(void *v)
>                       goto bad;
>               }
>               if (fip->fi_writers == 1) {
> -                     fip->fi_readsock->so_state &= 
> ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
> +                     rso->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
>                       if (fip->fi_readers > 0)
>                               wakeup(&fip->fi_readers);
>               }
>       }
> +     sounlock(s);
>       if ((ap->a_mode & O_NONBLOCK) == 0) {
>               if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
>                       VOP_UNLOCK(vp, p);

The goto bad after error = ENXIO has no sounlock().

bluhm

Reply via email to