Subject: Re: [PATCH net-next] sockopt: Change getsockopt() of SO_BINDTODEVICE to return an interface name

From: Pavel Emelyanov <[email-masked]>
Date: Fri, 02 Nov 2012 13:36:11 +0400

> +static int sock_getbindtodevice(struct sock *sk, char __user *optval,
> +				int __user *optlen, int len)
> +{
> +	int ret = -ENOPROTOOPT;
> +#ifdef CONFIG_NETDEVICES
> +	struct net *net = sock_net(sk);
> +	struct net_device *dev;
> +	char devname[IFNAMSIZ];
> +
> +	if (sk->sk_bound_dev_if == 0) {
> +		len = 0;
> +		goto zero;
> +	}
> +
> +	ret = -EINVAL;
> +	if (len < IFNAMSIZ)
> +		goto out;
> +
> +	rcu_read_lock();
> +	dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
> +	if (dev)
> +		strcpy(devname, dev->name);

This still races with the device name change, potentially providing
a name which never existed in the system, doesn't it?

> +	rcu_read_unlock();
> +	ret = -ENODEV;
> +	if (!dev)
> +		goto out;
> +
> +	len = strlen(devname) + 1;
> +
> +	ret = -EFAULT;
> +	if (copy_to_user(optval, devname, len))
> +		goto out;
> +
> +zero:
> +	ret = -EFAULT;
> +	if (put_user(len, optlen))
> +		goto out;
> +
> +	ret = 0;
> +
> +out:
> +#endif
> +
> +	return ret;
> +}

Thanks,
Pavel