Re: [PATCH] aio: Fix io_pgetevents() struct __compat_aio_sigset layout

2019-10-21 Thread Al Viro
On Thu, Oct 17, 2019 at 03:48:00PM +0200, Jan Kara wrote:
> On Wed 21-08-19 05:38:20, Guillem Jover wrote:
> > This type is used to pass the sigset_t from userland to the kernel,
> > but it was using the kernel native pointer type for the member
> > representing the compat userland pointer to the userland sigset_t.
> > 
> > This messes up the layout, and makes the kernel eat up both the
> > userland pointer and the size members into the kernel pointer, and
> > then reads garbage into the kernel sigsetsize. Which makes the sigset_t
> > size consistency check fail, and consequently the syscall always
> > returns -EINVAL.
> > 
> > This breaks both libaio and strace on 32-bit userland running on 64-bit
> > kernels. And there are apparently no users in the wild of the current
> > broken layout (at least according to codesearch.debian.org and a brief
> > check over github.com search). So it looks safe to fix this directly
> > in the kernel, instead of either letting userland deal with this
> > permanently with the additional overhead or trying to make the syscall
> > infer what layout userland used, even though this is also being worked
> > around in libaio to temporarily cope with kernels that have not yet
> > been fixed.
> > 
> > We use a proper compat_uptr_t instead of a compat_sigset_t pointer.
> > 
> > Fixes: 7a074e96 ("aio: implement io_pgetevents")
> > Signed-off-by: Guillem Jover 
> 
> This patch seems to have fallen through the cracks. Al?

Looks like - back then I assumed that Jens would've picked it...
Applied to #fixes...


Re: [PATCH] aio: Fix io_pgetevents() struct __compat_aio_sigset layout

2019-10-17 Thread Jan Kara
On Wed 21-08-19 05:38:20, Guillem Jover wrote:
> This type is used to pass the sigset_t from userland to the kernel,
> but it was using the kernel native pointer type for the member
> representing the compat userland pointer to the userland sigset_t.
> 
> This messes up the layout, and makes the kernel eat up both the
> userland pointer and the size members into the kernel pointer, and
> then reads garbage into the kernel sigsetsize. Which makes the sigset_t
> size consistency check fail, and consequently the syscall always
> returns -EINVAL.
> 
> This breaks both libaio and strace on 32-bit userland running on 64-bit
> kernels. And there are apparently no users in the wild of the current
> broken layout (at least according to codesearch.debian.org and a brief
> check over github.com search). So it looks safe to fix this directly
> in the kernel, instead of either letting userland deal with this
> permanently with the additional overhead or trying to make the syscall
> infer what layout userland used, even though this is also being worked
> around in libaio to temporarily cope with kernels that have not yet
> been fixed.
> 
> We use a proper compat_uptr_t instead of a compat_sigset_t pointer.
> 
> Fixes: 7a074e96 ("aio: implement io_pgetevents")
> Signed-off-by: Guillem Jover 

This patch seems to have fallen through the cracks. Al?

Honza

> ---
>  fs/aio.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/aio.c b/fs/aio.c
> index 01e0fb9ae45a..056f291bc66f 100644
> --- a/fs/aio.c
> +++ b/fs/aio.c
> @@ -2179,7 +2179,7 @@ SYSCALL_DEFINE5(io_getevents_time32, __u32, ctx_id,
>  #ifdef CONFIG_COMPAT
>  
>  struct __compat_aio_sigset {
> - compat_sigset_t __user  *sigmask;
> + compat_uptr_t   sigmask;
>   compat_size_t   sigsetsize;
>  };
>  
> @@ -2204,7 +2204,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
>   if (usig && copy_from_user(, usig, sizeof(ksig)))
>   return -EFAULT;
>  
> - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
> + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
> ksig.sigsetsize);
>   if (ret)
>   return ret;
>  
> @@ -2239,7 +2239,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
>   if (usig && copy_from_user(, usig, sizeof(ksig)))
>   return -EFAULT;
>  
> - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
> + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
> ksig.sigsetsize);
>   if (ret)
>   return ret;
>  
> -- 
> 2.23.0
> 
-- 
Jan Kara 
SUSE Labs, CR


Re: [PATCH] aio: Fix io_pgetevents() struct __compat_aio_sigset layout

2019-08-22 Thread Jeff Moyer
Guillem Jover  writes:

> This type is used to pass the sigset_t from userland to the kernel,
> but it was using the kernel native pointer type for the member
> representing the compat userland pointer to the userland sigset_t.
>
> This messes up the layout, and makes the kernel eat up both the
> userland pointer and the size members into the kernel pointer, and
> then reads garbage into the kernel sigsetsize. Which makes the sigset_t
> size consistency check fail, and consequently the syscall always
> returns -EINVAL.
>
> This breaks both libaio and strace on 32-bit userland running on 64-bit
> kernels. And there are apparently no users in the wild of the current
> broken layout (at least according to codesearch.debian.org and a brief
> check over github.com search). So it looks safe to fix this directly
> in the kernel, instead of either letting userland deal with this
> permanently with the additional overhead or trying to make the syscall
> infer what layout userland used, even though this is also being worked
> around in libaio to temporarily cope with kernels that have not yet
> been fixed.
>
> We use a proper compat_uptr_t instead of a compat_sigset_t pointer.
>
> Fixes: 7a074e96 ("aio: implement io_pgetevents")
> Signed-off-by: Guillem Jover 

