qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Qemu-arm] getdents patch for 64-bit app on 32-bit host


From: Peter Maydell
Subject: Re: [Qemu-devel] [Qemu-arm] getdents patch for 64-bit app on 32-bit host
Date: Thu, 19 Apr 2018 12:58:40 +0100

On 19 April 2018 at 12:11, Daniel P. Berrangé <address@hidden> wrote:
> If we can't even get something common like dirents working with 64-bit
> guest on 32-bit host, should we refuse to even build 64-bit linux-user
> emulation on a 32-bit host ?  There must be many other similar cases
> where the 64-bit guest syscall is going have insufficient space in the
> host 32-bit syscall structs.

Most of those are OK because you know in advance the size of
the structures, so you can tell the host the buffer length
is smaller, giving you room for the conversion.

Note also that this only happens for NR_getdents, not NR_getdents64,
because in the latter case the structs are always the same size.
So an AArch64 guest would be fine.

Thinking about the getdents problem, I was wondering if we could
manage to calculate a suitable host buffer size based on the worst
case. dirent for a 32-bit host is 12 bytes, and for a 64-bit host
is 24 bytes (plus potentially extra for the name strings). So
we will need an extra 12 bytes per record. The worst case is
when the names are all short enough to fit in the padding inside
the structure, which means bufsize / 24 records in the buffer;
so if we provide the host with a buffer size of bufsize / 24 * 12
 == bufsize / 2 then we know the host can't give us back more
records than we can fit in the guest buffer. We would then need
to do some annoying special casing to handle the "host syscall
returns EINVAL because it can't fit a record into bufsize / 2,
but it would fit into bufsize". I think you'd probably have to
loop round gradually giving the host getdents more buffers
until you got to bufsize - 12 (or live with passing the guest
back an unnecessarily pessimistic EINVAL).

But I've just realised that all that is entirely unnecessary,
because the right thing to do here is to say "for the 64-on-32
case, use the "implement getdents in terms of getdents64" codepath".
This will have no buffer overrun problems, because the dirent64
struct is the same size on every host and always larger than the
dirent struct for any architecture. I'll cook up a patch...

(One reason we do still provide the 64-on-32 emulation setups are
that if you have a fairly simple guest binary it can work well
enough -- the classic use case here is gcc test suite binaries,
most of which barely use any of the syscall interface. But there's
also a fair bit of inertia :-))

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]