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