From: Aleksandar Markovic <aleksandar.m.mail@gmail.com>
To: David Hildenbrand <david@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Cornelia Huck <cohuck@redhat.com>,
Riku Voipio <riku.voipio@iki.fi>,
Richard Henderson <richard.henderson@linaro.org>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
Laurent Vivier <laurent@vivier.eu>,
qemu-s390x <qemu-s390x@nongnu.org>
Subject: Re: [Qemu-devel] [qemu-s390x] linux-user: s390x issue on Fedora 30 (dynamic library loader?)
Date: Mon, 19 Aug 2019 15:43:51 +0200 [thread overview]
Message-ID: <CAL1e-=jT4r79st+oqR=Zc_Fh62Tp31iUZSX7DLjy0fnysEvy1A@mail.gmail.com> (raw)
In-Reply-To: <CAL1e-=hD03RDSHhaBK1BVScKSRsrkXy-dJCvUFzfpJCbYSVe9w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7191 bytes --]
On Mon, Aug 19, 2019 at 3:34 PM Aleksandar Markovic <
aleksandar.m.mail@gmail.com> wrote:
> Hi, David.
>
> I can't repro the problem either, but I do have a patch authored by an
> engineer that left the company a while ago that seems to be at least
> related to your scenario. May I ask you to test it (just apply it to QEMU
> ToT and rerun the scenario to see if it changes the outcome) (feel free to
> experiment and modify the changes)? I never managed to understand the
> purpose of that patch (I lost the contact with the former engineer, and the
> patch is without any comment), so I never dared to send it to the list, but
> I hope your scenario may actually explain the purpose and the origin of the
> patch.
>
> I am attaching the patch both as a file and inline.
>
>
In the patch I had sent in my previous mail, TARGET_ENONET should be
replaced by TARGET_ENOENT. I made a mistake while doing speedy rebasing.
Though, both ENONET and ENOENT compile, and perhaps the error code value is
not crucial. I am attaching the updated/corrected patch.
Aleksandar
> Yours,
> Aleksandar
>
>
> From 377f99e807f4aa42ece9f0cd437f50af11611b4c Mon Sep 17 00:00:00 2001
> From: Aleksandar Markovic <amarkovic@wavecomp.com>
> Date: Mon, 19 Aug 2019 15:20:29 +0200
> Subject: [PATCH] linux-user: Special case /etc/ld.cache.so and pretend it
> does
> not exist
>
> Prevent target executables from opening host ld.so.cache.
> ---
> linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 8367cb1..f5bae6e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8820,6 +8820,10 @@ static abi_long do_syscall1(void *cpu_env, int num,
> abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(statfs(path(p), &stfs));
> unlock_user(p, arg1, 0);
> convert_statfs:
> @@ -8859,6 +8863,10 @@ static abi_long do_syscall1(void *cpu_env, int num,
> abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(statfs(path(p), &stfs));
> unlock_user(p, arg1, 0);
> convert_statfs64:
> @@ -9059,6 +9067,10 @@ static abi_long do_syscall1(void *cpu_env, int num,
> abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(stat(path(p), &st));
> unlock_user(p, arg1, 0);
> goto do_stat;
> @@ -9068,6 +9080,10 @@ static abi_long do_syscall1(void *cpu_env, int num,
> abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(lstat(path(p), &st));
> unlock_user(p, arg1, 0);
> goto do_stat;
> @@ -10268,6 +10284,10 @@ static abi_long do_syscall1(void *cpu_env, int
> num, abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(stat(path(p), &st));
> unlock_user(p, arg1, 0);
> if (!is_error(ret))
> @@ -10279,6 +10299,10 @@ static abi_long do_syscall1(void *cpu_env, int
> num, abi_long arg1,
> if (!(p = lock_user_string(arg1))) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> ret = get_errno(lstat(path(p), &st));
> unlock_user(p, arg1, 0);
> if (!is_error(ret))
> @@ -10319,6 +10343,10 @@ static abi_long do_syscall1(void *cpu_env, int
> num, abi_long arg1,
> if (p == NULL) {
> return -TARGET_EFAULT;
> }
> + if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
> + unlock_user(p, arg1, 0);
> + return -TARGET_ENONET;
> + }
> #if defined(__NR_statx)
> {
> /*
> --
> 2.7.4
>
>
> On Mon, Aug 19, 2019 at 3:08 PM David Hildenbrand <david@redhat.com>
> wrote:
>
>> On 19.08.19 14:11, Peter Maydell wrote:
>> > On Sat, 17 Aug 2019 at 17:14, David Hildenbrand <david@redhat.com>
>> wrote:
>> >>
>> >> On 17.08.19 17:59, David Hildenbrand wrote:
>> >>> Hi everybody,
>> >>>
>> >>> I was just trying to run qemu-s390x (linux-user) with a very simple
>> >>> binary (gzip + lib/ld64.so.1, compiled under Fedora 27). This used to
>> >>> work just fine a while ago (especially when I was working on vector
>> >>> instructions using QEMU v3.1). However, now I can't get past a
>> SEGFAULT
>> >>> in the dynamic library loader (I assume it is trying to locate
>> glibc). I
>> >>> tried a couple of other binaries that definitely used to work (from
>> >>> Fedora 30).
>> >>>
>> >>> I checked QEMU v4.1, v4.0 and v3.1. All are broken for me. Which is
>> >>> weird - because it used to work :/
>> >>>
>> >>> I remember that I was running Fedora 29 the last time I had it
>> running,
>> >>> so my gut feeling is that this is related to some other system library
>> >>> (but which?). I am running on an up-to-date Fedora 30 x86-64 now.
>> >>>
>> >>> Any ideas? Has this been reported already? (not sure if this is a
>> Fedora
>> >>> 30 issue)
>> >
>> > I'm pretty sure the problem you've run into is a long standing
>> > bug in the glibc dynamic loader. It cannot cope with the ld.so.cache
>> > being for the wrong endianness. (Correct endianness but incorrect
>> > architecture it correctly detects and ignores). The result is that
>> > running a linux-user QEMU dynamic binary for big-endian on little-endian
>> > like this will crash in the dynamic loader unless you arrange that it
>> can't
>> > find the host's ld.so.cache somehow, eg:
>> > (a) run inside a chroot
>> > (b) create an empty /etc/ld.so.cache file inside the -L directory
>> >
>> > The ideal fix would be if somebody cared enough to track down
>> > and fix the ld.so bug.
>> >
>> > Compare:
>> > https://bugs.launchpad.net/qemu/+bug/1701798
>> > https://bugs.launchpad.net/qemu/+bug/1835693
>> >
>> > thanks
>> > -- PMM
>> >
>>
>> Thanks, running
>>
>> "ldconfig -c etc/ld.so.cache -r ."
>>
>> Seems to fix the issue for me. So you are sure the bug resides in glic
>> and not in the qemu-user pieces of the library loader?
>>
>> --
>>
>> Thanks,
>>
>> David / dhildenb
>>
>>
[-- Attachment #2: 0001-linux-user-Special-case-etc-ld.cache.so-and-pretend-.patch --]
[-- Type: text/x-patch, Size: 3543 bytes --]
From 6146453ecbbeca26e64a6ed6aa86b359032d32be Mon Sep 17 00:00:00 2001
From: Aleksandar Markovic <amarkovic@wavecomp.com>
Date: Mon, 19 Aug 2019 15:20:29 +0200
Subject: [PATCH] linux-user: Special case /etc/ld.cache.so and pretend it does
not exist
Prevent target executables from opening host ld.so.cache.
---
linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8367cb1..983c6e7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8820,6 +8820,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(statfs(path(p), &stfs));
unlock_user(p, arg1, 0);
convert_statfs:
@@ -8859,6 +8863,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(statfs(path(p), &stfs));
unlock_user(p, arg1, 0);
convert_statfs64:
@@ -9059,6 +9067,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(stat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
@@ -9068,6 +9080,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(lstat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
@@ -10268,6 +10284,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(stat(path(p), &st));
unlock_user(p, arg1, 0);
if (!is_error(ret))
@@ -10279,6 +10299,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1))) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
ret = get_errno(lstat(path(p), &st));
unlock_user(p, arg1, 0);
if (!is_error(ret))
@@ -10319,6 +10343,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (p == NULL) {
return -TARGET_EFAULT;
}
+ if (strcmp("/etc/ld.so.cache", path(p)) == 0) {
+ unlock_user(p, arg1, 0);
+ return -TARGET_ENOENT;
+ }
#if defined(__NR_statx)
{
/*
--
2.7.4
next prev parent reply other threads:[~2019-08-19 13:45 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <8fb538f3-dfdd-b427-727a-2e7c2120da09@gmail.com>
2019-08-17 16:14 ` [Qemu-devel] [qemu-s390x] linux-user: s390x issue on Fedora 30 (dynamic library loader?) David Hildenbrand
2019-08-17 16:22 ` Laurent Vivier
2019-08-17 16:51 ` David Hildenbrand
2019-08-19 10:32 ` Laurent Vivier
2019-08-19 11:55 ` David Hildenbrand
2019-08-19 12:02 ` Laurent Vivier
2019-08-19 12:03 ` David Hildenbrand
2019-08-19 12:11 ` Peter Maydell
2019-08-19 12:22 ` David Hildenbrand
2019-08-19 12:36 ` Peter Maydell
2019-08-19 13:34 ` Aleksandar Markovic
2019-08-19 13:43 ` Aleksandar Markovic [this message]
2019-08-19 13:43 ` Laurent Vivier
2019-08-19 13:44 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAL1e-=jT4r79st+oqR=Zc_Fh62Tp31iUZSX7DLjy0fnysEvy1A@mail.gmail.com' \
--to=aleksandar.m.mail@gmail.com \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=laurent@vivier.eu \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=riku.voipio@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).