Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Brian Gerst
On Mon, Jun 15, 2020 at 2:47 PM Arnd Bergmann  wrote:
>
> On Mon, Jun 15, 2020 at 4:48 PM Brian Gerst  wrote:
> > On Mon, Jun 15, 2020 at 10:13 AM Christoph Hellwig  wrote:
> > > On Mon, Jun 15, 2020 at 03:31:35PM +0200, Arnd Bergmann wrote:
>
> > >
> > > I'd rather keep it in common code as that allows all the low-level
> > > exec stuff to be marked static, and avoid us growing new pointless
> > > compat variants through copy and paste.
> > > smart compiler to d
> > >
> > > > I don't really understand
> > > > the comment, why can't this just use this?
> > >
> > > That errors out with:
> > >
> > > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> > > `__x32_sys_execve'
> > > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> > > `__x32_sys_execveat'
> > > make: *** [Makefile:1139: vmlinux] Error 1
> >
> > I think I have a fix for this, by modifying the syscall wrappers to
> > add an alias for the __x32 variant to the native __x64_sys_foo().
> > I'll get back to you with a patch.
>
> Do we actually need the __x32 prefix any more, or could we just
> change all x32 specific calls to use __x64_compat_sys_foo()?

I suppose that would work too.  The prefix really describes the
register mapping.

--
Brian Gerst


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Arnd Bergmann
On Mon, Jun 15, 2020 at 4:48 PM Brian Gerst  wrote:
> On Mon, Jun 15, 2020 at 10:13 AM Christoph Hellwig  wrote:
> > On Mon, Jun 15, 2020 at 03:31:35PM +0200, Arnd Bergmann wrote:

> >
> > I'd rather keep it in common code as that allows all the low-level
> > exec stuff to be marked static, and avoid us growing new pointless
> > compat variants through copy and paste.
> > smart compiler to d
> >
> > > I don't really understand
> > > the comment, why can't this just use this?
> >
> > That errors out with:
> >
> > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> > `__x32_sys_execve'
> > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> > `__x32_sys_execveat'
> > make: *** [Makefile:1139: vmlinux] Error 1
>
> I think I have a fix for this, by modifying the syscall wrappers to
> add an alias for the __x32 variant to the native __x64_sys_foo().
> I'll get back to you with a patch.

Do we actually need the __x32 prefix any more, or could we just
change all x32 specific calls to use __x64_compat_sys_foo()?

  Arnd


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Christoph Hellwig
On Mon, Jun 15, 2020 at 11:33:49AM -0400, Brian Gerst wrote:
> If you move those aliases above all the __SYSCALL_* defines it will
> work, since that will get the forward declaration too.  This would be
> the simplest workaround.

That compiles and also passes my exaustive x32 tests (chroot + ls -l).

This is the updated version:

