Blob Blame History Raw
From d1c0b7d119bb9dd2c51143b44cc86a369f453746 Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Wed, 4 Dec 2013 15:21:19 +0100
Subject: [PATCH] patch: format-security

Squashed commit of the following:

commit 19e071b9f6d477462a0f4afbbd17acd15268ddfa
Author: Nils Philippsen <nils@redhat.com>
Date:   Wed Dec 4 15:04:12 2013 +0100

    avoid using string formats insecurely with "-f"

    In the process, simplify processing the device list format: don't copy
    the format string for writing \0 into it, just iterate over chunks in
    the original string.

    (cherry picked from commit 8082a42ec4f3b3cf2cffc30a45dda5fc41d55576)
---
 frontend/scanimage.c | 52 ++++++++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 32 deletions(-)

diff --git a/frontend/scanimage.c b/frontend/scanimage.c
index d41c849..9e1bcfb 100644
--- a/frontend/scanimage.c
+++ b/frontend/scanimage.c
@@ -1826,23 +1826,16 @@ main (int argc, char **argv)
 	    else
 	      {
 		int i = 0, int_arg = 0;
-		char *percent, *start, *fmt;
+		const char *percent, *start;
 		const char *text_arg = 0;
-		char cc, ftype;
-
-		fmt = malloc (strlen (optarg) + 1);
-		if (fmt == 0)
-		  {
-		    fprintf (stderr, "%s: not enough memory\n", prog_name);
-		    exit (1);
-		  }
+		char ftype;
 
 		for (i = 0; device_list[i]; ++i)
 		  {
-		    strcpy (fmt, optarg);
-		    start = fmt;
+		    start = optarg;
 		    while (*start && (percent = strchr (start, '%')))
 		      {
+			int start_len = percent - start;
 			percent++;
 			if (*percent)
 			  {
@@ -1850,19 +1843,19 @@ main (int argc, char **argv)
 			      {
 			      case 'd':
 				text_arg = device_list[i]->name;
-				ftype = *percent = 's';
+				ftype = 's';
 				break;
 			      case 'v':
 				text_arg = device_list[i]->vendor;
-				ftype = *percent = 's';
+				ftype = 's';
 				break;
 			      case 'm':
 				text_arg = device_list[i]->model;
-				ftype = *percent = 's';
+				ftype = 's';
 				break;
 			      case 't':
 				text_arg = device_list[i]->type;
-				ftype = *percent = 's';
+				ftype = 's';
 				break;
 			      case 'i':
 				int_arg = i;
@@ -1870,45 +1863,40 @@ main (int argc, char **argv)
 				break;
 			      case 'n':
 				text_arg = "\n";
-				ftype = *percent = 's';
+				ftype = 's';
 				break;
 			      case '%':
-				ftype = 0;
+				text_arg = "%";
+				ftype = 's';
 				break;
 			      default:
 				fprintf (stderr,
 					 "%s: unknown format specifier %%%c\n",
 					 prog_name, *percent);
-				*percent = '%';
-				ftype = 0;
+                                text_arg = "%";
+				ftype = 's';
 			      }
-			    percent++;
-			    cc = *percent;
-			    *percent = 0;
+			    printf ("%.*s", start_len, start);
 			    switch (ftype)
 			      {
 			      case 's':
-				printf (start, text_arg);
+				printf ("%s", text_arg);
 				break;
 			      case 'i':
-				printf (start, int_arg);
-				break;
-			      case 0:
-				printf (start);
+				printf ("%i", int_arg);
 				break;
 			      }
-			    *percent = cc;
-			    start = percent;
+			    start = percent + 1;
 			  }
 			else
 			  {
-			    /* last char of the string is a '%', suppress it */
-			    *start = 0;
+			    /* last char of the string is a '%', ignore it */
+			    start++;
 			    break;
 			  }
 		      }
 		    if (*start)
-		      printf (start);
+		      printf ("%s", start);
 		  }
 	      }
 	    if (i == 0 && ch != 'f')
-- 
1.8.4.2