diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-09-17 12:20:07 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-09-17 12:20:07 +0200 |
commit | a82ac1f413712a375d5e14ef7641ce0abf7a6543 (patch) | |
tree | 9f5b8441eb6e15b26460d3417417b0c1e5e1859b | |
parent | 6ad6cb16ba7624c66e3c173f66e44a9ba34c9cd4 (diff) | |
download | systemtap-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.c | 35 |
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; } |