summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-09-17 12:20:07 +0200
committerMark Wielaard <mjw@redhat.com>2009-09-17 12:20:07 +0200
commita82ac1f413712a375d5e14ef7641ce0abf7a6543 (patch)
tree9f5b8441eb6e15b26460d3417417b0c1e5e1859b
parent6ad6cb16ba7624c66e3c173f66e44a9ba34c9cd4 (diff)
downloadsystemtap-steved-a82ac1f413712a375d5e14ef7641ce0abf7a6543.tar.gz
systemtap-steved-a82ac1f413712a375d5e14ef7641ce0abf7a6543.tar.xz
systemtap-steved-a82ac1f413712a375d5e14ef7641ce0abf7a6543.zip
PR10595 Work around uprobe2 causing selinux failures for kernel 2.6.28+.
We allocate a "fake" unlinked shmem file because anonymous memory might not be granted execute permission when the selinux security hooks have their way. Only do this for 2.6.28 or higher since shmem_file_setup() isn't exported before that. * runtime/uprobes2/uprobes.c (uprobe_setup_ssol_vma): Use shmem_file_setup to setup the ssol vma area when using 2.6.28+.
-rw-r--r--runtime/uprobes2/uprobes.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/runtime/uprobes2/uprobes.c b/runtime/uprobes2/uprobes.c
index 07ad3984..edf882a6 100644
--- a/runtime/uprobes2/uprobes.c
+++ b/runtime/uprobes2/uprobes.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) IBM Corporation, 2006
+ * Copyright (C) Red Hat, Inc. 2009
*/
#include <linux/types.h>
#include <linux/hash.h>
@@ -28,6 +29,8 @@
#include <linux/kref.h>
#include <linux/utrace.h>
#include <linux/regset.h>
+#include <linux/file.h>
+#include <linux/version.h>
#define UPROBES_IMPLEMENTATION 1
/* PR9974: Adapt to struct renaming. */
@@ -1387,6 +1390,9 @@ static noinline unsigned long uprobe_setup_ssol_vma(unsigned long nbytes)
unsigned long addr;
struct mm_struct *mm;
struct vm_area_struct *vma;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ struct file *file;
+#endif
BUG_ON(nbytes & ~PAGE_MASK);
if ((addr = find_old_ssol_vma()) != 0)
@@ -1400,17 +1406,40 @@ static noinline unsigned long uprobe_setup_ssol_vma(unsigned long nbytes)
* Find the end of the top mapping and skip a page.
* If there is no space for PAGE_SIZE above
* that, mmap will ignore our address hint.
+ *
+ * We allocate a "fake" unlinked shmem file because anonymous
+ * memory might not be granted execute permission when the selinux
+ * security hooks have their way. Only do this for 2.6.28 or higher
+ * since shmem_file_setup() isn't exported before that.
*/
vma = rb_entry(rb_last(&mm->mm_rb), struct vm_area_struct, vm_rb);
addr = vma->vm_end + PAGE_SIZE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ file = shmem_file_setup("uprobes/ssol", nbytes, VM_NORESERVE);
+ if (file) {
+ addr = do_mmap_pgoff(file, addr, nbytes, PROT_EXEC,
+ MAP_PRIVATE, 0);
+ fput(file);
+ }
+ if (!file || addr & ~PAGE_MASK) {
+#else
addr = do_mmap_pgoff(NULL, addr, nbytes, PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, 0);
if (addr & ~PAGE_MASK) {
+#endif
up_write(&mm->mmap_sem);
mmput(mm);
- printk(KERN_ERR "Uprobes failed to allocate a vma for"
- " pid/tgid %d/%d for single-stepping out of line.\n",
- current->pid, current->tgid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ if (!file)
+ printk(KERN_ERR "Uprobes shmem_file_setup failed while"
+ " allocating vma for pid/tgid %d/%d for"
+ " single-stepping out of line.\n",
+ current->pid, current->tgid);
+ else
+#endif
+ printk(KERN_ERR "Uprobes failed to allocate a vma for"
+ " pid/tgid %d/%d for single-stepping out of"
+ " line.\n", current->pid, current->tgid);
return addr;
}