*             - if started by zero, it is abstract name.
  */
 
+static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
+{
+       if (addr_len <= offsetof(struct sockaddr_un, sun_path) ||
+           addr_len > sizeof(*sunaddr))
+               return -EINVAL;
+
+       if (sunaddr->sun_family != AF_UNIX)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
 {
        *hashp = 0;
 
-       if (len <= offsetof(struct sockaddr_un, sun_path) ||
-           len > sizeof(*sunaddr))
-               return -EINVAL;
-       if (!sunaddr || sunaddr->sun_family != AF_UNIX)
-               return -EINVAL;
        if (sunaddr->sun_path[0]) {
                /*
                 * This may look like an off by one error but it is a bit more
        unsigned int hash;
        struct unix_address *addr;
 
-       if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
-           sunaddr->sun_family != AF_UNIX)
-               return -EINVAL;
-
-       if (addr_len == offsetof(struct sockaddr_un, sun_path))
+       if (addr_len == offsetof(struct sockaddr_un, sun_path) &&
+           sunaddr->sun_family == AF_UNIX)
                return unix_autobind(sk);
 
+       err = unix_validate_addr(sunaddr, addr_len);
+       if (err)
+               return err;
+
        err = unix_mkname(sunaddr, addr_len, &hash);
        if (err < 0)
                return err;
                goto out;
 
        if (addr->sa_family != AF_UNSPEC) {
+               err = unix_validate_addr(sunaddr, alen);
+               if (err)
+                       goto out;
+
                err = unix_mkname(sunaddr, alen, &hash);
                if (err < 0)
                        goto out;
        int err;
        long timeo;
 
+       err = unix_validate_addr(sunaddr, addr_len);
+       if (err)
+               goto out;
+
        err = unix_mkname(sunaddr, addr_len, &hash);
        if (err < 0)
                goto out;
                goto out;
 
        if (msg->msg_namelen) {
+               err = unix_validate_addr(sunaddr, msg->msg_namelen);
+               if (err)
+                       goto out;
+
                err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
                if (err < 0)
                        goto out;