提交 693fa779 编写于 作者: C Clemens Ladisch 提交者: Stefan Richter

firewire: ohci: fix race when reading count in AR descriptor

If the controller is storing a split packet and therefore changing
d->res_count to zero between the two reads by the driver, we end up with
an end pointer that is not at a packet boundary, and therefore overflow
the buffer when handling the split packet.

To fix this, read the field once, atomically.  The compiler usually
merges the two reads anyway, but for correctness, we have to enforce it.
Signed-off-by: NClemens Ladisch <clemens@ladisch.de>
Tested-by: NMaxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: NStefan Richter <stefanr@s5r6.in-berlin.de>
上级 837596a6
......@@ -740,11 +740,13 @@ static void ar_context_tasklet(unsigned long data)
struct ar_buffer *ab;
struct descriptor *d;
void *buffer, *end;
__le16 res_count;
ab = ctx->current_buffer;
d = &ab->descriptor;
if (d->res_count == 0) {
res_count = ACCESS_ONCE(d->res_count);
if (res_count == 0) {
size_t size, size2, rest, pktsize, size3, offset;
dma_addr_t start_bus;
void *start;
......@@ -812,7 +814,7 @@ static void ar_context_tasklet(unsigned long data)
} else {
buffer = ctx->pointer;
ctx->pointer = end =
(void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count);
(void *) ab + PAGE_SIZE - le16_to_cpu(res_count);
while (buffer < end)
buffer = handle_ar_packet(ctx, buffer);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册