summaryrefslogtreecommitdiff
path: root/libstore/device.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-16 22:22:16 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-16 22:23:36 +0200
commit21d99ce0cfefc82039f9bd45bd9d12eb47966992 (patch)
treeac40d91f4eaec264bf2957911dd585f7944df5dc /libstore/device.c
parent7e176f23511446bc33f4e43fd098ddb73acd8146 (diff)
libstore: Detect device-based access overflow
recnum_t is 32bit while offsets are 64bit. We need to detect the otherwise-silent truncation of the address. This happens here at 2TiB for 512-byte sectors. * libstore/device.c (dev_read, dev_write): Return EOVERFLOW on addresses that are larger than what the device interface can handle.
Diffstat (limited to 'libstore/device.c')
-rw-r--r--libstore/device.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/libstore/device.c b/libstore/device.c
index 0d4ca477..098506a0 100644
--- a/libstore/device.c
+++ b/libstore/device.c
@@ -52,7 +52,12 @@ dev_read (struct store *store,
store_offset_t addr, size_t index, mach_msg_type_number_t amount,
void **buf, mach_msg_type_number_t *len)
{
- return dev_error (device_read (store->port, 0, addr, amount,
+ recnum_t recnum = addr;
+
+ if (recnum != addr)
+ return EOVERFLOW;
+
+ return dev_error (device_read (store->port, 0, recnum, amount,
(io_buf_ptr_t *)buf, len));
}
@@ -62,10 +67,17 @@ dev_write (struct store *store,
const void *buf, mach_msg_type_number_t len,
mach_msg_type_number_t *amount)
{
- error_t err = dev_error (device_write (store->port, 0, addr,
+ recnum_t recnum = addr;
+ error_t err;
+ int amount_r;
+
+ if (recnum != addr)
+ return EOVERFLOW;
+
+ err = dev_error (device_write (store->port, 0, addr,
(io_buf_ptr_t)buf, len,
- (int *) amount));
- *amount = *(int *) amount; /* stupid device.defs uses int */
+ &amount_r));
+ *amount = amount_r;
return err;
}