SHA256
1
0
forked from pool/qemu

- fix getdent in linux-user

- fix statfs in linux-user
- disable FIEMAP support in linux-user

OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=102
This commit is contained in:
Alexander Graf 2012-08-21 12:29:30 +00:00 committed by Git OBS Bridge
parent 90ea47ce78
commit ace8e9a5c4
5 changed files with 148 additions and 0 deletions

View File

@ -0,0 +1,61 @@
From b08f65c466f03820436df6143b1a256f81a5a98a Mon Sep 17 00:00:00 2001
From: Dmitry V. Levin <ldv@altlinux.org>
Date: Mon, 20 Aug 2012 12:13:12 +0000
Subject: [PATCH] linux-user: fix emulation of getdents
In case when TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64, the last
byte of the target dirent structure (aka d_type byte) was never copied
from the host dirent structure, thus breaking everything that relies
on valid d_type value, e.g. glob(3).
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
linux-user/syscall.c | 11 +++++------
linux-user/syscall_defs.h | 8 ++++----
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d19efb8..df4a538 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7161,15 +7161,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
tde = target_dirp;
while (len > 0) {
reclen = de->d_reclen;
- treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
+ tnamelen = reclen - offsetof(struct linux_dirent, d_name);
+ assert(tnamelen >= 0);
+ treclen = tnamelen + offsetof(struct target_dirent, d_name);
+ assert(count1 + treclen <= count);
tde->d_reclen = tswap16(treclen);
tde->d_ino = tswapal(de->d_ino);
tde->d_off = tswapal(de->d_off);
- tnamelen = treclen - (2 * sizeof(abi_long) + 2);
- if (tnamelen > 256)
- tnamelen = 256;
- /* XXX: may not be correct */
- pstrcpy(tde->d_name, tnamelen, de->d_name);
+ memcpy(tde->d_name, de->d_name, tnamelen);
de = (struct linux_dirent *)((char *)de + reclen);
len -= reclen;
tde = (struct target_dirent *)((char *)tde + treclen);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 349229d..d618414 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -255,10 +255,10 @@ struct kernel_statfs {
};
struct target_dirent {
- abi_long d_ino;
- abi_long d_off;
- unsigned short d_reclen;
- char d_name[256]; /* We must not include limits.h! */
+ abi_long d_ino;
+ abi_long d_off;
+ unsigned short d_reclen;
+ char d_name[];
};
struct target_dirent64 {

View File

@ -0,0 +1,48 @@
From 496ac41ba22b2dcda7eb0a90690dc55ae86c7c50 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 21 Aug 2012 11:16:06 +0200
Subject: [PATCH] linux-user: fix statfs
The statfs syscall should always memset(0) its full struct extent before
writing to it. Newer versions of the syscall use one of the reserved fields
for flags, which would otherwise get stale values from uncleaned memory.
This fixes libarchive for me, which got confused about the return value of
pathconf("/", _PC_REC_XFER_ALIGN) otherwise, as it some times gave old pointers
as return value.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
linux-user/syscall.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index df4a538..60cf77f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6667,6 +6667,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
__put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
__put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
__put_user(stfs.f_namelen, &target_stfs->f_namelen);
+ __put_user(stfs.f_frsize, &target_stfs->f_frsize);
+ __put_user(0, &target_stfs->f_spare[0]);
+ __put_user(0, &target_stfs->f_spare[1]);
+ __put_user(0, &target_stfs->f_spare[2]);
+ __put_user(0, &target_stfs->f_spare[3]);
+ __put_user(0, &target_stfs->f_spare[4]);
unlock_user_struct(target_stfs, arg2, 1);
}
break;
@@ -6695,6 +6701,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
__put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
__put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
__put_user(stfs.f_namelen, &target_stfs->f_namelen);
+ __put_user(stfs.f_frsize, &target_stfs->f_frsize);
+ __put_user(0, &target_stfs->f_spare[0]);
+ __put_user(0, &target_stfs->f_spare[1]);
+ __put_user(0, &target_stfs->f_spare[2]);
+ __put_user(0, &target_stfs->f_spare[3]);
+ __put_user(0, &target_stfs->f_spare[4]);
unlock_user_struct(target_stfs, arg3, 1);
}
break;

View File

@ -0,0 +1,26 @@
From cb9b53ee9c4277f5b61038b37c1a7ef827652b4a Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 21 Aug 2012 14:20:40 +0200
Subject: [PATCH] linux-user: XXX disable fiemap
agraf: fiemap breaks in libarchive. Disable it for now.
---
linux-user/syscall.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 60cf77f..21856f0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3252,6 +3252,11 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
uint32_t outbufsz;
int free_fm = 0;
+ if (1) {
+ /* XXX agraf: fiemap breaks for me */
+ return -TARGET_EINVAL;
+ }
+
assert(arg_type[0] == TYPE_PTR);
assert(ie->access == IOC_RW);
arg_type++;

View File

@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Aug 21 12:21:49 UTC 2012 - agraf@suse.com
- fix getdent in linux-user
- fix statfs in linux-user
- disable FIEMAP support in linux-user
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Aug 21 08:21:20 UTC 2012 - agraf@suse.com Tue Aug 21 08:21:20 UTC 2012 - agraf@suse.com

View File

@ -53,6 +53,9 @@ Patch0026: 0026-linux-user-lock-tb-flushing-too.pat.patch
Patch0027: 0027-linux-user-Fake-proc-cpuinfo.patch.patch Patch0027: 0027-linux-user-Fake-proc-cpuinfo.patch.patch
Patch0028: 0028-linux-user-implement-FS_IOC_GETFLAG.patch Patch0028: 0028-linux-user-implement-FS_IOC_GETFLAG.patch
Patch0029: 0029-linux-user-implement-FS_IOC_SETFLAG.patch Patch0029: 0029-linux-user-implement-FS_IOC_SETFLAG.patch
Patch0030: 0030-linux-user-fix-emulation-of-getdent.patch
Patch0031: 0031-linux-user-fix-statfs.patch.patch
Patch0032: 0032-linux-user-XXX-disable-fiemap.patch.patch
# this is to make lint happy # this is to make lint happy
Source300: rpmlintrc Source300: rpmlintrc
Source302: bridge.conf Source302: bridge.conf
@ -193,6 +196,9 @@ run cross-architecture builds.
%patch0027 -p1 %patch0027 -p1
%patch0028 -p1 %patch0028 -p1
%patch0029 -p1 %patch0029 -p1
%patch0030 -p1
%patch0031 -p1
%patch0032 -p1
%build %build
# build QEMU # build QEMU