qiling
qiling copied to clipboard
POSIX ql_syscall_readv returns incorrect value.
*Describe the bug
readv() according to the manpages should return the number of bytes read but it seems to return the size of the iovec everytime???
Sample Code
def ql_syscall_readv(ql: Qiling, fd: int, vec: int, vlen: int):
regreturn = 0
size_t_len = ql.arch.pointersize
iov = ql.mem.read(vec, vlen * size_t_len * 2)
ql.log.debug('readv() CONTENT:')
for i in range(vlen):
addr = ql.unpack(iov[i * size_t_len * 2 : i * size_t_len * 2 + size_t_len])
l = ql.unpack(iov[i * size_t_len * 2 + size_t_len : i * size_t_len * 2 + size_t_len * 2])
regreturn += l
if hasattr(ql.os.fd[fd], 'read'):
data = ql.os.fd[fd].read(l)
ql.log.debug(f'{data!r}')
ql.mem.write(addr, data)
return regreturn
Expected behavior
readv() should return the amount of bytes read from fd.
Proposed Change My solution that fixes this looks like the following:
def ql_syscall_readv(ql: Qiling, fd: int, vec: int, vlen: int):
regreturn = 0
size_t_len = ql.arch.pointersize
iov = ql.mem.read(vec, vlen * size_t_len * 2)
ql.log.debug('readv() CONTENT:')
for i in range(vlen):
addr = ql.unpack(iov[i * size_t_len * 2 : i * size_t_len * 2 + size_t_len])
l = ql.unpack(iov[i * size_t_len * 2 + size_t_len : i * size_t_len * 2 + size_t_len * 2])
if hasattr(ql.os.fd[fd], 'read'):
data = ql.os.fd[fd].read(l)
ql.log.debug(f'{data!r}')
ql.mem.write(addr, data)
regreturn += len(data)
return regreturn