lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190807222634.1723-5-john.ogness@linutronix.de>
Date:   Thu,  8 Aug 2019 00:32:29 +0206
From:   John Ogness <john.ogness@...utronix.de>
To:     linux-kernel@...r.kernel.org
Cc:     Peter Zijlstra <peterz@...radead.org>,
        Petr Mladek <pmladek@...e.com>,
        Sergey Senozhatsky <sergey.senozhatsky.work@...il.com>,
        Steven Rostedt <rostedt@...dmis.org>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Andrea Parri <andrea.parri@...rulasolutions.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Sergey Senozhatsky <sergey.senozhatsky@...il.com>,
        Brendan Higgins <brendanhiggins@...gle.com>
Subject: [RFC PATCH v4 4/9] printk-rb: initialize new descriptors as invalid

Initialize never-used descriptors as permanently invalid so there
is no risk of the descriptor unexpectedly being determined as
valid due to dataring head overflowing/wrapping.

Signed-off-by: John Ogness <john.ogness@...utronix.de>
---
 kernel/printk/dataring.c   | 42 +++++++++++++++++++++++++++-----------
 kernel/printk/dataring.h   | 12 +++++++++++
 kernel/printk/ringbuffer.c |  5 +++++
 kernel/printk/ringbuffer.h |  7 ++++++-
 4 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/kernel/printk/dataring.c b/kernel/printk/dataring.c
index 6642e085a05d..345c46dba5bb 100644
--- a/kernel/printk/dataring.c
+++ b/kernel/printk/dataring.c
@@ -316,8 +316,8 @@ static unsigned long _dataring_pop(struct dataring *dr,
 	 * If dB reads from gA, then dD reads from fH.
 	 * If dB reads from gA, then dE reads from fE.
 	 *
-	 * Note that if dB reads from gA, then dC cannot read from fC.
-	 * Note that if dB reads from gA, then dD cannot read from fD.
+	 * Note that if dB reads from gA, then dC cannot read from fC->nA.
+	 * Note that if dB reads from gA, then dD cannot read from fC->nB.
 	 *
 	 * Relies on:
 	 *
@@ -489,6 +489,30 @@ static bool get_new_lpos(struct dataring *dr, unsigned int size,
 	}
 }
 
+/**
+ * dataring_desc_init() - Initialize a descriptor to be permanently invalid.
+ *
+ * @desc: The descriptor to initialize.
+ *
+ * Setting a descriptor to be permanently invalid means that there is no risk
+ * of the descriptor later unexpectedly being determined as valid due to
+ * overflowing/wrapping of @head_lpos.
+ */
+void dataring_desc_init(struct dr_desc *desc)
+{
+	/*
+	 * An unaligned @begin_lpos can never point to a data block and
+	 * having the same value for @begin_lpos and @next_lpos is also
+	 * invalid.
+	 */
+
+	/* nA: */
+	WRITE_ONCE(desc->begin_lpos, 1);
+
+	/* nB: */
+	WRITE_ONCE(desc->next_lpos, 1);
+}
+
 /**
  * dataring_push() - Reserve a data block in the data array.
  *
@@ -568,20 +592,14 @@ char *dataring_push(struct dataring *dr, unsigned int size,
 
 		if (!ret) {
 			/*
+			 * fC:
+			 *
 			 * Force @desc permanently invalid to minimize risk
 			 * of the descriptor later unexpectedly being
 			 * determined as valid due to overflowing/wrapping of
-			 * @head_lpos. An unaligned @begin_lpos can never
-			 * point to a data block and having the same value
-			 * for @begin_lpos and @next_lpos is also invalid.
+			 * @head_lpos.
 			 */
-
-			/* fC: */
-			WRITE_ONCE(desc->begin_lpos, 1);
-
-			/* fD: */
-			WRITE_ONCE(desc->next_lpos, 1);
-
+			dataring_desc_init(desc);
 			return NULL;
 		}
 	/* fE: */
diff --git a/kernel/printk/dataring.h b/kernel/printk/dataring.h
index 346a455a335a..413ee95f4dd6 100644
--- a/kernel/printk/dataring.h
+++ b/kernel/printk/dataring.h
@@ -43,6 +43,17 @@ struct dr_desc {
 	unsigned long	next_lpos;
 };
 
+/*
+ * Initialize a descriptor to be permanently invalid so there is no risk
+ * of the descriptor later unexpectedly being determined as valid due to
+ * overflowing/wrapping of @head_lpos.
+ */
+#define __DR_DESC_INITIALIZER		\
+	{				\
+		.begin_lpos	= 1,	\
+		.next_lpos	= 1,	\
+	}
+
 /**
  * struct dataring - A data ringbuffer with support for entry IDs.
  *
@@ -90,6 +101,7 @@ void dataring_datablock_setid(struct dataring *dr, struct dr_desc *desc,
 struct dr_datablock *dataring_getdatablock(struct dataring *dr,
 					   struct dr_desc *desc, int *size);
 bool dataring_datablock_isvalid(struct dataring *dr, struct dr_desc *desc);
+void dataring_desc_init(struct dr_desc *desc);
 void dataring_desc_copy(struct dr_desc *dst, struct dr_desc *src);
 
 #endif /* _KERNEL_PRINTK_DATARING_H */
diff --git a/kernel/printk/ringbuffer.c b/kernel/printk/ringbuffer.c
index b9fc13597b10..9be841761ea2 100644
--- a/kernel/printk/ringbuffer.c
+++ b/kernel/printk/ringbuffer.c
@@ -345,6 +345,11 @@ static bool assign_desc(struct prb_reserved_entry *e)
 			if (i < DESCS_COUNT(rb)) {
 				d = &rb->descs[i];
 				atomic_long_set(&d->id, i);
+				/*
+				 * Initialize the new descriptor such that
+				 * it is permanently invalid.
+				 */
+				dataring_desc_init(&d->desc);
 				break;
 			}
 		}
diff --git a/kernel/printk/ringbuffer.h b/kernel/printk/ringbuffer.h
index 9fe54a09fbc2..462b4d3a3ee2 100644
--- a/kernel/printk/ringbuffer.h
+++ b/kernel/printk/ringbuffer.h
@@ -178,7 +178,12 @@ struct dr_desc *prb_getdesc(unsigned long id, void *arg);
 char _##name##_data[(1 << ((avgdatabits) + (descbits))) +		\
 				 sizeof(long)]				\
 	__aligned(__alignof__(long));					\
-struct prb_desc _##name##_descs[1 << (descbits)];			\
+struct prb_desc _##name##_descs[1 << (descbits)] = {			\
+		{							\
+			.id	= ATOMIC_LONG_INIT(0),			\
+			.desc	= __DR_DESC_INITIALIZER,		\
+		},							\
+	};								\
 struct printk_ringbuffer name = {					\
 	.desc_count_bits	= descbits,				\
 	.descs			= &_##name##_descs[0],			\
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