From 107e8f3d17de6729c2115cdf2ed6406bad783c04 Mon Sep 17 00:00:00 2001 From: Tiberiu Bucur Date: Tue, 20 Aug 2024 15:17:51 +0100 Subject: [PATCH] arch, sim-se: Fix size_t size mismatch bug Same as with the off_t, some syscalls were using incorrect size parametres in place of a guest-defined size_t. This commit changes the signature of said syscalls and adds the size_t typedef to the arch-dependent Linux OSs. Change-Id: Iece43814971a8e6275d25f6789e41528d241d1f4 Reviewed-by: Giacomo Travaglini --- src/arch/arm/linux/se_workload.cc | 12 ++++---- src/arch/mips/linux/linux.hh | 1 + src/arch/mips/linux/se_workload.cc | 2 +- src/arch/riscv/linux/se_workload.cc | 4 +-- src/arch/sparc/linux/linux.hh | 2 ++ src/arch/sparc/linux/syscalls.cc | 2 +- src/arch/x86/linux/syscall_tbl32.cc | 2 +- src/arch/x86/linux/syscall_tbl64.cc | 2 +- src/sim/syscall_emul.cc | 30 ------------------ src/sim/syscall_emul.hh | 47 +++++++++++++++++++++++------ 10 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/arch/arm/linux/se_workload.cc b/src/arch/arm/linux/se_workload.cc index ef9c9136dc..e2df5374a6 100644 --- a/src/arch/arm/linux/se_workload.cc +++ b/src/arch/arm/linux/se_workload.cc @@ -305,10 +305,10 @@ class SyscallTable32 : public SyscallDescTable { base + 177, "rt_sigtimedwait" }, { base + 178, "rt_sigqueueinfo", ignoreFunc }, { base + 179, "rt_sigsuspend" }, - { base + 180, "pread64" }, - { base + 181, "pwrite64" }, + { base + 180, "pread64", pread64Func }, + { base + 181, "pwrite64", pwrite64Func }, { base + 182, "chown" }, - { base + 183, "getcwd", getcwdFunc }, + { base + 183, "getcwd", getcwdFunc }, { base + 184, "capget" }, { base + 185, "capset" }, { base + 186, "sigaltstack" }, @@ -518,7 +518,7 @@ class SyscallTable64 : public SyscallDescTable { base + 14, "removexattr" }, { base + 15, "lremovexattr" }, { base + 16, "fremovexattr" }, - { base + 17, "getcwd", getcwdFunc }, + { base + 17, "getcwd", getcwdFunc }, { base + 18, "lookup_dcookie" }, { base + 19, "eventfd2" }, { base + 20, "epoll_create1" }, @@ -572,8 +572,8 @@ class SyscallTable64 : public SyscallDescTable { base + 64, "write", writeFunc }, { base + 65, "readv" }, { base + 66, "writev", writevFunc }, - { base + 67, "pread64" }, - { base + 68, "pwrite64" }, + { base + 67, "pread64", pread64Func }, + { base + 68, "pwrite64", pwrite64Func }, { base + 69, "preadv" }, { base + 70, "pwritev" }, { base + 71, "sendfile64" }, diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index 393cceaedd..543cdb05b0 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -203,6 +203,7 @@ class MipsLinux : public Linux, public OpenFlagTable uint32_t mem_unit; /* Memory unit size in bytes */ }; + typedef uint32_t size_t; typedef int32_t off_t; }; diff --git a/src/arch/mips/linux/se_workload.cc b/src/arch/mips/linux/se_workload.cc index 0cb59d2f26..a7aedbc0e6 100644 --- a/src/arch/mips/linux/se_workload.cc +++ b/src/arch/mips/linux/se_workload.cc @@ -372,7 +372,7 @@ SyscallDescTable EmuLinux::syscallDescs = { { 4200, "pread64" }, { 4201, "pwrite64" }, { 4202, "chown" }, - { 4203, "getcwd", getcwdFunc }, + { 4203, "getcwd", getcwdFunc }, { 4204, "capget" }, { 4205, "capset" }, { 4206, "sigalstack" }, diff --git a/src/arch/riscv/linux/se_workload.cc b/src/arch/riscv/linux/se_workload.cc index acd7d7c094..c1af16fb3b 100644 --- a/src/arch/riscv/linux/se_workload.cc +++ b/src/arch/riscv/linux/se_workload.cc @@ -152,7 +152,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { { 14, "removexattr" }, { 15, "lremovexattr" }, { 16, "fremovexattr" }, - { 17, "getcwd", getcwdFunc }, + { 17, "getcwd", getcwdFunc }, { 18, "lookup_dcookie" }, { 19, "eventfd2" }, { 20, "epoll_create1" }, @@ -491,7 +491,7 @@ SyscallDescTable EmuLinux::syscallDescs32 = { { 14, "removexattr" }, { 15, "lremovexattr" }, { 16, "fremovexattr" }, - { 17, "getcwd", getcwdFunc }, + { 17, "getcwd", getcwdFunc }, { 18, "lookup_dcookie" }, { 19, "eventfd2" }, { 20, "epoll_create1" }, diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index eae4651e99..e609031e8b 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -254,6 +254,7 @@ class SparcLinux : public Linux, public OpenFlagTable ctc->setReg(SparcISA::SyscallPseudoReturnReg, 1); } + typedef uint64_t size_t; typedef int64_t off_t; }; @@ -301,6 +302,7 @@ class Sparc32Linux : public SparcLinux uint32_t mem_unit; /* Memory unit size in bytes */ }; + typedef uint32_t size_t; typedef int32_t off_t; /// Resource constants for getrlimit() (overide some generics). diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 1b5be17fca..2ff0fa1a1e 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -215,7 +215,7 @@ SyscallDescTable EmuLinux::syscall32Descs = { { 116, "gettimeofday", gettimeofdayFunc }, // 32 bit { 117, "getrusage" }, // 32 bit { 118, "getsockopt" }, - { 119, "getcwd", getcwdFunc }, + { 119, "getcwd", getcwdFunc }, { 120, "readv" }, { 121, "writev" }, { 122, "settimeofday" }, // 32 bit diff --git a/src/arch/x86/linux/syscall_tbl32.cc b/src/arch/x86/linux/syscall_tbl32.cc index 02f12f1014..bf5d03e7b5 100644 --- a/src/arch/x86/linux/syscall_tbl32.cc +++ b/src/arch/x86/linux/syscall_tbl32.cc @@ -237,7 +237,7 @@ SyscallDescTable EmuLinux::syscallDescs32 = { { 180, "pread64", pread64Func }, { 181, "pwrite64", pwrite64Func }, { 182, "chown" }, - { 183, "getcwd", getcwdFunc }, + { 183, "getcwd", getcwdFunc }, { 184, "capget" }, { 185, "capset" }, { 186, "sigaltstack" }, diff --git a/src/arch/x86/linux/syscall_tbl64.cc b/src/arch/x86/linux/syscall_tbl64.cc index c8bd28ced1..1c3eebd63d 100644 --- a/src/arch/x86/linux/syscall_tbl64.cc +++ b/src/arch/x86/linux/syscall_tbl64.cc @@ -133,7 +133,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { #else { 78, "getdents" }, #endif - { 79, "getcwd", getcwdFunc }, + { 79, "getcwd", getcwdFunc }, { 80, "chdir", chdirFunc }, { 81, "fchdir" }, { 82, "rename", renameFunc }, diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 28fe4798ae..13f7cf09fb 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -344,36 +344,6 @@ gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, return 0; } -SyscallReturn -getcwdFunc(SyscallDesc *desc, ThreadContext *tc, - VPtr<> buf_ptr, unsigned long size) -{ - int result = 0; - auto p = tc->getProcessPtr(); - BufferArg buf(buf_ptr, size); - - // Is current working directory defined? - std::string cwd = p->tgtCwd; - if (!cwd.empty()) { - if (cwd.length() >= size) { - // Buffer too small - return -ERANGE; - } - strncpy((char *)buf.bufferPtr(), cwd.c_str(), size); - result = cwd.length(); - } else { - if (getcwd((char *)buf.bufferPtr(), size)) { - result = strlen((char *)buf.bufferPtr()); - } else { - result = -1; - } - } - - buf.copyOut(SETranslatingPortProxy(tc)); - - return (result == -1) ? -errno : result; -} - SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname) { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 37d4a598eb..02d032bcd7 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -173,10 +173,6 @@ SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc, SyscallReturn gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, int name_len); -/// Target getcwd() handler. -SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc, - VPtr<> buf_ptr, unsigned long size); - /// Target unlink() handler. SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname); @@ -972,6 +968,38 @@ openFunc(SyscallDesc *desc, ThreadContext *tc, desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags, mode); } +/// Target getcwd() handler +template +SyscallReturn +getcwdFunc(SyscallDesc *desc, ThreadContext *tc, + VPtr<> buf_ptr, typename OS::size_t size) +{ + int result = 0; + auto p = tc->getProcessPtr(); + BufferArg buf(buf_ptr, size); + + // Is current working directory defined? + std::string cwd = p->tgtCwd; + if (!cwd.empty()) { + if (cwd.length() >= size) { + // Buffer too small + return -ERANGE; + } + strncpy((char *)buf.bufferPtr(), cwd.c_str(), size); + result = cwd.length(); + } else { + if (getcwd((char *)buf.bufferPtr(), size)) { + result = strlen((char *)buf.bufferPtr()); + } else { + result = -1; + } + } + + buf.copyOut(SETranslatingPortProxy(tc)); + + return (result == -1) ? -errno : result; +} + /// Target lseek() handler template SyscallReturn @@ -1341,7 +1369,8 @@ fchmodFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t mode) template SyscallReturn mremapFunc(SyscallDesc *desc, ThreadContext *tc, - VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t flags, + VPtr<> start, typename OS::size_t old_length, + typename OS::size_t new_length, int flags, guest_abi::VarArgs varargs) { auto p = tc->getProcessPtr(); @@ -2106,7 +2135,7 @@ mmapFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn pread64Func(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> bufPtr, int nbytes, + int tgt_fd, VPtr<> bufPtr, typename OS::size_t nbytes, typename OS::off_t offset) { auto p = tc->getProcessPtr(); @@ -2128,7 +2157,7 @@ pread64Func(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn pwrite64Func(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> bufPtr, int nbytes, + int tgt_fd, VPtr<> bufPtr, typename OS::size_t nbytes, typename OS::off_t offset) { auto p = tc->getProcessPtr(); @@ -2762,7 +2791,7 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, int nfds, template SyscallReturn readFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> buf_ptr, int nbytes) + int tgt_fd, VPtr<> buf_ptr, typename OS::size_t nbytes) { auto p = tc->getProcessPtr(); @@ -2790,7 +2819,7 @@ readFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn writeFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> buf_ptr, int nbytes) + int tgt_fd, VPtr<> buf_ptr, typename OS::size_t nbytes) { auto p = tc->getProcessPtr();