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);
}