http://git.infradead.org/users/hch/misc.git/commitdiff/c8d319711ad2f53be003ae8e9be08519068bdcee


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Brian Gerst
On Mon, Jun 15, 2020 at 11:10 AM Christoph Hellwig  wrote:
>
> On Mon, Jun 15, 2020 at 04:46:15PM +0200, Arnd Bergmann wrote:
> > How about this one:
> >
> > diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
> > index 3d8d70d3896c..0ce15807cf54 100644
> > --- a/arch/x86/entry/syscall_x32.c
> > +++ b/arch/x86/entry/syscall_x32.c
> > @@ -16,6 +16,9 @@
> >  #undef __SYSCALL_X32
> >  #undef __SYSCALL_COMMON
> >
> > +#define __x32_sys_execve __x64_sys_execve
> > +#define __x32_sys_execveat __x64_sys_execveat
> > +
>
>
> arch/x86/entry/syscall_x32.c:19:26: error: ‘__x64_sys_execve’ undeclared here 
> (not in a function); did you mean ‘__x32_sys_execve’?
>19 | #define __x32_sys_execve __x64_sys_execve
>   |  ^~~~
> arch/x86/entry/syscall_x32.c:22:39: note: in expansion of macro 
> ‘__x32_sys_execve’
>22 | #define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
>   |   ^~
> ./arch/x86/include/generated/asm/syscalls_64.h:344:1: note: in expansion of 
> macro ‘__SYSCALL_X32’
>   344 | __SYSCALL_X32(520, sys_execve)
>   | ^
> arch/x86/entry/syscall_x32.c:20:28: error: ‘__x64_sys_execveat’ undeclared 
> here (not in a function); did you mean ‘__x32_sys_execveat’?
>20 | #define __x32_sys_execveat __x64_sys_execveat
>   |^~
> arch/x86/entry/syscall_x32.c:22:39: note: in expansion of macro 
> ‘__x32_sys_execveat’
>22 | #define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
>   |   ^~
> ./arch/x86/include/generated/asm/syscalls_64.h:369:1: note: in expansion of 
> macro ‘__SYSCALL_X32’
>   369 | __SYSCALL_X32(545, sys_execveat)
>   | ^
> make[2]: *** [scripts/Makefile.build:281: arch/x86/entry/syscall_x32.o] Error 
> 1
> make[1]: *** [scripts/Makefile.build:497: arch/x86/entry] Error 2
> make[1]: *** Waiting for unfinished jobs
> kernel/exit.o: warning: objtool: __x64_sys_exit_group()+0x14: unreachable 
> instruction
> make: *** [Makefile:1764: arch/x86] Error 2
> make: *** Waiting for unfinished jobs

If you move those aliases above all the __SYSCALL_* defines it will
work, since that will get the forward declaration too.  This would be
the simplest workaround.

--
Brian Gerst


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Christoph Hellwig
On Mon, Jun 15, 2020 at 04:46:15PM +0200, Arnd Bergmann wrote:
> How about this one:
> 
> diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
> index 3d8d70d3896c..0ce15807cf54 100644
> --- a/arch/x86/entry/syscall_x32.c
> +++ b/arch/x86/entry/syscall_x32.c
> @@ -16,6 +16,9 @@
>  #undef __SYSCALL_X32
>  #undef __SYSCALL_COMMON
> 
> +#define __x32_sys_execve __x64_sys_execve
> +#define __x32_sys_execveat __x64_sys_execveat
> +


arch/x86/entry/syscall_x32.c:19:26: error: ‘__x64_sys_execve’ undeclared here 
(not in a function); did you mean ‘__x32_sys_execve’?
   19 | #define __x32_sys_execve __x64_sys_execve
  |  ^~~~
arch/x86/entry/syscall_x32.c:22:39: note: in expansion of macro 
‘__x32_sys_execve’
   22 | #define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
  |   ^~
./arch/x86/include/generated/asm/syscalls_64.h:344:1: note: in expansion of 
macro ‘__SYSCALL_X32’
  344 | __SYSCALL_X32(520, sys_execve)
  | ^
arch/x86/entry/syscall_x32.c:20:28: error: ‘__x64_sys_execveat’ undeclared here 
(not in a function); did you mean ‘__x32_sys_execveat’?
   20 | #define __x32_sys_execveat __x64_sys_execveat
  |^~
arch/x86/entry/syscall_x32.c:22:39: note: in expansion of macro 
‘__x32_sys_execveat’
   22 | #define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
  |   ^~
./arch/x86/include/generated/asm/syscalls_64.h:369:1: note: in expansion of 
macro ‘__SYSCALL_X32’
  369 | __SYSCALL_X32(545, sys_execveat)
  | ^
