From: Matthew Wilcox (Oracle) <willy@infradead.org> Date: Mon, 10 Aug 2020 14:05:22 +0000 (-0400) Subject: mshare: Store the base/len in the mm_struct X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ad6f463cc4b9ebd7b7e8ed3b40a6911088f8443a;p=users%2Fwilly%2Flinux.git mshare: Store the base/len in the mm_struct Also add a read operation so the recipient can find out what address range the donor shared. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> --- diff --git a/mm/mshare.c b/mm/mshare.c index 525f624adede..75eb0796584f 100644 --- a/mm/mshare.c +++ b/mm/mshare.c @@ -3,7 +3,21 @@ #include <linux/sched/mm.h> #include <linux/syscalls.h> -int mshare_release(struct inode *inode, struct file *file) +static ssize_t mshare_read(struct kiocb *iocb, struct iov_iter *iov) +{ + struct mm_struct *mm = iocb->ki_filp->private_data; + size_t ret; + u64 tmp[2]; + + tmp[0] = mm->mmap_base; + tmp[1] = mm->task_size - mm->mmap_base; + ret = copy_to_iter(&tmp, sizeof(tmp), iov); + if (!ret) + return -EFAULT; + return ret; +} + +static int mshare_release(struct inode *inode, struct file *file) { struct mm_struct *mm = file->private_data; @@ -13,6 +27,7 @@ int mshare_release(struct inode *inode, struct file *file) } static const struct file_operations mshare_fops = { + .read_iter = mshare_read, .release = mshare_release, }; @@ -24,10 +39,16 @@ SYSCALL_DEFINE3(mshare, unsigned long, addr, unsigned long, len, if ((addr | len) & (PGDIR_SIZE - 1)) return -EINVAL; + if ((addr + len - 1) < addr) + return -EINVAL; mm = mm_alloc(); if (!mm) return -ENOMEM; + mm->mmap_base = addr; + mm->task_size = addr + len; + if (!mm->task_size) + mm->task_size--; fd = anon_inode_getfd("mshare", &mshare_fops, mm, O_RDWR);