提交 8401d92b 编写于 作者: D David Moore 提交者: Stefan Richter

firewire: Preserve response data alignment bug when it is harmless

Recently, a bug having to do with the alignment of transaction response
data was fixed.  However, some apps such as libdc1394 relied on the
presence of that bug in order to function correctly.  In order to stay
compatible with old versions of those apps, this patch preserves the bug
in cases where it is harmless to normal operation (such as the single
quadlet read) due to a simple duplication of data.  This guarantees
maximum compatability for those users who are using the old app with the
fixed kernel.
Signed-off-by: NDavid Moore <dcm@acm.org>
Signed-off-by: NStefan Richter <stefanr@s5r6.in-berlin.de>
上级 f05e21b3
......@@ -369,22 +369,33 @@ 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,
NULL, 0);
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);
}
static int ioctl_send_request(struct client *client, void *buffer)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册