diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a4fdad475594..18656c4094b3 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -856,10 +856,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
856 | err = 0; | 856 | err = 0; |
857 | } | 857 | } |
858 | 858 | ||
859 | rcu_assign_pointer(tfile->tun, tun); | ||
860 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | ||
861 | tun->numqueues++; | ||
862 | |||
863 | if (tfile->detached) { | 859 | if (tfile->detached) { |
864 | tun_enable_queue(tfile); | 860 | tun_enable_queue(tfile); |
865 | } else { | 861 | } else { |
@@ -876,6 +872,13 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
876 | * refcnt. | 872 | * refcnt. |
877 | */ | 873 | */ |
878 | 874 | ||
875 | /* Publish tfile->tun and tun->tfiles only after we've fully | ||
876 | * initialized tfile; otherwise we risk using half-initialized | ||
877 | * object. | ||
878 | */ | ||
879 | rcu_assign_pointer(tfile->tun, tun); | ||
880 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | ||
881 | tun->numqueues++; | ||
879 | out: | 882 | out: |
880 | return err; | 883 | return err; |
881 | } | 884 | } |