Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a14ad05f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: Preserve response data alignment bug when it is harmless
parents 0016fe9d 8401d92b
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -369,21 +369,32 @@ complete_transaction(struct fw_card *card, int rcode,
	struct response *response = data;
	struct client *client = response->client;
	unsigned long flags;
	struct fw_cdev_event_response *r = &response->response;

	if (length < response->response.length)
		response->response.length = length;
	if (length < r->length)
		r->length = length;
	if (rcode == RCODE_COMPLETE)
		memcpy(response->response.data, payload,
		       response->response.length);
		memcpy(r->data, payload, r->length);

	spin_lock_irqsave(&client->lock, flags);
	list_del(&response->resource.link);
	spin_unlock_irqrestore(&client->lock, flags);

	response->response.type   = FW_CDEV_EVENT_RESPONSE;
	response->response.rcode  = rcode;
	queue_event(client, &response->event, &response->response,
		    sizeof(response->response) + response->response.length,
	r->type   = FW_CDEV_EVENT_RESPONSE;
	r->rcode  = rcode;

	/*
	 * In the case that sizeof(*r) doesn't align with the position of the
	 * data, and the read is short, preserve an extra copy of the data
	 * to stay compatible with a pre-2.6.27 bug.  Since the bug is harmless
	 * for short reads and some apps depended on it, this is both safe
	 * and prudent for compatibility.
	 */
	if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
		queue_event(client, &response->event, r, sizeof(*r),
			    r->data, r->length);
	else
		queue_event(client, &response->event, r, sizeof(*r) + r->length,
			    NULL, 0);
}