aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-01-20 06:00:40 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 19:00:44 -0500
commit631ab46b79559d6fed784fd7883c0cda4d8cfcfa (patch)
tree8f78e43c4b5adf223254da3315f4957ac629a38a /drivers
parenteac9e902658dab1e097b8ef064e9e3d16c152cc9 (diff)
tun: Introduce tun_file
Currently the tun code suffers from only having a single word of data that exists for the entire life of the tun file descriptor. This results in peculiar holding of references to the network namespace as well as races between free_netdevice and tun_chr_close. Fix this by introducing tun_file which will hold the per file state. For the moment it still holds just a single word so the differences are all logic changes with no changes in semantics. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tun.c156
1 files changed, 104 insertions, 52 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8743de9d2572..d3a665d2f7b8 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -87,9 +87,13 @@ struct tap_filter {
87 unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; 87 unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
88}; 88};
89 89
90struct tun_file {
91 struct tun_struct *tun;
92};
93
90struct tun_struct { 94struct tun_struct {
95 struct tun_file *tfile;
91 unsigned int flags; 96 unsigned int flags;
92 int attached;
93 uid_t owner; 97 uid_t owner;
94 gid_t group; 98 gid_t group;
95 99
@@ -108,14 +112,15 @@ struct tun_struct {
108 112
109static int tun_attach(struct tun_struct *tun, struct file *file) 113static int tun_attach(struct tun_struct *tun, struct file *file)
110{ 114{
115 struct tun_file *tfile = file->private_data;
111 const struct cred *cred = current_cred(); 116 const struct cred *cred = current_cred();
112 117
113 ASSERT_RTNL(); 118 ASSERT_RTNL();
114 119
115 if (file->private_data) 120 if (tfile->tun)
116 return -EINVAL; 121 return -EINVAL;
117 122
118 if (tun->attached) 123 if (tun->tfile)
119 return -EBUSY; 124 return -EBUSY;
120 125
121 /* Check permissions */ 126 /* Check permissions */
@@ -124,13 +129,41 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
124 !capable(CAP_NET_ADMIN)) 129 !capable(CAP_NET_ADMIN))
125 return -EPERM; 130 return -EPERM;
126 131
127 file->private_data = tun; 132 tfile->tun = tun;
128 tun->attached = 1; 133 tun->tfile = tfile;
129 get_net(dev_net(tun->dev)); 134 get_net(dev_net(tun->dev));
130 135
131 return 0; 136 return 0;
132} 137}
133 138
139static void __tun_detach(struct tun_struct *tun)
140{
141 struct tun_file *tfile = tun->tfile;
142
143 /* Detach from net device */
144 tfile->tun = NULL;
145 tun->tfile = NULL;
146 put_net(dev_net(tun->dev));
147
148 /* Drop read queue */
149 skb_queue_purge(&tun->readq);
150}
151
152static struct tun_struct *__tun_get(struct tun_file *tfile)
153{
154 return tfile->tun;
155}
156
157static struct tun_struct *tun_get(struct file *file)
158{
159 return __tun_get(file->private_data);
160}
161
162static void tun_put(struct tun_struct *tun)
163{
164 /* Noop for now */
165}
166
134/* TAP filterting */ 167/* TAP filterting */
135static void addr_hash_set(u32 *mask, const u8 *addr) 168static void addr_hash_set(u32 *mask, const u8 *addr)
136{ 169{
@@ -261,7 +294,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
261 DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len); 294 DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
262 295
263 /* Drop packet if interface is not attached */ 296 /* Drop packet if interface is not attached */
264 if (!tun->attached) 297 if (!tun->tfile)
265 goto drop; 298 goto drop;
266 299
267 /* Drop if the filter does not like it. 300 /* Drop if the filter does not like it.
@@ -378,7 +411,7 @@ static void tun_net_init(struct net_device *dev)
378/* Poll */ 411/* Poll */
379static unsigned int tun_chr_poll(struct file *file, poll_table * wait) 412static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
380{ 413{
381 struct tun_struct *tun = file->private_data; 414 struct tun_struct *tun = tun_get(file);
382 unsigned int mask = POLLOUT | POLLWRNORM; 415 unsigned int mask = POLLOUT | POLLWRNORM;
383 416
384 if (!tun) 417 if (!tun)
@@ -391,6 +424,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
391 if (!skb_queue_empty(&tun->readq)) 424 if (!skb_queue_empty(&tun->readq))
392 mask |= POLLIN | POLLRDNORM; 425 mask |= POLLIN | POLLRDNORM;
393 426
427 tun_put(tun);
394 return mask; 428 return mask;
395} 429}
396 430
@@ -575,14 +609,18 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
575static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, 609static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
576 unsigned long count, loff_t pos) 610 unsigned long count, loff_t pos)
577{ 611{
578 struct tun_struct *tun = iocb->ki_filp->private_data; 612 struct tun_struct *tun = tun_get(iocb->ki_filp);
613 ssize_t result;
579 614
580 if (!tun) 615 if (!tun)
581 return -EBADFD; 616 return -EBADFD;
582 617
583 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); 618 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
584 619
585 return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count)); 620 result = tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
621
622 tun_put(tun);
623 return result;
586} 624}
587 625
588/* Put packet to the user space buffer */ 626/* Put packet to the user space buffer */
@@ -655,7 +693,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
655 unsigned long count, loff_t pos) 693 unsigned long count, loff_t pos)
656{ 694{
657 struct file *file = iocb->ki_filp; 695 struct file *file = iocb->ki_filp;
658 struct tun_struct *tun = file->private_data; 696 struct tun_struct *tun = tun_get(file);
659 DECLARE_WAITQUEUE(wait, current); 697 DECLARE_WAITQUEUE(wait, current);
660 struct sk_buff *skb; 698 struct sk_buff *skb;
661 ssize_t len, ret = 0; 699 ssize_t len, ret = 0;
@@ -666,8 +704,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
666 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); 704 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
667 705
668 len = iov_length(iv, count); 706 len = iov_length(iv, count);
669 if (len < 0) 707 if (len < 0) {
670 return -EINVAL; 708 ret = -EINVAL;
709 goto out;
710 }
671 711
672 add_wait_queue(&tun->read_wait, &wait); 712 add_wait_queue(&tun->read_wait, &wait);
673 while (len) { 713 while (len) {
@@ -698,6 +738,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
698 current->state = TASK_RUNNING; 738 current->state = TASK_RUNNING;
699 remove_wait_queue(&tun->read_wait, &wait); 739 remove_wait_queue(&tun->read_wait, &wait);
700 740
741out:
742 tun_put(tun);
701 return ret; 743 return ret;
702} 744}
703 745
@@ -822,7 +864,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
822 864
823static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr) 865static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
824{ 866{
825 struct tun_struct *tun = file->private_data; 867 struct tun_struct *tun = tun_get(file);
826 868
827 if (!tun) 869 if (!tun)
828 return -EBADFD; 870 return -EBADFD;
@@ -847,6 +889,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
847 if (tun->flags & TUN_VNET_HDR) 889 if (tun->flags & TUN_VNET_HDR)
848 ifr->ifr_flags |= IFF_VNET_HDR; 890 ifr->ifr_flags |= IFF_VNET_HDR;
849 891
892 tun_put(tun);
850 return 0; 893 return 0;
851} 894}
852 895
@@ -893,7 +936,7 @@ static int set_offload(struct net_device *dev, unsigned long arg)
893static int tun_chr_ioctl(struct inode *inode, struct file *file, 936static int tun_chr_ioctl(struct inode *inode, struct file *file,
894 unsigned int cmd, unsigned long arg) 937 unsigned int cmd, unsigned long arg)
895{ 938{
896 struct tun_struct *tun = file->private_data; 939 struct tun_struct *tun;
897 void __user* argp = (void __user*)arg; 940 void __user* argp = (void __user*)arg;
898 struct ifreq ifr; 941 struct ifreq ifr;
899 int ret; 942 int ret;
@@ -902,6 +945,16 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
902 if (copy_from_user(&ifr, argp, sizeof ifr)) 945 if (copy_from_user(&ifr, argp, sizeof ifr))
903 return -EFAULT; 946 return -EFAULT;
904 947
948 if (cmd == TUNGETFEATURES) {
949 /* Currently this just means: "what IFF flags are valid?".
950 * This is needed because we never checked for invalid flags on
951 * TUNSETIFF. */
952 return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
953 IFF_VNET_HDR,
954 (unsigned int __user*)argp);
955 }
956
957 tun = tun_get(file);
905 if (cmd == TUNSETIFF && !tun) { 958 if (cmd == TUNSETIFF && !tun) {
906 int err; 959 int err;
907 960
@@ -919,28 +972,21 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
919 return 0; 972 return 0;
920 } 973 }
921 974
922 if (cmd == TUNGETFEATURES) {
923 /* Currently this just means: "what IFF flags are valid?".
924 * This is needed because we never checked for invalid flags on
925 * TUNSETIFF. */
926 return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
927 IFF_VNET_HDR,
928 (unsigned int __user*)argp);
929 }
930 975
931 if (!tun) 976 if (!tun)
932 return -EBADFD; 977 return -EBADFD;
933 978
934 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); 979 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
935 980
981 ret = 0;
936 switch (cmd) { 982 switch (cmd) {
937 case TUNGETIFF: 983 case TUNGETIFF:
938 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr); 984 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
939 if (ret) 985 if (ret)
940 return ret; 986 break;
941 987
942 if (copy_to_user(argp, &ifr, sizeof(ifr))) 988 if (copy_to_user(argp, &ifr, sizeof(ifr)))
943 return -EFAULT; 989 ret = -EFAULT;
944 break; 990 break;
945 991
946 case TUNSETNOCSUM: 992 case TUNSETNOCSUM:
@@ -992,7 +1038,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
992 ret = 0; 1038 ret = 0;
993 } 1039 }
994 rtnl_unlock(); 1040 rtnl_unlock();
995 return ret; 1041 break;
996 1042
997#ifdef TUN_DEBUG 1043#ifdef TUN_DEBUG
998 case TUNSETDEBUG: 1044 case TUNSETDEBUG:
@@ -1003,24 +1049,25 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
1003 rtnl_lock(); 1049 rtnl_lock();
1004 ret = set_offload(tun->dev, arg); 1050 ret = set_offload(tun->dev, arg);
1005 rtnl_unlock(); 1051 rtnl_unlock();
1006 return ret; 1052 break;
1007 1053
1008 case TUNSETTXFILTER: 1054 case TUNSETTXFILTER:
1009 /* Can be set only for TAPs */ 1055 /* Can be set only for TAPs */
1056 ret = -EINVAL;
1010 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) 1057 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1011 return -EINVAL; 1058 break;
1012 rtnl_lock(); 1059 rtnl_lock();
1013 ret = update_filter(&tun->txflt, (void __user *)arg); 1060 ret = update_filter(&tun->txflt, (void __user *)arg);
1014 rtnl_unlock(); 1061 rtnl_unlock();
1015 return ret; 1062 break;
1016 1063
1017 case SIOCGIFHWADDR: 1064 case SIOCGIFHWADDR:
1018 /* Get hw addres */ 1065 /* Get hw addres */
1019 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); 1066 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
1020 ifr.ifr_hwaddr.sa_family = tun->dev->type; 1067 ifr.ifr_hwaddr.sa_family = tun->dev->type;
1021 if (copy_to_user(argp, &ifr, sizeof ifr)) 1068 if (copy_to_user(argp, &ifr, sizeof ifr))
1022 return -EFAULT; 1069 ret = -EFAULT;
1023 return 0; 1070 break;
1024 1071
1025 case SIOCSIFHWADDR: 1072 case SIOCSIFHWADDR:
1026 /* Set hw address */ 1073 /* Set hw address */
@@ -1030,18 +1077,19 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
1030 rtnl_lock(); 1077 rtnl_lock();
1031 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); 1078 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
1032 rtnl_unlock(); 1079 rtnl_unlock();
1033 return ret; 1080 break;
1034
1035 default: 1081 default:
1036 return -EINVAL; 1082 ret = -EINVAL;
1083 break;
1037 }; 1084 };
1038 1085
1039 return 0; 1086 tun_put(tun);
1087 return ret;
1040} 1088}
1041 1089
1042static int tun_chr_fasync(int fd, struct file *file, int on) 1090static int tun_chr_fasync(int fd, struct file *file, int on)
1043{ 1091{
1044 struct tun_struct *tun = file->private_data; 1092 struct tun_struct *tun = tun_get(file);
1045 int ret; 1093 int ret;
1046 1094
1047 if (!tun) 1095 if (!tun)
@@ -1063,40 +1111,44 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
1063 ret = 0; 1111 ret = 0;
1064out: 1112out:
1065 unlock_kernel(); 1113 unlock_kernel();
1114 tun_put(tun);
1066 return ret; 1115 return ret;
1067} 1116}
1068 1117
1069static int tun_chr_open(struct inode *inode, struct file * file) 1118static int tun_chr_open(struct inode *inode, struct file * file)
1070{ 1119{
1120 struct tun_file *tfile;
1071 cycle_kernel_lock(); 1121 cycle_kernel_lock();
1072 DBG1(KERN_INFO "tunX: tun_chr_open\n"); 1122 DBG1(KERN_INFO "tunX: tun_chr_open\n");
1073 file->private_data = NULL; 1123
1124 tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
1125 if (!tfile)
1126 return -ENOMEM;
1127 tfile->tun = NULL;
1128 file->private_data = tfile;
1074 return 0; 1129 return 0;
1075} 1130}
1076 1131
1077static int tun_chr_close(struct inode *inode, struct file *file) 1132static int tun_chr_close(struct inode *inode, struct file *file)
1078{ 1133{
1079 struct tun_struct *tun = file->private_data; 1134 struct tun_file *tfile = file->private_data;
1080 1135 struct tun_struct *tun = __tun_get(tfile);
1081 if (!tun)
1082 return 0;
1083 1136
1084 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
1085 1137
1086 rtnl_lock(); 1138 if (tun) {
1139 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
1087 1140
1088 /* Detach from net device */ 1141 rtnl_lock();
1089 file->private_data = NULL; 1142 __tun_detach(tun);
1090 tun->attached = 0;
1091 put_net(dev_net(tun->dev));
1092 1143
1093 /* Drop read queue */ 1144 /* If desireable, unregister the netdevice. */
1094 skb_queue_purge(&tun->readq); 1145 if (!(tun->flags & TUN_PERSIST))
1146 unregister_netdevice(tun->dev);
1095 1147
1096 if (!(tun->flags & TUN_PERSIST)) 1148 rtnl_unlock();
1097 unregister_netdevice(tun->dev); 1149 }
1098 1150
1099 rtnl_unlock(); 1151 kfree(tfile);
1100 1152
1101 return 0; 1153 return 0;
1102} 1154}
@@ -1177,7 +1229,7 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
1177static u32 tun_get_link(struct net_device *dev) 1229static u32 tun_get_link(struct net_device *dev)
1178{ 1230{
1179 struct tun_struct *tun = netdev_priv(dev); 1231 struct tun_struct *tun = netdev_priv(dev);
1180 return tun->attached; 1232 return !!tun->tfile;
1181} 1233}
1182 1234
1183static u32 tun_get_rx_csum(struct net_device *dev) 1235static u32 tun_get_rx_csum(struct net_device *dev)