summaryrefslogtreecommitdiffstats
path: root/sys/net/if_pppx.c
diff options
context:
space:
mode:
authormvs <mvs@openbsd.org>2020-07-10 11:45:08 +0000
committermvs <mvs@openbsd.org>2020-07-10 11:45:08 +0000
commit8b3855785010c310a37f5d3cf289b07bf58bfec5 (patch)
tree69a4f43d18da6a796d6b7b28697a8142588850f9 /sys/net/if_pppx.c
parentSet missing `IFXF_CLONED' flag to pppx(4) related `ifnet'. That should (diff)
downloadwireguard-openbsd-8b3855785010c310a37f5d3cf289b07bf58bfec5.tar.xz
wireguard-openbsd-8b3855785010c310a37f5d3cf289b07bf58bfec5.zip
Kill `pppx_devs_lk' rwlock. It used only to prevent races caused by
malloc(9) in pppxopen(). We can avoid these races without rwlock. Also we move malloc(9) out of rwlock. ok mpi@
Diffstat (limited to '')
-rw-r--r--sys/net/if_pppx.c54
1 files changed, 12 insertions, 42 deletions
diff --git a/sys/net/if_pppx.c b/sys/net/if_pppx.c
index 876b614edc2..6550d6bf079 100644
--- a/sys/net/if_pppx.c
+++ b/sys/net/if_pppx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pppx.c,v 1.92 2020/07/10 09:26:36 mvs Exp $ */
+/* $OpenBSD: if_pppx.c,v 1.93 2020/07/10 11:45:08 mvs Exp $ */
/*
* Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org>
@@ -50,7 +50,6 @@
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/queue.h>
-#include <sys/rwlock.h>
#include <sys/pool.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
@@ -132,9 +131,8 @@ struct pppx_dev {
LIST_HEAD(,pppx_if) pxd_pxis;
};
-struct rwlock pppx_devs_lk = RWLOCK_INITIALIZER("pppxdevs");
LIST_HEAD(, pppx_dev) pppx_devs = LIST_HEAD_INITIALIZER(pppx_devs);
-struct pool *pppx_if_pl;
+struct pool pppx_if_pl;
struct pppx_dev *pppx_dev_lookup(dev_t);
struct pppx_dev *pppx_dev2pxd(dev_t);
@@ -218,8 +216,6 @@ pppx_dev_lookup(dev_t dev)
struct pppx_dev *pxd;
int unit = minor(dev);
- /* must hold pppx_devs_lk */
-
LIST_FOREACH(pxd, &pppx_devs, pxd_entry) {
if (pxd->pxd_unit == unit)
return (pxd);
@@ -233,9 +229,7 @@ pppx_dev2pxd(dev_t dev)
{
struct pppx_dev *pxd;
- rw_enter_read(&pppx_devs_lk);
pxd = pppx_dev_lookup(dev);
- rw_exit_read(&pppx_devs_lk);
return (pxd);
}
@@ -243,6 +237,8 @@ pppx_dev2pxd(dev_t dev)
void
pppxattach(int n)
{
+ pool_init(&pppx_if_pl, sizeof(struct pppx_if), 0, IPL_NONE,
+ PR_WAITOK, "pppxif", NULL);
pipex_init();
}
@@ -250,25 +246,12 @@ int
pppxopen(dev_t dev, int flags, int mode, struct proc *p)
{
struct pppx_dev *pxd;
- int rv = 0;
-
- rv = rw_enter(&pppx_devs_lk, RW_WRITE | RW_INTR);
- if (rv != 0)
- return (rv);
-
- pxd = pppx_dev_lookup(dev);
- if (pxd != NULL) {
- rv = EBUSY;
- goto out;
- }
-
- if (LIST_EMPTY(&pppx_devs) && pppx_if_pl == NULL) {
- pppx_if_pl = malloc(sizeof(*pppx_if_pl), M_DEVBUF, M_WAITOK);
- pool_init(pppx_if_pl, sizeof(struct pppx_if), 0, IPL_NONE,
- PR_WAITOK, "pppxif", NULL);
- }
pxd = malloc(sizeof(*pxd), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (pppx_dev_lookup(dev) != NULL) {
+ free(pxd, M_DEVBUF, sizeof(*pxd));
+ return (EBUSY);
+ }
pxd->pxd_unit = minor(dev);
mtx_init(&pxd->pxd_rsel_mtx, IPL_NET);
@@ -278,9 +261,7 @@ pppxopen(dev_t dev, int flags, int mode, struct proc *p)
mq_init(&pxd->pxd_svcq, 128, IPL_NET);
LIST_INSERT_HEAD(&pppx_devs, pxd, pxd_entry);
-out:
- rw_exit(&pppx_devs_lk);
- return (rv);
+ return 0;
}
int
@@ -587,8 +568,6 @@ pppxclose(dev_t dev, int flags, int mode, struct proc *p)
struct pppx_dev *pxd;
struct pppx_if *pxi;
- rw_enter_write(&pppx_devs_lk);
-
pxd = pppx_dev_lookup(dev);
/* XXX */
@@ -603,13 +582,6 @@ pppxclose(dev_t dev, int flags, int mode, struct proc *p)
free(pxd, M_DEVBUF, sizeof(*pxd));
- if (LIST_EMPTY(&pppx_devs)) {
- pool_destroy(pppx_if_pl);
- free(pppx_if_pl, M_DEVBUF, sizeof(*pppx_if_pl));
- pppx_if_pl = NULL;
- }
-
- rw_exit_write(&pppx_devs_lk);
return (0);
}
@@ -676,7 +648,7 @@ pppx_add_session(struct pppx_dev *pxd, struct pipex_session_req *req)
if (error)
return (error);
- pxi = pool_get(pppx_if_pl, PR_WAITOK | PR_ZERO);
+ pxi = pool_get(&pppx_if_pl, PR_WAITOK | PR_ZERO);
ifp = &pxi->pxi_if;
pxi->pxi_session = session;
@@ -777,7 +749,7 @@ remove:
panic("%s: inconsistent RB tree", __func__);
LIST_REMOVE(pxi, pxi_list);
out:
- pool_put(pppx_if_pl, pxi);
+ pool_put(&pppx_if_pl, pxi);
pipex_rele_session(session);
return (error);
@@ -872,7 +844,7 @@ pppx_if_destroy(struct pppx_dev *pxd, struct pppx_if *pxi)
panic("%s: inconsistent RB tree", __func__);
LIST_REMOVE(pxi, pxi_list);
- pool_put(pppx_if_pl, pxi);
+ pool_put(&pppx_if_pl, pxi);
}
void
@@ -958,7 +930,6 @@ pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
th = mtod(m, struct pppx_hdr *);
th->pppx_proto = 0; /* not used */
th->pppx_id = pxi->pxi_session->ppp_id;
- rw_enter_read(&pppx_devs_lk);
error = mq_enqueue(&pxi->pxi_dev->pxd_svcq, m);
if (error == 0) {
if (pxi->pxi_dev->pxd_waiting) {
@@ -967,7 +938,6 @@ pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
}
selwakeup(&pxi->pxi_dev->pxd_rsel);
}
- rw_exit_read(&pppx_devs_lk);
}
out: