Commit f71e1cc1 authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 34db1f91
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -655,7 +655,6 @@ static void gb_connection_recv_response(struct gb_connection *connection,
{
	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,18 +667,16 @@ static void gb_connection_recv_response(struct gb_connection *connection,
	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)
	if (result)
		size = sizeof(*message->header);
	memcpy(message->header, data, size);

	/* The rest will be handled in work queue context */