Wed Jan 25 03:04:22 2017 UTC ()
fix locking against myself in module autoload; module autoload calls
if_clone_attach which takes the lock again.


(christos)
diff -r1.374 -r1.375 src/sys/net/if.c

cvs diff -r1.374 -r1.375 src/sys/net/if.c (expand / switch to unified diff)

--- src/sys/net/if.c 2017/01/24 07:58:58 1.374
+++ src/sys/net/if.c 2017/01/25 03:04:21 1.375
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if.c,v 1.374 2017/01/24 07:58:58 ozaki-r Exp $ */ 1/* $NetBSD: if.c,v 1.375 2017/01/25 03:04:21 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by William Studenmund and Jason R. Thorpe. 8 * by William Studenmund and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -80,27 +80,27 @@ @@ -80,27 +80,27 @@
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE. 87 * SUCH DAMAGE.
88 * 88 *
89 * @(#)if.c 8.5 (Berkeley) 1/9/95 89 * @(#)if.c 8.5 (Berkeley) 1/9/95
90 */ 90 */
91 91
92#include <sys/cdefs.h> 92#include <sys/cdefs.h>
93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.374 2017/01/24 07:58:58 ozaki-r Exp $"); 93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.375 2017/01/25 03:04:21 christos Exp $");
94 94
95#if defined(_KERNEL_OPT) 95#if defined(_KERNEL_OPT)
96#include "opt_inet.h" 96#include "opt_inet.h"
97#include "opt_ipsec.h" 97#include "opt_ipsec.h"
98 98
99#include "opt_atalk.h" 99#include "opt_atalk.h"
100#include "opt_natm.h" 100#include "opt_natm.h"
101#include "opt_wlan.h" 101#include "opt_wlan.h"
102#include "opt_net_mpsafe.h" 102#include "opt_net_mpsafe.h"
103#endif 103#endif
104 104
105#include <sys/param.h> 105#include <sys/param.h>
106#include <sys/mbuf.h> 106#include <sys/mbuf.h>
@@ -1609,28 +1609,33 @@ if_clone_lookup(const char *name, int *u @@ -1609,28 +1609,33 @@ if_clone_lookup(const char *name, int *u
1609 *dp++ = *cp++; 1609 *dp++ = *cp++;
1610 1610
1611 if (cp == name || cp - name == IFNAMSIZ || !*cp) 1611 if (cp == name || cp - name == IFNAMSIZ || !*cp)
1612 return NULL; /* No name or unit number */ 1612 return NULL; /* No name or unit number */
1613 *dp++ = '\0'; 1613 *dp++ = '\0';
1614 1614
1615again: 1615again:
1616 LIST_FOREACH(ifc, &if_cloners, ifc_list) { 1616 LIST_FOREACH(ifc, &if_cloners, ifc_list) {
1617 if (strcmp(ifname + 3, ifc->ifc_name) == 0) 1617 if (strcmp(ifname + 3, ifc->ifc_name) == 0)
1618 break; 1618 break;
1619 } 1619 }
1620 1620
1621 if (ifc == NULL) { 1621 if (ifc == NULL) {
1622 if (*ifname == '\0' || 1622 int error;
1623 module_autoload(ifname, MODULE_CLASS_DRIVER)) 1623 if (*ifname == '\0')
 1624 return NULL;
 1625 mutex_exit(&if_clone_mtx);
 1626 error = module_autoload(ifname, MODULE_CLASS_DRIVER);
 1627 mutex_enter(&if_clone_mtx);
 1628 if (error)
1624 return NULL; 1629 return NULL;
1625 *ifname = '\0'; 1630 *ifname = '\0';
1626 goto again; 1631 goto again;
1627 } 1632 }
1628 1633
1629 unit = 0; 1634 unit = 0;
1630 while (cp - name < IFNAMSIZ && *cp) { 1635 while (cp - name < IFNAMSIZ && *cp) {
1631 if (*cp < '0' || *cp > '9' || unit >= INT_MAX / 10) { 1636 if (*cp < '0' || *cp > '9' || unit >= INT_MAX / 10) {
1632 /* Bogus unit number. */ 1637 /* Bogus unit number. */
1633 return NULL; 1638 return NULL;
1634 } 1639 }
1635 unit = (unit * 10) + (*cp++ - '0'); 1640 unit = (unit * 10) + (*cp++ - '0');
1636 } 1641 }