Message ID | mvmftdg8wxw.fsf@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | linux-user: Use getcwd syscall directly | expand |
Le 06/04/2020 à 17:18, Andreas Schwab a écrit : > The glibc getcwd function returns different errors than the getcwd > syscall, which triggers an assertion failure in the glibc getcwd function > when running under the emulation. > > Signed-off-by: Andreas Schwab <schwab@suse.de> > --- > linux-user/syscall.c | 9 +-------- > 1 file changed, 1 insertion(+), 8 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 83c2891169..90c5433fec 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -375,14 +375,7 @@ static bitmask_transtbl fcntl_flags_tbl[] = { > { 0, 0, 0, 0 } > }; > > -static int sys_getcwd1(char *buf, size_t size) > -{ > - if (getcwd(buf, size) == NULL) { > - /* getcwd() sets errno */ > - return (-1); > - } > - return strlen(buf)+1; > -} > +_syscall2(int, sys_getcwd1, char *, buf, size_t, size) > > #ifdef TARGET_NR_utimensat > #if defined(__NR_utimensat) > According to the commit introducing the function, it could break fakeroot: commit 3b3f24add09f8ab720860d4840f9755c102121b5 Author: Aurelien Jarno <aurelien@aurel32.net> Date: Wed Apr 15 16:12:13 2009 +0000 linux-user: prefer glibc over direct syscalls The openat/*at syscalls are incredibly common with modern coreutils, calling them directly via syscalls breaks for example fakeroot. Use glibc stubs whenever directly available and provide old syscall calling for people still using older libc. Patch originally from Mika Westerberg, Adapted to apply to current trunk and cleaned up by Riku Voipio. Signed-off-by: Riku Voipio <riku.voipio@iki.fi> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Thanks, Laurent
On Tue, 7 Apr 2020 at 11:37, Laurent Vivier <laurent@vivier.eu> wrote: > > Le 06/04/2020 à 17:18, Andreas Schwab a écrit : > > The glibc getcwd function returns different errors than the getcwd > > syscall, which triggers an assertion failure in the glibc getcwd function > > when running under the emulation. What exactly are the differences in errors ? > > --- > According to the commit introducing the function, it could break fakeroot: > > commit 3b3f24add09f8ab720860d4840f9755c102121b5 > Author: Aurelien Jarno <aurelien@aurel32.net> > Date: Wed Apr 15 16:12:13 2009 +0000 > > linux-user: prefer glibc over direct syscalls > > The openat/*at syscalls are incredibly common with modern coreutils, > calling them directly via syscalls breaks for example fakeroot. Use > glibc stubs whenever directly available and provide old syscall > calling for people still using older libc. I don't think (based on a quick grep of the fakeroot sources) that fakeroot intercepts 'getcwd', so this patch is probably ok on this front. It looks like the syscalls that fakeroot cares about that that patch was trying to improve our handling for are the ones like fstatat which return the kind of permission/ownership info fakeroot wants to alter (not including 'openat', despite that being the only function named in full in the commit message...) More generally, we rely on making direct syscalls for at least some syscalls for signal-handling related correctness, so if that ever comes into conflict with QEMU continuing to work under 'fakeroot' then fakeroot-compatilibity is going to lose... ('fakeroot-ng' would still work, as it intercepts syscalls via ptrace.) thanks -- PMM
On Apr 07 2020, Peter Maydell wrote: > On Tue, 7 Apr 2020 at 11:37, Laurent Vivier <laurent@vivier.eu> wrote: >> >> Le 06/04/2020 à 17:18, Andreas Schwab a écrit : >> > The glibc getcwd function returns different errors than the getcwd >> > syscall, which triggers an assertion failure in the glibc getcwd function >> > when running under the emulation. > > What exactly are the differences in errors ? It's ENAMETOOLONG vs. ERANGE. When the syscall returns ENAMETOOLONG, the glibc wrapper uses a fallback implementation that potentially handles an unlimited path length, and returns with ERANGE if the provided buffer is too small. The qemu emulation cannot distinguish the two cases, and thus always returns ERANGE. This is unexpected by the glibc wrapper. Andreas.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 83c2891169..90c5433fec 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -375,14 +375,7 @@ static bitmask_transtbl fcntl_flags_tbl[] = { { 0, 0, 0, 0 } }; -static int sys_getcwd1(char *buf, size_t size) -{ - if (getcwd(buf, size) == NULL) { - /* getcwd() sets errno */ - return (-1); - } - return strlen(buf)+1; -} +_syscall2(int, sys_getcwd1, char *, buf, size_t, size) #ifdef TARGET_NR_utimensat #if defined(__NR_utimensat)
The glibc getcwd function returns different errors than the getcwd syscall, which triggers an assertion failure in the glibc getcwd function when running under the emulation. Signed-off-by: Andreas Schwab <schwab@suse.de> --- linux-user/syscall.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)