summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2013-10-19 11:11:24 +0000
committermpi <mpi@openbsd.org>2013-10-19 11:11:24 +0000
commitf35d2347b455658bd376a4e98cafb62c4ae259a5 (patch)
tree723ffd8d1ceff032d04669c8a28e6f0f653fd32d
parentsimplify checksum handling. no need to compute the pseudo hdr cksum (diff)
downloadwireguard-openbsd-f35d2347b455658bd376a4e98cafb62c4ae259a5.tar.xz
wireguard-openbsd-f35d2347b455658bd376a4e98cafb62c4ae259a5.zip
When we attach an interface, do not try to reuse the last index to
limit the possible races related to unscheduled task, or anything else, relying on an unique index. I say "limit" here because a race can still occurs if you run out of indexes and jump back to 1. A generation number can be added later to avoid this problem. ok deraadt@, claudio@, krw@, mikeb@, "I can live with it" reyk@
-rw-r--r--sys/net/if.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 85f0d28ae43..a8328ad155f 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.268 2013/10/17 16:27:40 bluhm Exp $ */
+/* $OpenBSD: if.c,v 1.269 2013/10/19 11:11:24 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -210,31 +210,37 @@ if_attachsetup(struct ifnet *ifp)
{
int wrapped = 0;
- if (ifindex2ifnet == 0)
+ /*
+ * Always increment the index to avoid races.
+ */
+ if_index++;
+
+ /*
+ * If we hit USHRT_MAX, we skip back to 1 since there are a
+ * number of places where the value of ifp->if_index or
+ * if_index itself is compared to or stored in an unsigned
+ * short. By jumping back, we won't botch those assignments
+ * or comparisons.
+ */
+ if (if_index == USHRT_MAX) {
if_index = 1;
- else {
- while (if_index < if_indexlim &&
- ifindex2ifnet[if_index] != NULL) {
- if_index++;
+ wrapped++;
+ }
+
+ while (if_index < if_indexlim && ifindex2ifnet[if_index] != NULL) {
+ if_index++;
+
+ if (if_index == USHRT_MAX) {
/*
- * If we hit USHRT_MAX, we skip back to 1 since
- * there are a number of places where the value
- * of ifp->if_index or if_index itself is compared
- * to or stored in an unsigned short. By
- * jumping back, we won't botch those assignments
- * or comparisons.
+ * If we have to jump back to 1 twice without
+ * finding an empty slot then there are too many
+ * interfaces.
*/
- if (if_index == USHRT_MAX) {
- if_index = 1;
- /*
- * However, if we have to jump back to 1
- * *twice* without finding an empty
- * slot in ifindex2ifnet[], then there
- * there are too many (>65535) interfaces.
- */
- if (wrapped++)
- panic("too many interfaces");
- }
+ if (wrapped)
+ panic("too many interfaces");
+
+ if_index = 1;
+ wrapped++;
}
}
ifp->if_index = if_index;