Skip to content

Commit 9dc64bd

Browse files
akihikodakijasowang
authored andcommitted
util/iov: Do not assert offset is in iov
iov_from_buf(), iov_to_buf(), iov_memset(), and iov_copy() asserts that the given offset fits in the iov while tolerating the specified number of bytes to operate with to be greater than the size of iov. This is inconsistent so remove the assertions. Asserting the offset fits in the iov makes sense if it is expected that there are other operations that process the content before the offset and the content is processed in order. Under this expectation, the offset should point to the end of bytes that are previously processed and fit in the iov. However, this expectation depends on the details of the caller, and did not hold true at least one case and required code to check iov_size(), which is added with commit 83ddb3d ("hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()"). Adding such a check is inefficient and error-prone. These functions already tolerate the specified number of bytes to operate with to be greater than the size of iov to avoid such checks so remove the assertions to tolerate invalid offset as well. They return the number of bytes they operated with so their callers can still check the returned value to ensure there are sufficient space at the given offset. Signed-off-by: Akihiko Odaki <[email protected]> Signed-off-by: Jason Wang <[email protected]>
1 parent e7891c5 commit 9dc64bd

File tree

2 files changed

+3
-7
lines changed

2 files changed

+3
-7
lines changed

include/qemu/iov.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
3131
* only part of data will be copied, up to the end of the iovec.
3232
* Number of bytes actually copied will be returned, which is
3333
* min(bytes, iov_size(iov)-offset)
34-
* `Offset' must point to the inside of iovec.
34+
* Returns 0 when `offset' points to the outside of iovec.
3535
*/
3636
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
3737
size_t offset, const void *buf, size_t bytes);
@@ -67,11 +67,12 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
6767
/**
6868
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
6969
* starting at byte offset `start', to value `fillc', repeating it
70-
* `bytes' number of times. `Offset' must point to the inside of iovec.
70+
* `bytes' number of times.
7171
* If `bytes' is large enough, only last bytes portion of iovec,
7272
* up to the end of it, will be filled with the specified value.
7373
* Function return actual number of bytes processed, which is
7474
* min(size, iov_size(iov) - offset).
75+
* Returns 0 when `offset' points to the outside of iovec.
7576
*/
7677
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
7778
size_t offset, int fillc, size_t bytes);

util/iov.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
3737
offset -= iov[i].iov_len;
3838
}
3939
}
40-
assert(offset == 0);
4140
return done;
4241
}
4342

@@ -56,7 +55,6 @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
5655
offset -= iov[i].iov_len;
5756
}
5857
}
59-
assert(offset == 0);
6058
return done;
6159
}
6260

@@ -75,7 +73,6 @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
7573
offset -= iov[i].iov_len;
7674
}
7775
}
78-
assert(offset == 0);
7976
return done;
8077
}
8178

@@ -277,7 +274,6 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
277274
bytes -= len;
278275
offset = 0;
279276
}
280-
assert(offset == 0);
281277
return j;
282278
}
283279

@@ -348,7 +344,6 @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
348344
soffset -= src_iov[i].iov_len;
349345
}
350346
}
351-
assert(soffset == 0); /* offset beyond end of src */
352347

353348
return done;
354349
}

0 commit comments

Comments
 (0)