lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 7 Dec 2020 19:31:02 +0800 From: yulei.kernel@...il.com To: linux-mm@...ck.org, akpm@...ux-foundation.org, linux-fsdevel@...r.kernel.org, kvm@...r.kernel.org, linux-kernel@...r.kernel.org, naoya.horiguchi@....com, viro@...iv.linux.org.uk, pbonzini@...hat.com Cc: joao.m.martins@...cle.com, rdunlap@...radead.org, sean.j.christopherson@...el.com, xiaoguangrong.eric@...il.com, kernellwp@...il.com, lihaiwei.kernel@...il.com, Yulei Zhang <yuleixzhang@...cent.com>, Xiao Guangrong <gloryxiao@...cent.com> Subject: [RFC V2 09/37] dmemfs: support remote access From: Yulei Zhang <yuleixzhang@...cent.com> It is required by ptrace_writedata and ptrace_readdata to access dmem memory remotely. The typical user is gdb, after this patch, gdb is able to read & write memory owned by the attached process Signed-off-by: Xiao Guangrong <gloryxiao@...cent.com> Signed-off-by: Yulei Zhang <yuleixzhang@...cent.com> --- fs/dmemfs/inode.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/dmemfs/inode.c b/fs/dmemfs/inode.c index 7723b58..3192f31 100644 --- a/fs/dmemfs/inode.c +++ b/fs/dmemfs/inode.c @@ -364,6 +364,51 @@ static void radix_put_entry(void) rcu_read_unlock(); } +static bool check_vma_access(struct vm_area_struct *vma, int write) +{ + vm_flags_t vm_flags = write ? VM_WRITE : VM_READ; + + return !!(vm_flags & vma->vm_flags); +} + +static int +dmemfs_access_dmem(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write) +{ + struct inode *inode = file_inode(vma->vm_file); + struct super_block *sb = inode->i_sb; + void *entry, *maddr; + int offset, pgoff; + + if (!check_vma_access(vma, write)) + return -EACCES; + + pgoff = linear_page_index(vma, addr); + if (pgoff > (MAX_LFS_FILESIZE >> PAGE_SHIFT)) + return -EFAULT; + + entry = radix_get_create_entry(vma, addr, inode, pgoff); + if (IS_ERR(entry)) + return PTR_ERR(entry); + + offset = addr & (sb->s_blocksize - 1); + addr = dmem_entry_to_addr(inode, entry); + + /* + * it is not beyond vma's region as the vma should be aligned + * to blocksize + */ + len = min(len, (int)(sb->s_blocksize - offset)); + maddr = __va(addr); + if (write) + memcpy(maddr + offset, buf, len); + else + memcpy(buf, maddr + offset, len); + radix_put_entry(); + + return len; +} + static vm_fault_t dmemfs_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; @@ -400,6 +445,7 @@ static unsigned long dmemfs_pagesize(struct vm_area_struct *vma) static const struct vm_operations_struct dmemfs_vm_ops = { .fault = dmemfs_fault, .pagesize = dmemfs_pagesize, + .access = dmemfs_access_dmem, }; int dmemfs_file_mmap(struct file *file, struct vm_area_struct *vma) -- 1.8.3.1
Powered by blists - more mailing lists