⬢ DragonFlyBSD Kernel Audit
DF-5147 / fix.diff
← back to finding ↓ download raw
diff --git a/dcons_orig.c b/dcons.c
index 49680c5..f68ca6d 100644
--- a/sys/dev/misc/dcons/dcons.c
+++ b/sys/dev/misc/dcons/dcons.c
@@ -157,7 +157,8 @@ dcons_init_port(int port, int offset, int size, struct dcons_buf *buf,
 int
 dcons_load_buffer(struct dcons_buf *buf, int size, struct dcons_softc *sc)
 {
-	int port, s;
+	int port;
+	uint64_t s, ooff, ioff;
 	struct dcons_softc *dc;
 
 	if (buf->version != htonl(DCONS_VERSION))
@@ -168,12 +169,21 @@ dcons_load_buffer(struct dcons_buf *buf, int size, struct dcons_softc *sc)
 		dc = &sc[port];
 		dc->o.size = ntohl(buf->osize[port]);
 		dc->i.size = ntohl(buf->isize[port]);
-		dc->o.buf = (char *)buf + ntohl(buf->ooffset[port]);
-		dc->i.buf = (char *)buf + ntohl(buf->ioffset[port]);
+		ooff = ntohl(buf->ooffset[port]);
+		ioff = ntohl(buf->ioffset[port]);
+		if (ooff > (uint64_t)size ||
+		    ooff + dc->o.size > (uint64_t)size ||
+		    ioff > (uint64_t)size ||
+		    ioff + dc->i.size > (uint64_t)size)
+			return (-1);
+		dc->o.buf = (char *)buf + ooff;
+		dc->i.buf = (char *)buf + ioff;
 		dc->o.gen = ntohl(buf->optr[port]) >> DCONS_GEN_SHIFT;
 		dc->i.gen = ntohl(buf->iptr[port]) >> DCONS_GEN_SHIFT;
 		dc->o.pos = ntohl(buf->optr[port]) & DCONS_POS_MASK;
 		dc->i.pos = ntohl(buf->iptr[port]) & DCONS_POS_MASK;
+		if (dc->o.pos >= dc->o.size || dc->i.pos >= dc->i.size)
+			return (-1);
 		dc->o.ptr = &buf->optr[port];
 		dc->i.ptr = &buf->iptr[port];
 		dc->brk_state = STATE0;
@@ -182,7 +192,7 @@ dcons_load_buffer(struct dcons_buf *buf, int size, struct dcons_softc *sc)
 	}
 
 	/* sanity check */
-	if (s > size)
+	if (s > (uint64_t)size)
 		return (-1);
 
 	buf->magic = ntohl(DCONS_MAGIC);