greybus: short message is OK for errors

We enforce a rule that a response message must completely fill the
buffer that's been allocated to hold it.  However, if an error
occurs, the payload is off limits, so we should allow a short
message to convey an error result.

Change gb_connection_recv_response() to require the right message
size only if there's no error.

One other thing:  The arriving data is only being copied into the
response buffer if the request was successful.  That means the
response message header is assumed to have been initialized.  That
isn't a valid assumption.  So change it so that if an error is
seen, the header portion of the message is copied into the
response buffer--but only the header.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
index 1e0ce7d..2fd60cc 100644
--- a/drivers/staging/greybus/operation.c
+++ b/drivers/staging/greybus/operation.c
@@ -655,7 +655,6 @@
 {
 	struct gb_operation *operation;
 	struct gb_message *message;
-	struct gb_operation_msg_hdr *header;
 	int result;
 
 	operation = gb_pending_operation_find(connection, operation_id);
@@ -668,19 +667,17 @@
 	gb_pending_operation_remove(operation);
 
 	message = operation->response;
-	if (size == message->size) {
-		/* Transfer the operation result from the response header */
-		header = message->header;
-		result = gb_operation_status_map(header->result);
-	} else {
+	result = gb_operation_status_map(message->header->result);
+	if (!result && size != message->size) {
 		gb_connection_err(connection, "bad message size (%zu != %zu)",
 			size, message->size);
 		result = -EMSGSIZE;
 	}
 
 	/* We must ignore the payload if a bad status is returned */
-	if (!result)
-		memcpy(message->header, data, size);
+	if (result)
+		size = sizeof(*message->header);
+	memcpy(message->header, data, size);
 
 	/* The rest will be handled in work queue context */
 	if (gb_operation_result_set(operation, result))