Looks good, thanks for finding and fixing this!

Reviewed-by: Jeff Moyer 

> ---
>  fs/aio.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/fs/aio.c b/fs/aio.c
> index 01e0fb9ae45a..056f291bc66f 100644
> --- a/fs/aio.c
> +++ b/fs/aio.c
> @@ -2179,7 +2179,7 @@ SYSCALL_DEFINE5(io_getevents_time32, __u32, ctx_id,
>  #ifdef CONFIG_COMPAT
>  
>  struct __compat_aio_sigset {
> - compat_sigset_t __user  *sigmask;
> + compat_uptr_t   sigmask;
>   compat_size_t   sigsetsize;
>  };
>  
> @@ -2204,7 +2204,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
>   if (usig && copy_from_user(, usig, sizeof(ksig)))
>   return -EFAULT;
>  
> - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
> + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
> ksig.sigsetsize);
>   if (ret)
>   return ret;
>  
> @@ -2239,7 +2239,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
>   if (usig && copy_from_user(, usig, sizeof(ksig)))
>   return -EFAULT;
>  
> - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
> + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
> ksig.sigsetsize);
>   if (ret)
>   return ret;


Re: [PATCH] aio: Fix io_pgetevents() struct __compat_aio_sigset layout

2019-08-21 Thread Christoph Hellwig
On Wed, Aug 21, 2019 at 05:38:20AM +0200, Guillem Jover wrote:
> This type is used to pass the sigset_t from userland to the kernel,
> but it was using the kernel native pointer type for the member
> representing the compat userland pointer to the userland sigset_t.
> 
> This messes up the layout, and makes the kernel eat up both the
> userland pointer and the size members into the kernel pointer, and
> then reads garbage into the kernel sigsetsize. Which makes the sigset_t
> size consistency check fail, and consequently the syscall always
> returns -EINVAL.
> 
> This breaks both libaio and strace on 32-bit userland running on 64-bit
> kernels. And there are apparently no users in the wild of the current
> broken layout (at least according to codesearch.debian.org and a brief
> check over github.com search). So it looks safe to fix this directly
> in the kernel, instead of either letting userland deal with this
> permanently with the additional overhead or trying to make the syscall
> infer what layout userland used, even though this is also being worked
> around in libaio to temporarily cope with kernels that have not yet
> been fixed.
> 
> We use a proper compat_uptr_t instead of a compat_sigset_t pointer.
> 
> Fixes: 7a074e96 ("aio: implement io_pgetevents")
> Signed-off-by: Guillem Jover 

Looks good,

Reviewed-by: Christoph Hellwig 


[PATCH] aio: Fix io_pgetevents() struct __compat_aio_sigset layout

2019-08-20 Thread Guillem Jover
This type is used to pass the sigset_t from userland to the kernel,
but it was using the kernel native pointer type for the member
representing the compat userland pointer to the userland sigset_t.

This messes up the layout, and makes the kernel eat up both the
userland pointer and the size members into the kernel pointer, and
then reads garbage into the kernel sigsetsize. Which makes the sigset_t
size consistency check fail, and consequently the syscall always
returns -EINVAL.

This breaks both libaio and strace on 32-bit userland running on 64-bit
kernels. And there are apparently no users in the wild of the current
broken layout (at least according to codesearch.debian.org and a brief
check over github.com search). So it looks safe to fix this directly
in the kernel, instead of either letting userland deal with this
permanently with the additional overhead or trying to make the syscall
infer what layout userland used, even though this is also being worked
around in libaio to temporarily cope with kernels that have not yet
been fixed.

We use a proper compat_uptr_t instead of a compat_sigset_t pointer.

Fixes: 7a074e96 ("aio: implement io_pgetevents")
Signed-off-by: Guillem Jover 
---
 fs/aio.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index 01e0fb9ae45a..056f291bc66f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2179,7 +2179,7 @@ SYSCALL_DEFINE5(io_getevents_time32, __u32, ctx_id,
 #ifdef CONFIG_COMPAT
 
 struct __compat_aio_sigset {
-   compat_sigset_t __user  *sigmask;
+   compat_uptr_t   sigmask;
compat_size_t   sigsetsize;
 };
 
@@ -2204,7 +2204,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
if (usig && copy_from_user(, usig, sizeof(ksig)))
return -EFAULT;
 
-   ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
+   ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
ksig.sigsetsize);
if (ret)
return ret;
 
@@ -2239,7 +2239,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
if (usig && copy_from_user(, usig, sizeof(ksig)))
return -EFAULT;
 
-   ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
+   ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), 
ksig.sigsetsize);
if (ret)
return ret;
 
-- 
2.23.0