On [Mon, 04.02.2008 20:03], Richard Purdie wrote: > Hi, > > OpenEmbedded/Poky use qemu for locale generation when cross compiling. > When we upgraded to qemu 0.9.1 it started giving locale generation > errors on all 64 bit machines and some 32 bit ones. > > I've traced it to the writev syscall failing. localedef passes several > { NULL, 0 } iovec entries which trip up lock_iovec(). That function is > returning an error for these but the return value isn't checked. The > syscall is therefore always made but sometimes with a iovec that has > only been half copied. If the total writes exceed size_t, EINVAL is > returned by the kernel and glibc code emulates the call with a write > which is most likely to happen on 32 bit so it sometimes works. size_t > is unlikely to be exceeded on 64 bit so that returns an EFAULT and > always corrupts/fails. > > Anyhow, it seems 0 length iovec entries are allowed and we shouldn't > care about the addresses in those cases. The patch below is one way to > fix this. Ideally the return value of lock_iovec() needs be be checked > too. > > Regards, > > Richard > > --- > linux-user/syscall.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > Index: qemu-0.9.1/linux-user/syscall.c > =================================================================== > --- qemu-0.9.1.orig/linux-user/syscall.c 2008-02-03 00:00:00.000000000 > +0000 > +++ qemu-0.9.1/linux-user/syscall.c 2008-02-03 00:00:38.000000000 +0000 > @@ -1048,7 +1048,7 @@ static abi_long lock_iovec(int type, str > base = tswapl(target_vec[i].iov_base); > vec[i].iov_len = tswapl(target_vec[i].iov_len); > vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); > - if (!vec[i].iov_base) > + if (!vec[i].iov_base && vec[i].iov_len) > goto fail; > } > unlock_user (target_vec, target_addr, 0);
I have post similar patch some days ago. -- Regards, Kirill A. Shutemov + Belarus, Minsk + Velesys Ltd, http://www.velesys.com/ + ALT Linux Team, http://www.altlinux.com/
signature.asc
Description: Digital signature