Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1283348

[PATCH v3 03/14] lib/vsprintf.c: eliminate potential race in string()

From Rasmus Villemoes <linux@rasmusvillemoes.dk>
Newsgroups linux.kernel
Subject [PATCH v3 03/14] lib/vsprintf.c: eliminate potential race in string()
Date 2015-12-03 22:00 +0100
Message-ID <qBJ8T-1Cs-63@gated-at.bofh.it> (permalink)
References <qBJ8R-1Cs-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


If the string corresponding to a %s specifier can change under us, we
might end up copying a \0 byte to the output buffer. There might be
callers who expect the output buffer to contain a genuine C string
whose length is exactly the snprintf return value (assuming truncation
hasn't happened or has been checked for).

We can avoid this by only passing over the source string once,
stopping the first time we meet a nul byte (or when we reach the given
precision), and then letting widen_string() handle left/right space
padding. As a small bonus, this code reuse also makes the generated
code slightly smaller.

Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 lib/vsprintf.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a021e6380404..63ca52366049 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -557,32 +557,22 @@ char *widen_string(char *buf, int n, char *end, struct printf_spec spec)
 static noinline_for_stack
 char *string(char *buf, char *end, const char *s, struct printf_spec spec)
 {
-	int len, i;
+	int len = 0;
+	size_t lim = spec.precision;
 
 	if ((unsigned long)s < PAGE_SIZE)
 		s = "(null)";
 
-	len = strnlen(s, spec.precision);
-
-	if (!(spec.flags & LEFT)) {
-		while (len < spec.field_width--) {
-			if (buf < end)
-				*buf = ' ';
-			++buf;
-		}
-	}
-	for (i = 0; i < len; ++i) {
-		if (buf < end)
-			*buf = *s;
-		++buf; ++s;
-	}
-	while (len < spec.field_width--) {
+	while (lim--) {
+		char c = *s++;
+		if (!c)
+			break;
 		if (buf < end)
-			*buf = ' ';
+			*buf = c;
 		++buf;
+		++len;
 	}
-
-	return buf;
+	return widen_string(buf, len, end, spec);
 }
 
 static noinline_for_stack
-- 
2.6.1

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

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v3 00/14] printf stuff for 4.5 Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 01/14] lib/vsprintf.c: pull out padding code from dentry_name() Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Joe Perches <joe@perches.com> - 2015-12-03 22:00 +0100
    Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Andy Shevchenko <andriy.shevchenko@linux.intel.com> - 2015-12-03 22:40 +0100
      Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Andrew Morton <akpm@linux-foundation.org> - 2015-12-04 00:40 +0100
        Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Joe Perches <joe@perches.com> - 2015-12-04 01:10 +0100
          Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-04 10:10 +0100
        Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-04 10:10 +0100
      Re: [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Joe Perches <joe@perches.com> - 2015-12-04 00:50 +0100
  [PATCH v3 08/14] lib/test_printf.c: don't BUG Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 03/14] lib/vsprintf.c: eliminate potential race in string() Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 06/14] lib/vsprintf.c: warn about too large precisions and field widths Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 09/14] lib/test_printf.c: check for out-of-bound writes Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 02/14] lib/vsprintf.c: move string() below widen_string() Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
  [PATCH v3 14/14] lib/test_printf.c: test dentry printing Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100
    Re: [PATCH v3 14/14] lib/test_printf.c: test dentry printing Andrew Morton <akpm@linux-foundation.org> - 2015-12-04 01:20 +0100
      Re: [PATCH v3 14/14] lib/test_printf.c: test dentry printing Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-04 09:20 +0100
        Re: [PATCH v3 14/14] lib/test_printf.c: test dentry printing Andrew Morton <akpm@linux-foundation.org> - 2015-12-04 09:50 +0100
  [PATCH v3 04/14] lib/vsprintf.c: expand field_width to 24 bits Rasmus Villemoes <linux@rasmusvillemoes.dk> - 2015-12-03 22:00 +0100

csiph-web