qiling icon indicating copy to clipboard operation
qiling copied to clipboard

POSIX ql_syscall_readv returns incorrect value.

Open iMoD1998 opened this issue 1 year ago • 0 comments

*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

iMoD1998 avatar Feb 02 '24 12:02 iMoD1998