Commit-ID:  40814f6805a524130a5ec313871147f7aa9b5318
Gitweb:     http://git.kernel.org/tip/40814f6805a524130a5ec313871147f7aa9b5318
Author:     Oleg Nesterov <o...@redhat.com>
AuthorDate: Mon, 19 May 2014 20:41:36 +0200
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 5 Jun 2014 12:30:11 +0200

uprobes: Teach copy_insn() to support tmpfs

tmpfs is widely used but as Denys reports shmem_aops doesn't have
->readpage() and thus you can't probe a binary on this filesystem.

As Hugh suggested we can use shmem_read_mapping_page() in this case,
just we need to check shmem_mapping() if ->readpage == NULL.

Reported-by: Denys Vlasenko <dvlas...@redhat.com>
Suggested-by: Hugh Dickins <hu...@google.com>
Signed-off-by: Oleg Nesterov <o...@redhat.com>
Acked-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra <pet...@infradead.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Link: http://lkml.kernel.org/r/20140519184136.gb6...@redhat.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 kernel/events/uprobes.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index c56b13e..6bfb671 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -36,6 +36,7 @@
 #include "../../mm/internal.h" /* munlock_vma_page */
 #include <linux/percpu-rwsem.h>
 #include <linux/task_work.h>
+#include <linux/shmem_fs.h>
 
 #include <linux/uprobes.h>
 
@@ -537,10 +538,14 @@ static int __copy_insn(struct address_space *mapping, 
struct file *filp,
 {
        struct page *page;
        /*
-        * Ensure that the page that has the original instruction is
-        * populated and in page-cache.
+        * Ensure that the page that has the original instruction is populated
+        * and in page-cache. If ->readpage == NULL it must be shmem_mapping(),
+        * see uprobe_register().
         */
-       page = read_mapping_page(mapping, offset >> PAGE_CACHE_SHIFT, filp);
+       if (mapping->a_ops->readpage)
+               page = read_mapping_page(mapping, offset >> PAGE_CACHE_SHIFT, 
filp);
+       else
+               page = shmem_read_mapping_page(mapping, offset >> 
PAGE_CACHE_SHIFT);
        if (IS_ERR(page))
                return PTR_ERR(page);
 
@@ -876,8 +881,8 @@ int uprobe_register(struct inode *inode, loff_t offset, 
struct uprobe_consumer *
        if (!uc->handler && !uc->ret_handler)
                return -EINVAL;
 
-       /* copy_insn()->read_mapping_page() needs ->readpage() */
-       if (!inode->i_mapping->a_ops->readpage)
+       /* copy_insn() uses read_mapping_page() or shmem_read_mapping_page() */
+       if (!inode->i_mapping->a_ops->readpage && 
!shmem_mapping(inode->i_mapping))
                return -EIO;
        /* Racy, just to catch the obvious mistakes */
        if (offset > i_size_read(inode))
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to