Re: [PATCH 4/5] AF_UNIX: find peers on multicast Unix streamsockets

From: Eric Dumazet
Date: Fri Sep 24 2010 - 14:00:50 EST


Le vendredi 24 septembre 2010 Ã 18:25 +0100, Alban Crequy a Ãcrit :

> @@ -1612,7 +1671,12 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
> } else {
> sunaddr = NULL;
> err = -ENOTCONN;
> - other = NULL; /* FIXME: get the list of other connection */
> + max_others = atomic_read(&unix_nr_multicast_socks);
> + others = kzalloc((max_others + 1) * sizeof(void *), GFP_KERNEL);
> + unix_find_other(sock_net(sk), u->addr->name,
> + u->addr->len, 0, u->addr->hash, 1, others, max_others, &err);
> + other = others[0];
> + kfree(others);
> if (!other)
> goto out_err;
> }

Seriously, this block sizing against unix_nr_multicast_socks is not
scalable. What happens if we have 1000 sockets ?
kzalloc() to clear 8000 bytes ?
Its also unsafe.

(say you kzalloc() a buffer for 2 sockets, and another cpu inserts a new
socket. unix_find_socket_byname() can overflow the buffer)


You should use a list, and allocates elements in
unix_find_socket_byname()

struct item {
struct item *next;
struct sock *s;
};


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/