HEX_SYS_ACCESS wrote a NUL byte past its fixed-size filename buffer when
the guest string filled it. Use lock_user_string() to avoid the out-of-bounds
write.

Fixes: 7711fdba88b ("target/hexagon: add main arch-specific semihosting 
operations")
Resolves: Coverity CID 1685942
Link: 
https://lore.kernel.org/all/cafeaca9mos6vfhf2uhz8z4cdvab+7dy6hjb2emyz2alse-t...@mail.gmail.com/
Suggested-by: Peter Maydell <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/hexswi.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c
index a5c8ee27c7e..9ff72253385 100644
--- a/target/hexagon/hexswi.c
+++ b/target/hexagon/hexswi.c
@@ -626,26 +626,24 @@ static void sim_handle_trap0(CPUHexagonState *env)
 
     case HEX_SYS_ACCESS:
     {
-        char filename[BUFSIZ];
+        char *filename;
         uint32_t FileNameAddr;
         uint32_t BufferMode;
-        int rc;
-
-        int i = 0;
+        int rc, err;
 
         if (get_user_u32(FileNameAddr, swi_info) ||
             get_user_u32(BufferMode, swi_info + 4)) {
             goto do_fault;
         }
-        do {
-            if (get_user_u8(filename[i], FileNameAddr + i)) {
-                goto do_fault;
-            }
-            i++;
-        } while ((i < BUFSIZ) && (filename[i - 1]));
-        filename[i] = 0;
+        filename = lock_user_string(FileNameAddr);
+        if (!filename) {
+            semi_cb(cs, -1, EFAULT);
+            break;
+        }
         rc = access(filename, BufferMode);
-        semi_cb(cs, rc,  rc == 0 ? 0 : errno);
+        err = errno;
+        unlock_user(filename, FileNameAddr, 0);
+        semi_cb(cs, rc,  rc == 0 ? 0 : err);
     }
     break;
 
-- 
2.34.1

Reply via email to