diff mbox series

[1/4] linux-user: Fix fcntl64() to return O_LARGEFILE for 32-bit targets

Message ID 20230707131928.89500-2-deller@gmx.de (mailing list archive)
State New, archived
Headers show
Series linux-user: Fix fcntl64() and accept4() for 32-bit targets | expand

Commit Message

Helge Deller July 7, 2023, 1:19 p.m. UTC
On a 64-bit host, O_LARGEFILE has the value 0.
When running a 32-bit guest on a 64-bit host, fcntl64(F_GETFL) should
return with the O_LARGEFILE flag set, because the 64-bit host supports
large files unconditionally.

The flag translation should have happened in do_fcntl(), but since O_LARGEFILE
is zero for 64-bit hosts, the translation can't be done with the
translation table.

Fix it by setting the TARGET_O_LARGEFILE flag unconditionally for
32-bit guests on 64-bit hosts when fcntl64() is called.

Signed-off-by: Helge Deller <deller@gmx.de>
---
 linux-user/syscall.c | 9 +++++++++
 1 file changed, 9 insertions(+)

--
2.41.0

Comments

Richard Henderson July 7, 2023, 8:12 p.m. UTC | #1
On 7/7/23 14:19, Helge Deller wrote:
> On a 64-bit host, O_LARGEFILE has the value 0.
> When running a 32-bit guest on a 64-bit host, fcntl64(F_GETFL) should
> return with the O_LARGEFILE flag set, because the 64-bit host supports
> large files unconditionally.
> 
> The flag translation should have happened in do_fcntl(), but since O_LARGEFILE
> is zero for 64-bit hosts, the translation can't be done with the
> translation table.

But surely add the code to do_fcntl, right after the host_to_target_bitmask, so that it's 
present for fcntl64 as well?


r~

> 
> Fix it by setting the TARGET_O_LARGEFILE flag unconditionally for
> 32-bit guests on 64-bit hosts when fcntl64() is called.
> 
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
>   linux-user/syscall.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 08162cc966..3f1e8e7ad9 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -12328,6 +12328,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
>           }
> 
>           switch(arg2) {
> +#if HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 && \
> +    O_LARGEFILE == 0     && TARGET_O_LARGEFILE != 0
> +        case TARGET_F_GETFL:
> +            ret = do_fcntl(arg1, arg2, arg3);
> +            if (ret > 0) {
> +                ret |= TARGET_O_LARGEFILE;
> +            }
> +	    break;
> +#endif
>           case TARGET_F_GETLK64:
>               ret = copyfrom(&fl, arg3);
>               if (ret) {
> --
> 2.41.0
>
diff mbox series

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 08162cc966..3f1e8e7ad9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12328,6 +12328,15 @@  static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
         }

         switch(arg2) {
+#if HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 && \
+    O_LARGEFILE == 0     && TARGET_O_LARGEFILE != 0
+        case TARGET_F_GETFL:
+            ret = do_fcntl(arg1, arg2, arg3);
+            if (ret > 0) {
+                ret |= TARGET_O_LARGEFILE;
+            }
+	    break;
+#endif
         case TARGET_F_GETLK64:
             ret = copyfrom(&fl, arg3);
             if (ret) {