Hi Frank, Jim, Mark,

This fix is equivalent to commit
a82ac1f413712a375d5e14ef7641ce0abf7a6543 in systemtap tree.
--

We allocate a "fake" unlinked shmem file because anonymous
memory might not be granted execute permission when the
selinux security hooks have their way.

Signed-off-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
Signed-off-by: Mark Wielaard <m...@redhat.com>
---
 kernel/ubp_xol.c |   38 ++++++++++++++++++++++++++++----------
 1 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/kernel/ubp_xol.c b/kernel/ubp_xol.c
index 017b3cf..4205ab7 100644
--- a/kernel/ubp_xol.c
+++ b/kernel/ubp_xol.c
@@ -35,6 +35,7 @@
 #include <linux/ubp.h>
 #include <linux/errno.h>
 #include <linux/mman.h>
+#include <linux/file.h>
 
 #define UINSNS_PER_PAGE        (PAGE_SIZE/UBP_XOL_SLOT_BYTES)
 
@@ -339,6 +340,7 @@ static inline struct ubp_xol_vma *xol_add_vma(struct 
ubp_xol_area *area)
        struct vm_area_struct *vma;
        struct ubp_xol_vma *usv;
        struct mm_struct *mm;
+       struct file *file;
        unsigned long addr;
 
        mm = get_task_mm(current);
@@ -356,22 +358,31 @@ static inline struct ubp_xol_vma *xol_add_vma(struct 
ubp_xol_area *area)
         * 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.
         */
        vma = rb_entry(rb_last(&mm->mm_rb), struct vm_area_struct, vm_rb);
        addr = vma->vm_end + PAGE_SIZE;
-       addr = do_mmap_pgoff(NULL, addr, PAGE_SIZE, PROT_EXEC,
-                               MAP_PRIVATE|MAP_ANONYMOUS, 0);
-       if (addr & ~PAGE_MASK) {
-               up_write(&mm->mmap_sem);
-               mmput(mm);
-               printk(KERN_ERR "ubp_xol failed to allocate a vma for"
-                       " pid/tgid %d/%d for single-stepping out of line.\n",
+       file = shmem_file_setup("uprobes/ssol", PAGE_SIZE, VM_NORESERVE);
+       if (!file) {
+               printk(KERN_ERR "ubp_xol failed to setup shmem_file while "
+                       "allocating vma for pid/tgid %d/%d for "
+                       "single-stepping out of line.\n",
                        current->pid, current->tgid);
-               kfree(usv->bitmap);
-               kfree(usv);
-               return ERR_PTR(-ENOMEM);
+               goto fail;
        }
+       addr = do_mmap_pgoff(file, addr, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, 0);
+       fput(file);
 
+       if (addr & ~PAGE_MASK) {
+               printk(KERN_ERR "ubp_xol failed to allocate a vma for pid/tgid"
+                               " %d/%d for single-stepping out of line.\n",
+                               current->pid, current->tgid);
+               goto fail;
+       }
        vma = find_vma(mm, addr);
        BUG_ON(!vma);
 
@@ -392,6 +403,13 @@ static inline struct ubp_xol_vma *xol_add_vma(struct 
ubp_xol_area *area)
        list_add_tail(&usv->list, &area->vmas);
        area->last_vma = usv;
        return usv;
+
+fail:
+       up_write(&mm->mmap_sem);
+       mmput(mm);
+       kfree(usv->bitmap);
+       kfree(usv);
+       return ERR_PTR(-ENOMEM);
 }
 
 /* Runs with area->mutex locked */

Reply via email to