make[2]: *** [scripts/Makefile.build:281: arch/x86/entry/syscall_x32.o] Error 1
make[1]: *** [scripts/Makefile.build:497: arch/x86/entry] Error 2
make[1]: *** Waiting for unfinished jobs
kernel/exit.o: warning: objtool: __x64_sys_exit_group()+0x14: unreachable 
instruction
make: *** [Makefile:1764: arch/x86] Error 2
make: *** Waiting for unfinished jobs


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Brian Gerst
On Mon, Jun 15, 2020 at 10:13 AM Christoph Hellwig  wrote:
>
> On Mon, Jun 15, 2020 at 03:31:35PM +0200, Arnd Bergmann wrote:
> > >  #ifdef CONFIG_COMPAT
> > > -   if (unlikely(argv.is_compat)) {
> > > +   if (in_compat_syscall()) {
> > > +   const compat_uptr_t __user *compat_argv =
> > > +   compat_ptr((unsigned long)argv);
> > > compat_uptr_t compat;
> > >
> > > -   if (get_user(compat, argv.ptr.compat + nr))
> > > +   if (get_user(compat, compat_argv + nr))
> > > return ERR_PTR(-EFAULT);
> > >
> > > return compat_ptr(compat);
> > > }
> > >  #endif
> >
> > I would expect that the "#ifdef CONFIG_COMPAT" can be removed
> > now, since compat_ptr() and in_compat_syscall() are now defined
> > unconditionally. I have not tried that though.
>
> True, I'll give it a spin.
>
> > > +/*
> > > + * x32 syscalls are listed in the same table as x86_64 ones, so we need 
> > > to
> > > + * define compat syscalls that are exactly the same as the native 
> > > version for
> > > + * the syscall table machinery to work.  Sigh..
> > > + */
> > > +#ifdef CONFIG_X86_X32
> > >  COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,
> > > -   const compat_uptr_t __user *, argv,
> > > -   const compat_uptr_t __user *, envp)
> > > +  const char __user *const __user *, argv,
> > > +  const char __user *const __user *, envp)
> > >  {
> > > -   return do_compat_execve(AT_FDCWD, getname(filename), argv, envp, 
> > > 0);
> > > +   return do_execveat(AT_FDCWD, getname(filename), argv, envp, 0, 
> > > NULL);
> > >  }
> >
> > Maybe move it to arch/x86/kernel/process_64.c or 
> > arch/x86/entry/syscall_x32.c
> > to keep it out of the common code if this is needed.
>
> I'd rather keep it in common code as that allows all the low-level
> exec stuff to be marked static, and avoid us growing new pointless
> compat variants through copy and paste.
> smart compiler to d
>
> > I don't really understand
> > the comment, why can't this just use this?
>
> That errors out with:
>
> ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> `__x32_sys_execve'
> ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> `__x32_sys_execveat'
> make: *** [Makefile:1139: vmlinux] Error 1

I think I have a fix for this, by modifying the syscall wrappers to
add an alias for the __x32 variant to the native __x64_sys_foo().
I'll get back to you with a patch.

--
Brian Gerst


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Arnd Bergmann
On Mon, Jun 15, 2020 at 4:43 PM Christoph Hellwig  wrote:
>
> On Mon, Jun 15, 2020 at 04:40:28PM +0200, Arnd Bergmann wrote:
> > > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> > > `__x32_sys_execve'
> > > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> > > `__x32_sys_execveat'
> > > make: *** [Makefile:1139: vmlinux] Error 1
> >
> > Ah, I see: it's marked x32-only, so arch/x86/entry/syscall_x32.c
> > uses the __x32 prefix instead of the __x64 one. Marking it 'common'
> > instead would make it work, but also create an extra entry point
> > for native processes, something that commit
> > 6365b842aae4 ("x86/syscalls: Split the x32 syscalls into their own table")
> > was trying to avoid.
>
> Marking it common also doesn't compile at all because __NR_execve
> and __NR_execveat get redefined in unistd_64.h.  I then tried to rename
> the x32 versions, which failed in yet another way.  At that point I gave
> up instead of digging myself into a deeper hole..

How about this one:

diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
index 3d8d70d3896c..0ce15807cf54 100644
--- a/arch/x86/entry/syscall_x32.c
+++ b/arch/x86/entry/syscall_x32.c
@@ -16,6 +16,9 @@
 #undef __SYSCALL_X32
 #undef __SYSCALL_COMMON

