Revert commitid: KtmyJEoS0WWxmlZ5
authorclaudio <claudio@openbsd.org>
Sun, 8 Oct 2023 07:44:52 +0000 (07:44 +0000)
committerclaudio <claudio@openbsd.org>
Sun, 8 Oct 2023 07:44:52 +0000 (07:44 +0000)
---
Protect interface queues with read once and mutex.

Reading atomic values need at least read once and writing values
should have a mutex.  This is what mbuf queues already do.  Add
READ_ONCE() to ifq and ifiq macros for len and empty.  Convert
ifq_set_maxlen() to a function that grabs ifq_mtx.

OK mvs@
---

ifq_set_maxlen() is called before the ifq_mtx is initalized and this at
least crashes WITNESS kernels on boot.

Reported-by: syzbot+7b218ef53432b5d56d7d@syzkaller.appspotmail.com
sys/net/ifq.c
sys/net/ifq.h

index 7255f44..fb8dea2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ifq.c,v 1.51 2023/10/05 11:08:56 bluhm Exp $ */
+/*     $OpenBSD: ifq.c,v 1.52 2023/10/08 07:44:52 claudio Exp $ */
 
 /*
  * Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -529,14 +529,6 @@ ifq_hdatalen(struct ifqueue *ifq)
        return (len);
 }
 
-void
-ifq_set_maxlen(struct ifqueue *ifq, unsigned int maxlen)
-{
-       mtx_enter(&ifq->ifq_mtx);
-       ifq->ifq_maxlen = maxlen;
-       mtx_leave(&ifq->ifq_mtx);
-}
-
 unsigned int
 ifq_purge(struct ifqueue *ifq)
 {
index d15af37..ac06de4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ifq.h,v 1.39 2023/10/05 11:08:56 bluhm Exp $ */
+/*     $OpenBSD: ifq.h,v 1.40 2023/10/08 07:44:52 claudio Exp $ */
 
 /*
  * Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -435,7 +435,6 @@ void                 ifq_deq_commit(struct ifqueue *, struct mbuf *);
 void            ifq_deq_rollback(struct ifqueue *, struct mbuf *);
 struct mbuf    *ifq_dequeue(struct ifqueue *);
 int             ifq_hdatalen(struct ifqueue *);
-void            ifq_set_maxlen(struct ifqueue *, unsigned int);
 void            ifq_mfreem(struct ifqueue *, struct mbuf *);
 void            ifq_mfreeml(struct ifqueue *, struct mbuf_list *);
 unsigned int    ifq_purge(struct ifqueue *);
@@ -449,8 +448,9 @@ int          ifq_deq_sleep(struct ifqueue *, struct mbuf **, int, int,
                     const char *, volatile unsigned int *,
                     volatile unsigned int *);
 
-#define ifq_len(_ifq)          READ_ONCE((_ifq)->ifq_len)
-#define ifq_empty(_ifq)                (ifq_len(_ifq) == 0)
+#define        ifq_len(_ifq)                   ((_ifq)->ifq_len)
+#define        ifq_empty(_ifq)                 (ifq_len(_ifq) == 0)
+#define        ifq_set_maxlen(_ifq, _l)        ((_ifq)->ifq_maxlen = (_l))
 
 static inline int
 ifq_is_priq(struct ifqueue *ifq)
@@ -490,8 +490,8 @@ int          ifiq_input(struct ifiqueue *, struct mbuf_list *);
 int             ifiq_enqueue(struct ifiqueue *, struct mbuf *);
 void            ifiq_add_data(struct ifiqueue *, struct if_data *);
 
-#define ifiq_len(_ifiq)                READ_ONCE(ml_len(&(_ifiq)->ifiq_ml))
-#define ifiq_empty(_ifiq)      (ifiq_len(_ifiq) == 0)
+#define        ifiq_len(_ifiq)                 ml_len(&(_ifiq)->ifiq_ml)
+#define        ifiq_empty(_ifiq)               ml_empty(&(_ifiq)->ifiq_ml)
 
 #endif /* _KERNEL */