From 226e283c3908947be9724187b338b3c9578e7380 Mon Sep 17 00:00:00 2001 From: Li Wei Date: Tue, 10 Sep 2024 23:00:14 +0900 Subject: [PATCH] DAOS-16251 object: Fix obj_ec_singv_split overflow (#15045) It has been seen that obj_ec_singv_split may read beyond the end of sgl->sg_iovs[0].iov_buf: iod_size=8569 c_bytes=4288 id_shard=0 tgt_off=1 iov_len=8569 iov_buf_len=8569 The memmove read 4288 bytes from offset 4288, whereas the buffer only had 8569 - 4288 = 4281 bytes from offset 4288. This patch fixes the problem by adding the min(...) expression. Signed-off-by: Li Wei --- src/object/cli_ec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/object/cli_ec.c b/src/object/cli_ec.c index bd5c7c1503b..c36d61c25cc 100644 --- a/src/object/cli_ec.c +++ b/src/object/cli_ec.c @@ -1408,13 +1408,15 @@ obj_ec_singv_split(daos_unit_oid_t oid, uint16_t layout_ver, struct daos_oclass_ { uint64_t c_bytes = obj_ec_singv_cell_bytes(iod_size, oca); uint32_t tgt_off = obj_ec_shard_off_by_layout_ver(layout_ver, dkey_hash, oca, oid.id_shard); + uint64_t tgt_size = min(c_bytes, iod_size - tgt_off * c_bytes); char *data = sgl->sg_iovs[0].iov_buf; - D_ASSERT(iod_size != DAOS_REC_ANY); + D_ASSERTF(iod_size != DAOS_REC_ANY && iod_size == sgl->sg_iovs[0].iov_len, + DF_U64 " == %zu\n", iod_size, sgl->sg_iovs[0].iov_len); if (tgt_off > 0) - memmove(data, data + tgt_off * c_bytes, c_bytes); + memmove(data, data + tgt_off * c_bytes, tgt_size); - sgl->sg_iovs[0].iov_len = c_bytes; + sgl->sg_iovs[0].iov_len = tgt_size; return 0; }