+#define __x32_sys_execve __x64_sys_execve
+#define __x32_sys_execveat __x64_sys_execveat
+
 #define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
 #define __SYSCALL_COMMON(nr, sym) [nr] = __x64_##sym,

Still ugly, but much simpler and more localized (if it works).

Arnd


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Arnd Bergmann
On Mon, Jun 15, 2020 at 4:12 PM Christoph Hellwig  wrote:
> On Mon, Jun 15, 2020 at 03:31:35PM +0200, Arnd Bergmann wrote:

>
> > I don't really understand
> > the comment, why can't this just use this?
>
> That errors out with:
>
> ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> `__x32_sys_execve'
> ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> `__x32_sys_execveat'
> make: *** [Makefile:1139: vmlinux] Error 1

Ah, I see: it's marked x32-only, so arch/x86/entry/syscall_x32.c
uses the __x32 prefix instead of the __x64 one. Marking it 'common'
instead would make it work, but also create an extra entry point
for native processes, something that commit
6365b842aae4 ("x86/syscalls: Split the x32 syscalls into their own table")
was trying to avoid.

  Arnd


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Christoph Hellwig
On Mon, Jun 15, 2020 at 04:40:28PM +0200, Arnd Bergmann wrote:
> > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
> > `__x32_sys_execve'
> > ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
> > `__x32_sys_execveat'
> > make: *** [Makefile:1139: vmlinux] Error 1
> 
> Ah, I see: it's marked x32-only, so arch/x86/entry/syscall_x32.c
> uses the __x32 prefix instead of the __x64 one. Marking it 'common'
> instead would make it work, but also create an extra entry point
> for native processes, something that commit
> 6365b842aae4 ("x86/syscalls: Split the x32 syscalls into their own table")
> was trying to avoid.

Marking it common also doesn't compile at all because __NR_execve
and __NR_execveat get redefined in unistd_64.h.  I then tried to rename
the x32 versions, which failed in yet another way.  At that point I gave
up instead of digging myself into a deeper hole..


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Christoph Hellwig
On Mon, Jun 15, 2020 at 03:31:35PM +0200, Arnd Bergmann wrote:
> >  #ifdef CONFIG_COMPAT
> > -   if (unlikely(argv.is_compat)) {
> > +   if (in_compat_syscall()) {
> > +   const compat_uptr_t __user *compat_argv =
> > +   compat_ptr((unsigned long)argv);
> > compat_uptr_t compat;
> >
> > -   if (get_user(compat, argv.ptr.compat + nr))
> > +   if (get_user(compat, compat_argv + nr))
> > return ERR_PTR(-EFAULT);
> >
> > return compat_ptr(compat);
> > }
> >  #endif
> 
> I would expect that the "#ifdef CONFIG_COMPAT" can be removed
> now, since compat_ptr() and in_compat_syscall() are now defined
> unconditionally. I have not tried that though.

True, I'll give it a spin.

> > +/*
> > + * x32 syscalls are listed in the same table as x86_64 ones, so we need to
> > + * define compat syscalls that are exactly the same as the native version 
> > for
> > + * the syscall table machinery to work.  Sigh..
> > + */
> > +#ifdef CONFIG_X86_X32
> >  COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,
> > -   const compat_uptr_t __user *, argv,
> > -   const compat_uptr_t __user *, envp)
> > +  const char __user *const __user *, argv,
> > +  const char __user *const __user *, envp)
> >  {
> > -   return do_compat_execve(AT_FDCWD, getname(filename), argv, envp, 0);
> > +   return do_execveat(AT_FDCWD, getname(filename), argv, envp, 0, 
> > NULL);
> >  }
> 
> Maybe move it to arch/x86/kernel/process_64.c or arch/x86/entry/syscall_x32.c
> to keep it out of the common code if this is needed.

