All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register()
@ 2014-05-19 18:40 Oleg Nesterov
  2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Oleg Nesterov @ 2014-05-19 18:40 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Denys Vlasenko, Hugh Dickins, Peter Zijlstra, Srikar Dronamraju,
	linux-kernel

Sorry for double-posting, but it seems that this patch didn't reach
lkml. Let me resend it just on case. Plus another patch in reply, on
top of this change.

-------------------------------------------------------------------------------
Subject: [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register()

copy_insn() fails with -EIO if ->readpage == NULL, but this error
is not propagated unless uprobe_register() path finds ->mm which
already mmaps this file. In this case (say) "perf record" does not
actually install the probe, but the user can't know about this.

Move this check into uprobe_register() so that this problem can be
detected earlier and reported to user.

Note: this is still not perfect,

	- copy_insn() and arch_uprobe_analyze_insn() should be called
	  by uprobe_register() but this is not simple, we need vm_file
	  for read_mapping_page() (although perhaps we can pass NULL),
	  and we need ->mm for is_64bit_mm() (although this logic is
	  broken anyway).

	- uprobe_register() should be called by create_trace_uprobe(),
	  not by probe_event_enable(), so that an error can be detected
	  at "perf probe -x" time. This also needs more changes in the
	  core uprobe code, uprobe register/unregister interface was
	  poorly designed from the very beginning.

Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/events/uprobes.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 3b02c72..c56b13e 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -536,9 +536,6 @@ static int __copy_insn(struct address_space *mapping, struct file *filp,
 			void *insn, int nbytes, loff_t offset)
 {
 	struct page *page;
-
-	if (!mapping->a_ops->readpage)
-		return -EIO;
 	/*
 	 * Ensure that the page that has the original instruction is
 	 * populated and in page-cache.
@@ -879,6 +876,9 @@ 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)
+		return -EIO;
 	/* Racy, just to catch the obvious mistakes */
 	if (offset > i_size_read(inode))
 		return -EINVAL;
-- 
1.5.5.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] uprobes: Teach copy_insn() to support tmpfs
  2014-05-19 18:40 [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Oleg Nesterov
@ 2014-05-19 18:41 ` Oleg Nesterov
  2014-05-21  8:54   ` Srikar Dronamraju
  2014-06-05 14:39   ` [tip:perf/core] " tip-bot for Oleg Nesterov
  2014-05-21  8:53 ` [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Srikar Dronamraju
  2014-06-05 14:38 ` [tip:perf/core] uprobes: Shift ->readpage check from __copy_insn( ) " tip-bot for Oleg Nesterov
  2 siblings, 2 replies; 6+ messages in thread
From: Oleg Nesterov @ 2014-05-19 18:41 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Denys Vlasenko, Hugh Dickins, Peter Zijlstra, Srikar Dronamraju,
	linux-kernel

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 <dvlasenk@redhat.com>
Suggested-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/events/uprobes.c |   15 ++++++++++-----
 1 files 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))
-- 
1.5.5.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register()
  2014-05-19 18:40 [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Oleg Nesterov
  2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
@ 2014-05-21  8:53 ` Srikar Dronamraju
  2014-06-05 14:38 ` [tip:perf/core] uprobes: Shift ->readpage check from __copy_insn( ) " tip-bot for Oleg Nesterov
  2 siblings, 0 replies; 6+ messages in thread
From: Srikar Dronamraju @ 2014-05-21  8:53 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Ingo Molnar, Denys Vlasenko, Hugh Dickins, Peter Zijlstra,
	linux-kernel

* Oleg Nesterov <oleg@redhat.com> [2014-05-19 20:40:54]:

> Sorry for double-posting, but it seems that this patch didn't reach
> lkml. Let me resend it just on case. Plus another patch in reply, on
> top of this change.
> 
> -------------------------------------------------------------------------------
> Subject: [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register()
> 
> copy_insn() fails with -EIO if ->readpage == NULL, but this error
> is not propagated unless uprobe_register() path finds ->mm which
> already mmaps this file. In this case (say) "perf record" does not
> actually install the probe, but the user can't know about this.
> 
> Move this check into uprobe_register() so that this problem can be
> detected earlier and reported to user.
> 
> Note: this is still not perfect,
> 
> 	- copy_insn() and arch_uprobe_analyze_insn() should be called
> 	  by uprobe_register() but this is not simple, we need vm_file
> 	  for read_mapping_page() (although perhaps we can pass NULL),
> 	  and we need ->mm for is_64bit_mm() (although this logic is
> 	  broken anyway).
> 
> 	- uprobe_register() should be called by create_trace_uprobe(),
> 	  not by probe_event_enable(), so that an error can be detected
> 	  at "perf probe -x" time. This also needs more changes in the
> 	  core uprobe code, uprobe register/unregister interface was
> 	  poorly designed from the very beginning.
> 
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

-- 
Thanks and Regards
Srikar Dronamraju


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] uprobes: Teach copy_insn() to support tmpfs
  2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
@ 2014-05-21  8:54   ` Srikar Dronamraju
  2014-06-05 14:39   ` [tip:perf/core] " tip-bot for Oleg Nesterov
  1 sibling, 0 replies; 6+ messages in thread
From: Srikar Dronamraju @ 2014-05-21  8:54 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Ingo Molnar, Denys Vlasenko, Hugh Dickins, Peter Zijlstra,
	linux-kernel

* Oleg Nesterov <oleg@redhat.com> [2014-05-19 20:41:36]:

> 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 <dvlasenk@redhat.com>
> Suggested-by: Hugh Dickins <hughd@google.com>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

-- 
Thanks and Regards
Srikar Dronamraju


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [tip:perf/core] uprobes: Shift ->readpage check from __copy_insn( ) to uprobe_register()
  2014-05-19 18:40 [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Oleg Nesterov
  2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
  2014-05-21  8:53 ` [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Srikar Dronamraju
@ 2014-06-05 14:38 ` tip-bot for Oleg Nesterov
  2 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Oleg Nesterov @ 2014-06-05 14:38 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, torvalds, peterz, acme, hughd, dvlasenk,
	srikar, tglx, oleg

Commit-ID:  41ccba029e9492dd0fc1bf5c23b72c6322a6dfe9
Gitweb:     http://git.kernel.org/tip/41ccba029e9492dd0fc1bf5c23b72c6322a6dfe9
Author:     Oleg Nesterov <oleg@redhat.com>
AuthorDate: Mon, 19 May 2014 20:40:54 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 5 Jun 2014 12:30:07 +0200

uprobes: Shift ->readpage check from __copy_insn() to uprobe_register()

copy_insn() fails with -EIO if ->readpage == NULL, but this error
is not propagated unless uprobe_register() path finds ->mm which
already mmaps this file. In this case (say) "perf record" does not
actually install the probe, but the user can't know about this.

Move this check into uprobe_register() so that this problem can be
detected earlier and reported to user.

Note: this is still not perfect,

	- copy_insn() and arch_uprobe_analyze_insn() should be called
	  by uprobe_register() but this is not simple, we need vm_file
	  for read_mapping_page() (although perhaps we can pass NULL),
	  and we need ->mm for is_64bit_mm() (although this logic is
	  broken anyway).

	- uprobe_register() should be called by create_trace_uprobe(),
	  not by probe_event_enable(), so that an error can be detected
	  at "perf probe -x" time. This also needs more changes in the
	  core uprobe code, uprobe register/unregister interface was
	  poorly designed from the very beginning.

Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/20140519184054.GA6750@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/events/uprobes.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 3b02c72..c56b13e 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -536,9 +536,6 @@ static int __copy_insn(struct address_space *mapping, struct file *filp,
 			void *insn, int nbytes, loff_t offset)
 {
 	struct page *page;
-
-	if (!mapping->a_ops->readpage)
-		return -EIO;
 	/*
 	 * Ensure that the page that has the original instruction is
 	 * populated and in page-cache.
@@ -879,6 +876,9 @@ 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)
+		return -EIO;
 	/* Racy, just to catch the obvious mistakes */
 	if (offset > i_size_read(inode))
 		return -EINVAL;

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [tip:perf/core] uprobes: Teach copy_insn() to support tmpfs
  2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
  2014-05-21  8:54   ` Srikar Dronamraju
@ 2014-06-05 14:39   ` tip-bot for Oleg Nesterov
  1 sibling, 0 replies; 6+ messages in thread
From: tip-bot for Oleg Nesterov @ 2014-06-05 14:39 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, torvalds, peterz, acme, hughd, dvlasenk,
	srikar, tglx, oleg

Commit-ID:  40814f6805a524130a5ec313871147f7aa9b5318
Gitweb:     http://git.kernel.org/tip/40814f6805a524130a5ec313871147f7aa9b5318
Author:     Oleg Nesterov <oleg@redhat.com>
AuthorDate: Mon, 19 May 2014 20:41:36 +0200
Committer:  Ingo Molnar <mingo@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 <dvlasenk@redhat.com>
Suggested-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/20140519184136.GB6750@redhat.com
Signed-off-by: Ingo Molnar <mingo@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))

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-06-05 14:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-19 18:40 [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Oleg Nesterov
2014-05-19 18:41 ` [PATCH] uprobes: Teach copy_insn() to support tmpfs Oleg Nesterov
2014-05-21  8:54   ` Srikar Dronamraju
2014-06-05 14:39   ` [tip:perf/core] " tip-bot for Oleg Nesterov
2014-05-21  8:53 ` [PATCH] uprobes: Shift ->readpage check from __copy_insn() to uprobe_register() Srikar Dronamraju
2014-06-05 14:38 ` [tip:perf/core] uprobes: Shift ->readpage check from __copy_insn( ) " tip-bot for Oleg Nesterov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.