From: Al Viro > Sent: 26 March 2021 16:12 > > On Fri, Mar 26, 2021 at 03:38:30PM +0100, Christoph Hellwig wrote: > > > +static const char __user * > > +get_user_arg_ptr(const char __user *const __user *argv, int nr) > > { > > + if (in_compat_syscall()) { > > + const compat_uptr_t __user *compat_argv = > > + compat_ptr((unsigned long)argv); > > compat_uptr_t compat; > > > > + if (get_user(compat, compat_argv + nr)) > > return ERR_PTR(-EFAULT); > > return compat_ptr(compat); > > + } else { > > + const char __user *native; > > > > + if (get_user(native, argv + nr)) > > + return ERR_PTR(-EFAULT); > > + return native; > > + } > > } > > Yecchhh.... So you have in_compat_syscall() called again and again, for > each argument in the list? I agree that current version is fucking ugly, > but I really hate that approach ;-/ Especially since in_compat_syscall() isn't entirely trivial on x86-64. Probably all in the noise for 'exec', but all the bits do add up. You may not want separate get_user() on some architectures either. The user_access_begin/end aren't cheap. OTOH if you call copy_from_user() you get hit by the stupid additional costs of 'user copy hardening'. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)