Fix stack corruption during juju lock transactions
When performing a lock transaction (such as with fw_lock) under Juju, 4 bytes of the stack gets corrupted. This is because the lock transaction has 8 bytes of data sent and 4 bytes received. Since the transaction "length" is specified as 8, handle_device_event() copies 8 bytes into the destination variable instead of the desired 4, and overflows into the stack by 4 bytes. This patch fixes the corruption by adding an extra "out_length" argument to the send_request() function so that both in_length and out_length can be specified separately. Signed-off-by: Dan Dennedy <dan@dennedy.org>
This commit is contained in:
parent
d69397ae8f
commit
cb8b7bf86a
32
src/fw.c
32
src/fw.c
|
@ -928,7 +928,8 @@ fw_start_phy_packet_write(fw_handle_t handle,
|
||||||
static int
|
static int
|
||||||
send_request(fw_handle_t handle, int tcode,
|
send_request(fw_handle_t handle, int tcode,
|
||||||
nodeid_t node, nodeaddr_t addr,
|
nodeid_t node, nodeaddr_t addr,
|
||||||
size_t length, void *in, void *out, unsigned long tag)
|
size_t in_length, void *in, size_t out_length, void *out,
|
||||||
|
unsigned long tag)
|
||||||
{
|
{
|
||||||
struct fw_cdev_send_request *request;
|
struct fw_cdev_send_request *request;
|
||||||
struct request_closure *closure;
|
struct request_closure *closure;
|
||||||
|
@ -961,14 +962,14 @@ send_request(fw_handle_t handle, int tcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
closure->data = out;
|
closure->data = out;
|
||||||
closure->length = length;
|
closure->length = out_length;
|
||||||
closure->tag = tag;
|
closure->tag = tag;
|
||||||
|
|
||||||
request = (struct fw_cdev_send_request *) handle->buffer;
|
request = (struct fw_cdev_send_request *) handle->buffer;
|
||||||
request->tcode = tcode;
|
request->tcode = tcode;
|
||||||
request->generation = handle->generation;
|
request->generation = handle->generation;
|
||||||
request->offset = addr;
|
request->offset = addr;
|
||||||
request->length = length;
|
request->length = in_length > out_length ? in_length : out_length;
|
||||||
request->closure = ptr_to_u64(closure);
|
request->closure = ptr_to_u64(closure);
|
||||||
request->data = ptr_to_u64(in);
|
request->data = ptr_to_u64(in);
|
||||||
|
|
||||||
|
@ -987,7 +988,7 @@ fw_start_read(fw_handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
tcode = TCODE_READ_BLOCK_REQUEST;
|
tcode = TCODE_READ_BLOCK_REQUEST;
|
||||||
|
|
||||||
return send_request(handle, tcode,
|
return send_request(handle, tcode,
|
||||||
node, addr, length, NULL, buffer, tag);
|
node, addr, 0, NULL, length, buffer, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1002,7 +1003,7 @@ fw_start_write(fw_handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
tcode = TCODE_WRITE_BLOCK_REQUEST;
|
tcode = TCODE_WRITE_BLOCK_REQUEST;
|
||||||
|
|
||||||
return send_request(handle, tcode,
|
return send_request(handle, tcode,
|
||||||
node, addr, length, data, NULL, tag);
|
node, addr, length, data, 0, NULL, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1064,7 +1065,8 @@ fw_start_lock(fw_handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
return send_request(handle, 16 + extcode,
|
return send_request(handle, 16 + extcode,
|
||||||
node, addr, length, buffer, result, tag);
|
node, addr, length, buffer,
|
||||||
|
sizeof *result, result, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1080,7 +1082,8 @@ fw_start_lock64(fw_handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
return send_request(handle, 16 + extcode,
|
return send_request(handle, 16 + extcode,
|
||||||
node, addr, length, buffer, result, tag);
|
node, addr, length, buffer,
|
||||||
|
sizeof *result, result, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1123,7 +1126,7 @@ sync_callback(raw1394handle_t handle, void *data, raw1394_errcode_t err)
|
||||||
static int
|
static int
|
||||||
send_request_sync(raw1394handle_t handle, int tcode,
|
send_request_sync(raw1394handle_t handle, int tcode,
|
||||||
nodeid_t node, nodeaddr_t addr,
|
nodeid_t node, nodeaddr_t addr,
|
||||||
size_t length, void *in, void *out)
|
size_t in_length, void *in, size_t out_length, void *out)
|
||||||
{
|
{
|
||||||
fw_handle_t fwhandle = handle->mode.fw;
|
fw_handle_t fwhandle = handle->mode.fw;
|
||||||
struct raw1394_reqhandle reqhandle;
|
struct raw1394_reqhandle reqhandle;
|
||||||
|
@ -1134,7 +1137,8 @@ send_request_sync(raw1394handle_t handle, int tcode,
|
||||||
reqhandle.data = &sd;
|
reqhandle.data = &sd;
|
||||||
|
|
||||||
err = send_request(fwhandle, tcode, node, addr,
|
err = send_request(fwhandle, tcode, node, addr,
|
||||||
length, in, out, (unsigned long) &reqhandle);
|
in_length, in, out_length, out,
|
||||||
|
(unsigned long) &reqhandle);
|
||||||
|
|
||||||
while (!sd.done) {
|
while (!sd.done) {
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -1160,7 +1164,7 @@ fw_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
tcode = TCODE_READ_BLOCK_REQUEST;
|
tcode = TCODE_READ_BLOCK_REQUEST;
|
||||||
|
|
||||||
return send_request_sync(handle, tcode,
|
return send_request_sync(handle, tcode,
|
||||||
node, addr, length, NULL, buffer);
|
node, addr, 0, NULL, length, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1175,7 +1179,7 @@ fw_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
tcode = TCODE_WRITE_BLOCK_REQUEST;
|
tcode = TCODE_WRITE_BLOCK_REQUEST;
|
||||||
|
|
||||||
return send_request_sync(handle, tcode,
|
return send_request_sync(handle, tcode,
|
||||||
node, addr, length, data, NULL);
|
node, addr, length, data, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1191,7 +1195,8 @@ fw_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
return send_request_sync(handle, 16 + extcode, node, addr,
|
return send_request_sync(handle, 16 + extcode, node, addr,
|
||||||
(size_t) length, buffer, result);
|
(size_t) length, buffer,
|
||||||
|
sizeof *result, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1207,7 +1212,8 @@ fw_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
return send_request_sync(handle, 16 + extcode, node, addr,
|
return send_request_sync(handle, 16 + extcode, node, addr,
|
||||||
(size_t) length, buffer, result);
|
(size_t) length, buffer,
|
||||||
|
sizeof *result, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Reference in New Issue