Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/sys



Hi David

On 03/02/2021 21:45, David Young wrote:
>
> This change looks a little hasty to me.
>
> It looks to me like some of these structs were __packed so that
> they could be read/written directly from/to any offset in a packet
> chain using mtod(), which does not pay any mind to the alignment
> of `*t`:
>
> #define mtod(m, t)      ((t)((m)->m_data))
>
> I see gre_h is accessed in that way, just for one example.

Looking at the other places where this is handled, does this patch to gre_h address your concerns? I tested this on aarch64 which does not define __NO_STRICT_ALIGNMENT and it passes the KASSERT.

Roy

diff -r e3c82b1d9c2e sys/net/if_gre.c
--- a/sys/net/if_gre.c	Mon Feb 08 01:00:49 2021 +0000
+++ b/sys/net/if_gre.c	Tue Feb 09 06:55:44 2021 +0000
@@ -395,10 +395,26 @@
 		sc->sc_error_ev.ev_count++;
 		return;
 	}
-	if (m->m_len < sizeof(*gh) && (m = m_pullup(m, sizeof(*gh))) == NULL) {
-		GRE_DPRINTF(sc, "m_pullup failed\n");
-		sc->sc_pullup_ev.ev_count++;
-		return;
+
+	/* If the GRE header is not aligned, slurp it up into a new
+	 * mbuf with space for link headers, in the event we forward
+	 * it.  Otherwise, if it is aligned, make sure the entire
+	 * base GRE header is in the first mbuf of the chain.
+	 */
+	if (GRE_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
+		if ((m = m_copyup(m, sizeof(struct gre_h),
+		    (max_linkhdr + 3) & ~3)) == NULL) {
+			/* XXXJRT new stat, please */
+			GRE_DPRINTF(sc, "m_copyup failed\n");
+			sc->sc_pullup_ev.ev_count++;
+			return;
+		}
+	} else if (__predict_false(m->m_len < sizeof(struct gre_h))) {
+		if ((m = m_pullup(m, sizeof(struct gre_h))) == NULL) {
+			GRE_DPRINTF(sc, "m_pullup failed\n");
+			sc->sc_pullup_ev.ev_count++;
+			return;
+		}
 	}
 	gh = mtod(m, const struct gre_h *);

@@ -940,7 +956,6 @@
 #endif

 	M_PREPEND(m, sizeof(*gh), M_DONTWAIT);
-
 	if (m == NULL) {
 		IF_DROP(&ifp->if_snd);
 		error = ENOBUFS;
@@ -948,6 +963,7 @@
 	}

 	gh = mtod(m, struct gre_h *);
+	KASSERT(GRE_HDR_ALIGNED_P(gh));
 	gh->flags = 0;
 	gh->ptype = etype;
 	/* XXX Need to handle IP ToS.  Look at how I handle IP TTL. */
diff -r e3c82b1d9c2e sys/net/if_gre.h
--- a/sys/net/if_gre.h	Mon Feb 08 01:00:49 2021 +0000
+++ b/sys/net/if_gre.h	Tue Feb 09 06:55:44 2021 +0000
@@ -131,6 +131,11 @@
 				Present if (rt_pres == 1)
  */
 };
+#ifdef __NO_STRICT_ALIGNMENT
+#define	GRE_HDR_ALIGNED_P(gh)	1
+#else
+#define	GRE_HDR_ALIGNED_P(gh)	((((vaddr_t) (gh)) & 3) == 0)
+#endif
 #ifdef __CTASSERT
 __CTASSERT(sizeof(struct gre_h) == 4);
 #endif


Home | Main Index | Thread Index | Old Index