Skip to content

Commit

Permalink
fix: coverity issue 1595331 [readv]
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Aug 2, 2024
1 parent d249cd7 commit 4dfc285
Showing 1 changed file with 79 additions and 29 deletions.
108 changes: 79 additions & 29 deletions src/tebako-fd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,26 +289,48 @@ ssize_t sync_tebako_fdtable::readv(int vfd,
const struct iovec* iov,
int iovcnt) noexcept
{
uint32_t ino;
off_t pos;
// Some specific error conditions:
// EOVERFLOW - the resulting file offset cannot be represented in an off_t.
// EINVAL - the sum of the iov_len values overflows an ssize_t value.
// EINVAL - the vector count, iovcnt, is less than zero or greater
// than the permitted maximum.

ssize_t ret = DWARFS_INVALID_FD;
auto p_fdtable = *rlock();
auto p_fd = p_fdtable->find(vfd);
if (p_fd != p_fdtable->end()) {
ret = 0;
for (int i = 0; i < iovcnt; ++i) {
ssize_t ssize =
dwarfs_inode_read(p_fd->second->st.st_ino, iov[i].iov_base,
iov[i].iov_len, p_fd->second->pos);
if (ssize > 0) {
p_fd->second->pos += ssize;
ret += ssize;
}
else {
if (ssize < 0) {
ret = DWARFS_IO_ERROR;
if (iovcnt < 0) {
TEBAKO_SET_LAST_ERROR(EINVAL);
ret = DWARFS_IO_ERROR;

Check warning on line 301 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L300-L301

Added lines #L300 - L301 were not covered by tests
}
else {
uint32_t ino;
off_t pos;
auto p_fdtable = *rlock();
auto p_fd = p_fdtable->find(vfd);
if (p_fd != p_fdtable->end()) {
ret = 0;
for (int i = 0; i < iovcnt; ++i) {
ssize_t ssize =
dwarfs_inode_read(p_fd->second->st.st_ino, iov[i].iov_base,
iov[i].iov_len, p_fd->second->pos);
if (ssize > 0) {
if (p_fd->second->pos > SIZE_MAX - ssize) {
TEBAKO_SET_LAST_ERROR(EOVERFLOW);
ret = DWARFS_IO_ERROR;
break;

Check warning on line 318 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L316-L318

Added lines #L316 - L318 were not covered by tests
}
if (ret > SIZE_MAX - ssize) {
TEBAKO_SET_LAST_ERROR(EINVAL);
ret = DWARFS_IO_ERROR;
break;

Check warning on line 323 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L321-L323

Added lines #L321 - L323 were not covered by tests
}
p_fd->second->pos += ssize;
ret += ssize;
}
else {
if (ssize < 0) {
ret = DWARFS_IO_ERROR;

Check warning on line 330 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L330

Added line #L330 was not covered by tests
}
break;
}
break;
}
}
}
Expand All @@ -323,25 +345,53 @@ off_t sync_tebako_fdtable::lseek(int vfd, off_t offset, int whence) noexcept
if (p_fd != p_fdtable->end()) {
switch (whence) {
case SEEK_SET:
ret = p_fd->second->pos = offset;
if (offset < 0) {
// [EINVAL] The resulting file offset would be negative for a regular
// file, block special file, or directory.
TEBAKO_SET_LAST_ERROR(EINVAL);
ret = DWARFS_IO_ERROR;

Check warning on line 352 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L351-L352

Added lines #L351 - L352 were not covered by tests
}
else {
ret = p_fd->second->pos = offset;
}
break;
case SEEK_CUR:
ret = p_fd->second->pos = p_fd->second->pos + offset;
if (ret < 0) {
// [EOVERFLOW] The resulting file offset would be a value which cannot
// be represented correctly in an object of type off_t.
TEBAKO_SET_LAST_ERROR(EOVERFLOW);
if (offset < 0 && p_fd->second->pos < -offset) {
// [EINVAL] The resulting file offset would be negative for a regular
// file, block special file, or directory.
TEBAKO_SET_LAST_ERROR(EINVAL);

Check warning on line 362 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L362

Added line #L362 was not covered by tests
ret = DWARFS_IO_ERROR;
}
else {
if (p_fd->second->pos > SIZE_MAX + offset) {
// [EOVERFLOW] The resulting file offset would be a value which
// cannot be represented correctly in an object of type off_t.
TEBAKO_SET_LAST_ERROR(EOVERFLOW);
ret = DWARFS_IO_ERROR;

Check warning on line 370 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L369-L370

Added lines #L369 - L370 were not covered by tests
}
else {
ret = p_fd->second->pos = p_fd->second->pos + offset;
}
}
break;
case SEEK_END:
ret = p_fd->second->pos = p_fd->second->st.st_size + offset;
if (ret < 0) {
// [EOVERFLOW] The resulting file offset would be a value which cannot
// be represented correctly in an object of type off_t.
TEBAKO_SET_LAST_ERROR(EOVERFLOW);
if (offset < 0 && p_fd->second->st.st_size < -offset) {
// [EINVAL] The resulting file offset would be negative for a regular
// file, block special file, or directory.
TEBAKO_SET_LAST_ERROR(EINVAL);

Check warning on line 381 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L381

Added line #L381 was not covered by tests
ret = DWARFS_IO_ERROR;
}
else {
if (p_fd->second->st.st_size > SIZE_MAX - offset) {
// [EOVERFLOW] The resulting file offset would be a value which
// cannot be represented correctly in an object of type off_t.
TEBAKO_SET_LAST_ERROR(EOVERFLOW);
ret = DWARFS_IO_ERROR;

Check warning on line 389 in src/tebako-fd.cpp

View check run for this annotation

Codecov / codecov/patch

src/tebako-fd.cpp#L388-L389

Added lines #L388 - L389 were not covered by tests
}
else {
ret = p_fd->second->pos = p_fd->second->st.st_size + offset;
}
}
break;
default:
// [EINVAL] The whence argument is not a proper value, or the resulting
Expand Down

0 comments on commit 4dfc285

Please sign in to comment.