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: <1432557993-20458-8-git-send-email-pmladek@suse.cz>
Date:	Mon, 25 May 2015 14:46:30 +0200
From:	Petr Mladek <pmladek@...e.cz>
To:	Andrew Morton <akpm@...ux-foundation.org>
Cc:	Frederic Weisbecker <fweisbec@...il.com>,
	Steven Rostedt <rostedt@...dmis.org>,
	Dave Anderson <anderson@...hat.com>,
	"Paul E. McKenney" <paulmck@...ux.vnet.ibm.com>,
	Kay Sievers <kay@...y.org>, Jiri Kosina <jkosina@...e.cz>,
	Michal Hocko <mhocko@...e.cz>, Jan Kara <jack@...e.cz>,
	linux-kernel@...r.kernel.org, Wang Long <long.wanglong@...wei.com>,
	peifeiyue@...wei.com, dzickus@...hat.com, morgan.wang@...wei.com,
	sasha.levin@...cle.com, Petr Mladek <pmladek@...e.cz>
Subject: [PATCH 07/10] printk: Split text formatting and analyze from vprintk_emit()

vprintk_emit() is too long. Let's move the text formatting and
the text analyze into a separate function.

I am not super happy with the result. The primary aim is to reduce
future mistakes when backporting fixes in this code to older stable
kernel releases. Therefore I want to keep the changes in the code
at minimum. Especially, I want to avoid conversion of @text into
"char **" because it is harder to read.

Well, there is one exception. @level is accessed via a pointer.
It looks safe because compiler warns about type mismatch when
the access is not updated. Also it used only in a very
simple code.

Better ideas are welcome!

This patch just shuffles the code. There is no change in
the functionality.

Signed-off-by: Petr Mladek <pmladek@...e.cz>
---
 kernel/printk/printk.c | 122 +++++++++++++++++++++++++++++++------------------
 1 file changed, 78 insertions(+), 44 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 91b8043044ac..7d009144f97f 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1740,13 +1740,85 @@ static int vprintk_delayed_warnings(void)
 	return printed_len;
 }
 
+/**
+ * vprintk_format_and_analyze - format and analyze the text message
+ * @fmt: text format
+ * @args: argumetns used to generate the formated text
+ * @dict: pointer to the message dictionary
+ * @facility: syslog facility
+ * @level: syslog level; might be replaced by the one found in the fomatted text
+ * @ftext: pointer to the formatted text after the syslog prefix
+ * @ftext_len: length of the formatted text without the syslog prefix
+ *
+ * This function modifies the global textbuf and therefore it must be called
+ * under lockbuf_lock!
+ */
+static enum log_flags vprinkt_format_and_analyze(const char *fmt, va_list args,
+						 const char *dict, int facility,
+						 int *level,
+						 char **ftext,
+						 size_t *ftext_len)
+{
+	char *text = textbuf;
+	size_t text_len;
+	enum log_flags lflags = 0;
+
+	/*
+	 * The printf needs to come first; we need the syslog
+	 * prefix which might be passed-in as a parameter.
+	 */
+	text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+
+	/* mark and strip a trailing newline */
+	if (text_len && text[text_len-1] == '\n') {
+		text_len--;
+		lflags |= LOG_NEWLINE;
+	}
+
+	/* strip kernel syslog prefix and extract log level or control flags */
+	if (facility == 0) {
+		int kern_level = printk_get_level(text);
+
+		if (kern_level) {
+			const char *end_of_header = printk_skip_level(text);
+
+			switch (kern_level) {
+			case '0' ... '7':
+				if (*level == LOGLEVEL_DEFAULT)
+					*level = kern_level - '0';
+				/* fallthrough */
+			case 'd':	/* KERN_DEFAULT */
+				lflags |= LOG_PREFIX;
+			}
+			/*
+			 * No need to check length here because vscnprintf
+			 * put '\0' at the end of the string. Only valid and
+			 * newly printed level is detected.
+			 */
+			text_len -= end_of_header - text;
+			text = (char *)end_of_header;
+		}
+	}
+
+	if (*level == LOGLEVEL_DEFAULT)
+		*level = default_message_loglevel;
+
+	if (dict)
+		lflags |= LOG_PREFIX|LOG_NEWLINE;
+
+	*ftext = text;
+	*ftext_len = text_len;
+
+	return lflags;
+}
+
 asmlinkage int vprintk_emit(int facility, int level,
 			    const char *dict, size_t dictlen,
 			    const char *fmt, va_list args)
 {
-	char *text = textbuf;
-	size_t text_len = 0;
-	enum log_flags lflags = 0;
+	char *text;
+	size_t text_len;
+	enum log_flags lflags;
 	unsigned long flags;
 	int this_cpu;
 	int printed_len = 0;
@@ -1808,47 +1880,9 @@ asmlinkage int vprintk_emit(int facility, int level,
 
 	printed_len += vprintk_delayed_warnings();
 
-	/*
-	 * The printf needs to come first; we need the syslog
-	 * prefix which might be passed-in as a parameter.
-	 */
-	text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
-
-	/* mark and strip a trailing newline */
-	if (text_len && text[text_len-1] == '\n') {
-		text_len--;
-		lflags |= LOG_NEWLINE;
-	}
-
-	/* strip kernel syslog prefix and extract log level or control flags */
-	if (facility == 0) {
-		int kern_level = printk_get_level(text);
-
-		if (kern_level) {
-			const char *end_of_header = printk_skip_level(text);
-			switch (kern_level) {
-			case '0' ... '7':
-				if (level == LOGLEVEL_DEFAULT)
-					level = kern_level - '0';
-				/* fallthrough */
-			case 'd':	/* KERN_DEFAULT */
-				lflags |= LOG_PREFIX;
-			}
-			/*
-			 * No need to check length here because vscnprintf
-			 * put '\0' at the end of the string. Only valid and
-			 * newly printed level is detected.
-			 */
-			text_len -= end_of_header - text;
-			text = (char *)end_of_header;
-		}
-	}
-
-	if (level == LOGLEVEL_DEFAULT)
-		level = default_message_loglevel;
-
-	if (dict)
-		lflags |= LOG_PREFIX|LOG_NEWLINE;
+	lflags = vprinkt_format_and_analyze(fmt, args, dict, facility,
+					    &level,
+					    &text, &text_len);
 
 	if (!(lflags & LOG_NEWLINE)) {
 		/*
-- 
1.8.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