I'd rather keep it in common code as that allows all the low-level
exec stuff to be marked static, and avoid us growing new pointless
compat variants through copy and paste.
smart compiler to d

> I don't really understand
> the comment, why can't this just use this?

That errors out with:

ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1040): undefined reference to
`__x32_sys_execve'
ld: arch/x86/entry/syscall_x32.o:(.rodata+0x1108): undefined reference to
`__x32_sys_execveat'
make: *** [Makefile:1139: vmlinux] Error 1


Re: [PATCH 2/6] exec: simplify the compat syscall handling

2020-06-15 Thread Arnd Bergmann
On Mon, Jun 15, 2020 at 3:00 PM Christoph Hellwig  wrote:
>
> The only differenence betweeen the compat exec* syscalls and their
> native versions is that compat_ptr sign extension, and the fact that
> the pointer arithmetics for the two dimensional arrays needs to use
> the compat pointer size.  Instead of the compat wrappers and the
> struct user_arg_ptr machinery just use in_compat_syscall() to do the
> right thing for the compat case deep inside get_user_arg_ptr().
>
> Signed-off-by: Christoph Hellwig 

Nice!

I have an older patch doing the same for sys_mount() somewhere,
but never got around to send that. One day we should see if we
can just do this for all of them.

> -
> -static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
> +static const char __user *
> +get_user_arg_ptr(const char __user *const __user *argv, int nr)
>  {
> const char __user *native;
>
>  #ifdef CONFIG_COMPAT
> -   if (unlikely(argv.is_compat)) {
> +   if (in_compat_syscall()) {
> +   const compat_uptr_t __user *compat_argv =
> +   compat_ptr((unsigned long)argv);
> compat_uptr_t compat;
>
> -   if (get_user(compat, argv.ptr.compat + nr))
> +   if (get_user(compat, compat_argv + nr))
> return ERR_PTR(-EFAULT);
>
> return compat_ptr(compat);
> }
>  #endif

I would expect that the "#ifdef CONFIG_COMPAT" can be removed
now, since compat_ptr() and in_compat_syscall() are now defined
unconditionally. I have not tried that though.

> +/*
> + * x32 syscalls are listed in the same table as x86_64 ones, so we need to
> + * define compat syscalls that are exactly the same as the native version for
> + * the syscall table machinery to work.  Sigh..
> + */
> +#ifdef CONFIG_X86_X32
>  COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,
> -   const compat_uptr_t __user *, argv,
> -   const compat_uptr_t __user *, envp)
> +  const char __user *const __user *, argv,
> +  const char __user *const __user *, envp)
>  {
> -   return do_compat_execve(AT_FDCWD, getname(filename), argv, envp, 0);
> +   return do_execveat(AT_FDCWD, getname(filename), argv, envp, 0, NULL);
>  }

Maybe move it to arch/x86/kernel/process_64.c or arch/x86/entry/syscall_x32.c
to keep it out of the common code if this is needed. I don't really understand
the comment, why can't this just use this?

--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -379,7 +379,7 @@
 517x32 recvfromcompat_sys_recvfrom
 518x32 sendmsg compat_sys_sendmsg
 519x32 recvmsg compat_sys_recvmsg
-520x32 execve  compat_sys_execve
+520x32 execve  sys_execve
 521x32 ptrace  compat_sys_ptrace
 522x32 rt_sigpending   compat_sys_rt_sigpending
 523x32 rt_sigtimedwait compat_sys_rt_sigtimedwait_time64
@@ -404,7 +404,7 @@
 542x32 getsockopt  compat_sys_getsockopt
 543x32 io_setupcompat_sys_io_setup
 544x32 io_submit   compat_sys_io_submit
-545x32 execveatcompat_sys_execveat
+545x32 execveatsys_execveat
 546x32 preadv2 compat_sys_preadv64v2
 547x32 pwritev2compat_sys_pwritev64v2
 548x32 process_madvise compat_sys_process_madvise

   Arnd