On Thu,  3 Dec 2020 11:18:44 +0300 Denis Kirjanov wrote:
> in the case of a socket which is already bound to an adress
> there is no sense to create a path in the next attempts

> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 41c3303c3357..489d49a1739c 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1029,6 +1029,16 @@ static int unix_bind(struct socket *sock, struct 
> sockaddr *uaddr, int addr_len)
>               goto out;
>       }
>  
> +     /* check if we're already bound to a path */
> +     err = mutex_lock_interruptible(&u->bindlock);
> +     if (err)
> +             goto out;
> +     if (u->addr)
> +             err = -EINVAL;
> +     mutex_unlock(&u->bindlock);

This, like v1, is not atomic with the creation, two threads can pass
this check and then try to assign to u->addr.

Naive question - can't we add the removal of the unnecessary node in
the error path, in the kernel?

> +     if (err)
> +             goto out;
> +
>       err = unix_mkname(sunaddr, addr_len, &hash);
>       if (err < 0)
>               goto out;
> @@ -1049,10 +1059,6 @@ static int unix_bind(struct socket *sock, struct 
> sockaddr *uaddr, int addr_len)
>       if (err)
>               goto out_put;
>  
> -     err = -EINVAL;
> -     if (u->addr)
> -             goto out_up;
> -
>       err = -ENOMEM;
>       addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
>       if (!addr)

Reply via email to