diff options
Diffstat (limited to 'drivers/net/tap.c')
| -rw-r--r-- | drivers/net/tap.c | 25 | 
1 files changed, 14 insertions, 11 deletions
| diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 21b71ae947fd..6c0c84c33e1f 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -517,6 +517,10 @@ static int tap_open(struct inode *inode, struct file *file)  					     &tap_proto, 0);  	if (!q)  		goto err; +	if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) { +		sk_free(&q->sk); +		goto err; +	}  	RCU_INIT_POINTER(q->sock.wq, &q->wq);  	init_waitqueue_head(&q->wq.wait); @@ -540,22 +544,18 @@ static int tap_open(struct inode *inode, struct file *file)  	if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG))  		sock_set_flag(&q->sk, SOCK_ZEROCOPY); -	err = -ENOMEM; -	if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) -		goto err_array; -  	err = tap_set_queue(tap, file, q); -	if (err) -		goto err_queue; +	if (err) { +		/* tap_sock_destruct() will take care of freeing skb_array */ +		goto err_put; +	}  	dev_put(tap->dev);  	rtnl_unlock();  	return err; -err_queue: -	skb_array_cleanup(&q->skb_array); -err_array: +err_put:  	sock_put(&q->sk);  err:  	if (tap) @@ -1032,6 +1032,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd,  	case TUNSETSNDBUF:  		if (get_user(s, sp))  			return -EFAULT; +		if (s <= 0) +			return -EINVAL;  		q->sk.sk_sndbuf = s;  		return 0; @@ -1249,8 +1251,8 @@ static int tap_list_add(dev_t major, const char *device_name)  	return 0;  } -int tap_create_cdev(struct cdev *tap_cdev, -		    dev_t *tap_major, const char *device_name) +int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major, +		    const char *device_name, struct module *module)  {  	int err; @@ -1259,6 +1261,7 @@ int tap_create_cdev(struct cdev *tap_cdev,  		goto out1;  	cdev_init(tap_cdev, &tap_fops); +	tap_cdev->owner = module;  	err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS);  	if (err)  		goto out2; |