Blob Blame History Raw
diff -up sane-backends-1.0.25/frontend/saned.c.CVE-2017-6318 sane-backends-1.0.25/frontend/saned.c
--- sane-backends-1.0.25/frontend/saned.c.CVE-2017-6318	2017-03-07 15:51:59.065762693 +0100
+++ sane-backends-1.0.25/frontend/saned.c	2017-03-07 16:24:13.913836854 +0100
@@ -1986,6 +1986,34 @@ process_request (Wire * w)
 	    return 1;
 	  }
 
+        if (w->direction == WIRE_DECODE
+            && req.value_type == SANE_TYPE_STRING
+            && req.action     == SANE_ACTION_GET_VALUE)
+          {
+            if (req.value)
+              {
+                /* Another try to fix problem with NUL terminator - try to pass string length
+                 * from protocol by struct member value_length to process_request function -
+                 * this change contains change of parameters, so I do not know if this is
+                 * acceptable change for sane-backends. But it could solve this issue.
+                 *
+                 */
+                w->allocated_memory -= req.value_length;
+                free (req.value);
+              }
+            req.value = malloc (req.value_size);
+            if (!req.value)
+              {
+                w->status = ENOMEM;
+                DBG (DBG_ERR,
+                     "process_request: (control_option) "
+                     "h=%d (%s)\n", req.handle, strerror (w->status));
+                return 1;
+              }
+            memset (req.value, 0, req.value_size);
+            w->allocated_memory += req.value_size;
+          }
+
 	can_authorize = 1;
 
 	memset (&reply, 0, sizeof (reply));	/* avoid leaking bits */
diff -up sane-backends-1.0.25/include/sane/sanei_net.h.CVE-2017-6318 sane-backends-1.0.25/include/sane/sanei_net.h
--- sane-backends-1.0.25/include/sane/sanei_net.h.CVE-2017-6318	2017-03-07 15:37:05.642610981 +0100
+++ sane-backends-1.0.25/include/sane/sanei_net.h	2017-03-07 16:20:48.370421540 +0100
@@ -88,6 +88,7 @@ typedef struct
     SANE_Word action;
     SANE_Word value_type;
     SANE_Word value_size;
+	SANE_Word value_length;
     void *value;
   }
 SANE_Control_Option_Req;
@@ -98,6 +99,7 @@ typedef struct
     SANE_Word info;
     SANE_Word value_type;
     SANE_Word value_size;
+    SANE_Word value_length;
     void *value;
     SANE_String resource_to_authorize;
   }
diff -up sane-backends-1.0.25/sanei/sanei_net.c.CVE-2017-6318 sane-backends-1.0.25/sanei/sanei_net.c
--- sane-backends-1.0.25/sanei/sanei_net.c.CVE-2017-6318	2017-03-07 15:37:21.625487191 +0100
+++ sane-backends-1.0.25/sanei/sanei_net.c	2017-03-07 15:51:08.717148058 +0100
@@ -90,9 +90,9 @@ sanei_w_open_reply (Wire *w, SANE_Open_R
 }
 
 static void
-w_option_value (Wire *w, SANE_Word type, SANE_Word size, void **value)
+w_option_value (Wire *w, SANE_Word type, SANE_Word size, SANE_Word * len, void **value)
 {
-  SANE_Word len, element_size;
+  SANE_Word element_size;
   WireCodecFunc w_value;
 
   switch (type)
@@ -102,19 +102,19 @@ w_option_value (Wire *w, SANE_Word type,
     case SANE_TYPE_FIXED:
       w_value = (WireCodecFunc) sanei_w_word;
       element_size = sizeof (SANE_Word);
-      len = size / element_size;
+      *len = size / element_size;
       break;
 
     case SANE_TYPE_STRING:
       w_value = (WireCodecFunc) sanei_w_char;
       element_size = sizeof (SANE_Char);
-      len = size;
+      *len = size;
       break;
 
     case SANE_TYPE_BUTTON:
     case SANE_TYPE_GROUP:
       w_value = (WireCodecFunc) sanei_w_void;
-      len = 0;
+      *len = 0;
       element_size = 0;
       break;
 
@@ -122,7 +122,7 @@ w_option_value (Wire *w, SANE_Word type,
       w->status = EINVAL;
       return;
     }
-  sanei_w_array (w, &len, value, w_value, element_size);
+  sanei_w_array (w, len, value, w_value, element_size);
 }
 
 void
@@ -146,7 +146,7 @@ sanei_w_control_option_req (Wire *w, SAN
     {
       sanei_w_word (w, &req->value_type);
       sanei_w_word (w, &req->value_size);
-      w_option_value (w, req->value_type, req->value_size, &req->value);
+      w_option_value (w, req->value_type, req->value_size, &req->value_length, &req->value);
     }
 }
 
@@ -157,7 +157,7 @@ sanei_w_control_option_reply (Wire *w, S
   sanei_w_word (w, &reply->info);
   sanei_w_word (w, &reply->value_type);
   sanei_w_word (w, &reply->value_size);
-  w_option_value (w, reply->value_type, reply->value_size, &reply->value);
+  w_option_value (w, reply->value_type, reply->value_size, &reply->value_length, &reply->value);
   sanei_w_string (w, &reply->resource_to_authorize);
 }