rseq structs represent all addresses as __u64. Some of them are in fact being used as pointers to access user memory. For now, let's create user pointers manually to make the access.
struct rseq::rseq_cs really represents a pointer (to a struct rseq_c) and its type should eventually be changed accordingly (__kernel_uintptr_t). The situation is less clear for struct rseq_cs::start_ip and struct rseq_cs::abort_ip as they are mostly addresses, but checks in PCuABI may still be desirable.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/rseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/rseq.c b/kernel/rseq.c index 9eebc6090c52..0afb44439a8d 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -141,7 +141,7 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) } if (ptr >= TASK_SIZE) return -EINVAL; - urseq_cs = (struct rseq_cs __user *)(unsigned long)ptr; + urseq_cs = uaddr_to_user_ptr(ptr); if (copy_from_user(rseq_cs, urseq_cs, sizeof(*rseq_cs))) return -EFAULT;
@@ -157,7 +157,7 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) if (rseq_cs->abort_ip - rseq_cs->start_ip < rseq_cs->post_commit_offset) return -EINVAL;
- usig = (u32 __user *)(unsigned long)(rseq_cs->abort_ip - sizeof(u32)); + usig = uaddr_to_user_ptr(rseq_cs->abort_ip - sizeof(u32)); ret = get_user(sig, usig); if (ret) return ret;