HEX_SYS_STAT could pass an unterminated local filename buffer to stat() when
the guest string filled it. Use lock_user_string() to safely map the guest 
string instead.

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

diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c
index cb6a061af16..18d73b491a0 100644
--- a/target/hexagon/hexswi.c
+++ b/target/hexagon/hexswi.c
@@ -544,20 +544,20 @@ static void sim_handle_trap0(CPUHexagonState *env)
         struct stat st_buf;
         uint8_t *st_bufptr = (uint8_t *)&sys_stat;
         int rc, err = 0;
-        char filename[BUFSIZ];
+        char *filename;
         target_ulong physical_filename_addr;
         target_ulong statBufferAddr;
         hexagon_read_memory(env, swi_info, 4, &physical_filename_addr, 
retaddr);
 
         if (what_swi == HEX_SYS_STAT) {
-            int i = 0;
-            do {
-                hexagon_read_memory(env, physical_filename_addr + i, 1,
-                                    &filename[i], retaddr);
-                i++;
-            } while ((i < BUFSIZ) && filename[i - 1]);
+            filename = lock_user_string(physical_filename_addr);
+            if (!filename) {
+                semi_cb(cs, -1, EFAULT);
+                break;
+            }
             rc = stat(filename, &st_buf);
             err = errno;
+            unlock_user(filename, physical_filename_addr, 0);
         } else {
             int fd = physical_filename_addr;
             GuestFD *gf = get_guestfd(fd);
-- 
2.34.1

Reply via email to