On 21 August 2012 13:43, Alexander Graf <ag...@suse.de> wrote: > 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 <ag...@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 d19efb8..61f5718 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;
For some targets there are 6 f_spare[] slots, not 5... I suggest memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare)); instead (which matches how the kernel does this). -- PMM