Author: mturk
Date: Fri Jun 19 06:48:37 2009
New Revision: 786391

URL: http://svn.apache.org/viewvc?rev=786391&view=rev
Log:
Check for SELinux and create double page mapped file if it is

Added:
    commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c   (with 
props)
Modified:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecutableMemory.java
    commons/sandbox/runtime/trunk/src/main/native/Makefile.in
    commons/sandbox/runtime/trunk/src/main/native/configure
    commons/sandbox/runtime/trunk/src/main/native/os/unix/execmem.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/execmem.c
    
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecutableMemory.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecutableMemory.java?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecutableMemory.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecutableMemory.java
 Fri Jun 19 06:48:37 2009
@@ -33,6 +33,8 @@
     }
 
 
+    public static native Pointer malloc0(long size)
+        throws OutOfMemoryError;
     /**
      * Allocates {...@code size} bytes and returns a {...@link Pointer}
      * to the allocated memory. The memory has executable permissions.
@@ -43,7 +45,32 @@
      * @throws OutOfMemoryError if memory cannot be allocated.
      * @throws IllegalArgumentException if the size is less then {...@code 1}.
      */
-    public static native Pointer malloc(long size)
-        throws OutOfMemoryError, IllegalArgumentException;
+    public static Pointer malloc(long size)
+        throws OutOfMemoryError, IllegalArgumentException
+    {
+        if (size < 1L)
+            throw new IllegalArgumentException();
+
+        return malloc0(size);
+    }
+
+    public static native Pointer exec0(Pointer src);
+    /**
+     * Returns the executable {...@code page} bytes of previously allocated
+     * executable memory and returns a {...@link Pointer},
+     *
+     * @return new {...@link Pointer} containing executable memory area.
+     *
+     * @throws NullPointerException if {...@code src} is {...@code null}.
+     */
+    public static Pointer getExecutablePage(Pointer src)
+        throws NullPointerException
+    {
+        if (src == null || src.IsNull())
+            throw new NullPointerException();
+        synchronized (ExecutableMemory.class) {
+            return exec0(src);
+        }
+    }
 
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Fri Jun 19 
06:48:37 2009
@@ -91,7 +91,6 @@
        $(SRCDIR)/modules/network/ssl/openssl.$(OBJ)
 
 LINUX_OBJS= \
-       $(SRCDIR)/os/unix/execmem.$(OBJ) \
        $(SRCDIR)/os/unix/file.$(OBJ) \
        $(SRCDIR)/os/unix/main.$(OBJ) \
        $(SRCDIR)/os/unix/group.$(OBJ) \
@@ -99,6 +98,7 @@
        $(SRCDIR)/os/unix/syslog.$(OBJ) \
        $(SRCDIR)/os/unix/uuid.$(OBJ) \
        $(SRCDIR)/os/unix/uutils.$(OBJ) \
+       $(SRCDIR)/os/linux/execmem.$(OBJ) \
        $(SRCDIR)/os/linux/platform.$(OBJ) \
        $(SRCDIR)/os/linux/pgroup.$(OBJ) \
        $(SRCDIR)/os/linux/puser.$(OBJ) \

Modified: commons/sandbox/runtime/trunk/src/main/native/configure
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/configure (original)
+++ commons/sandbox/runtime/trunk/src/main/native/configure Fri Jun 19 06:48:37 
2009
@@ -677,6 +677,20 @@
     varadds ldflags "-laio"
 fi
 
+if [ ".$host" = ".linux" ]; then
+    have_selinux=`have_include selinux/selinux`
+    if [ ".$have_selinux" = ".1" ]; then
+        ok=`have_library selinux`
+        if [ ".$ok" = ".1" ]; then
+            varadds ldflags "-lselinux"
+        else
+            have_selinux=0
+        fi
+    fi
+else
+    have_selinux=0
+fi
+
 # Generate configuration header file
 #
 cat > $topdir/include/ccconfig.h << EOF
@@ -697,6 +711,7 @@
 #define HAVE_LIBAIO_H         $have_libaio
 #define HAVE_UUID_UUID_H      $have_uuid_uuid
 #define HAVE_OPENSSL          $have_openssl
+#define HAVE_SELINUX_H        $have_selinux
 #define HAS_BIG_ENDIAN        $bige
 
 #define HAVE_UNISTD_H         `have_include unistd`
@@ -806,9 +821,9 @@
     -e "s;=...@rcflags@;=$rcflags;g" \
     -e "s;=...@includes@;=$includes;g" \
     -e "s;=...@name@;=$name;g" \
-    -e "s;=...@vmajor@;$vmajor;g" \
-    -e "s;=...@vminor@;$vminor;g" \
-    -e "s;=...@vpatch@;$vpatch;g" \
+    -e "s;=...@vmajor@;=$vmajor;g" \
+    -e "s;=...@vminor@;=$vminor;g" \
+    -e "s;=...@vpatch@;=$vpatch;g" \
     -e "s;@platform@;$platform;g" \
     -e "s;@testobjs@;$testobjs;g" \
     -e "s;@modules@;$modules;g" \

Added: commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c?rev=786391&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c Fri Jun 19 
06:48:37 2009
@@ -0,0 +1,177 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_memory.h"
+#include "acr_pointer.h"
+#include "acr_error.h"
+
+#include <sys/mman.h>
+#if HAVE_SELINUX_H
+#include <selinux/selinux.h>
+#else
+#define is_selinux_enabled()    0
+#endif
+
+extern acr_size_t acr_page_size;
+static int acr_exec_file = -1;
+#define EXEC_PAGE_OFF(M, L) *((ptrdiff_t *)((char *)(M) + (L) - 
sizeof(ptrdiff_t)))
+/**
+ * Linux executable memory functions
+ *
+ */
+static int execmem_pointer_cleanup(void *mem, size_t len)
+{
+    if (mem && len) {
+        ptrdiff_t p = EXEC_PAGE_OFF(mem, len);
+        munmap(mem, len);
+        if (p) {
+            munmap((void *)p, len);
+        }
+        return 0;
+    }
+    else {
+        return ACR_EISNULL;
+    }
+}
+
+static const char *tmp_envs[] = {
+    "TMP",
+    "TEMP",
+    "TMPDIR",
+    "HOME",
+    NULL
+};
+
+static const char *tmp_path[] = {
+    "/tmp",
+    "/var/tmp",
+    NULL
+};
+
+static int exec_tempfile()
+{
+    char path[PATH_MAX];
+    int  i = 0;
+    int  fd;
+    while (tmp_path[i]) {
+        strcpy(path, tmp_path[i++]);
+        strcat(path, "/acXXXXXX");
+        if ((fd = mkstemp(path)) != -1) {
+            unlink(path);
+            return fd;
+        }
+    }
+    i = 0;
+    while (tmp_envs[i]) {
+        char *es = getenv(tmp_envs[i++]);
+        if (es) {
+            strcpy(path, es);
+            strcat(path, "/mmXXXXXX");
+            if ((fd = mkstemp(path)) != -1) {
+                unlink(path);
+                return fd;
+            }
+        }
+    }
+    return -1;
+}
+
+
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, malloc0)(ACR_JNISTDARGS,
+                                                           jlong siz)
+{
+    jobject ptr = NULL;
+    void   *mmw = NULL;
+    void   *mmx = NULL;
+    acr_size_t ass = (acr_size_t)ACR_ALIGN(siz + sizeof(ptrdiff_t), 
acr_page_size);
+
+    UNREFERENCED_O;
+#if HAVE_SELINUX_H
+    if (acr_exec_file == -1 && !is_selinux_enabled()) {
+        mmw = mmap(0, ass, PROT_READ | PROT_WRITE | PROT_EXEC,
+                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    }
+    else {
+        if (acr_exec_file == -1) {
+            acr_exec_file = exec_tempfile();
+            if (acr_exec_file == -1) {
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM,
+                                   ACR_GET_OS_ERROR());
+                return NULL;
+            }
+        }
+        ftruncate(acr_exec_file, ass);
+        mmw = mmap(NULL, ass, PROT_READ | PROT_WRITE,
+                   MAP_SHARED, acr_exec_file, 0);
+        if (mmw == NULL) {
+            int se = ACR_GET_OS_ERROR();
+            close(acr_exec_file);
+            acr_exec_file = -1;
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM, se);
+            return NULL;
+        }
+        mmx = mmap(NULL, ass, PROT_READ | PROT_EXEC,
+                   MAP_SHARED, acr_exec_file, 0);
+        if (mmx == NULL) {
+            int se = ACR_GET_OS_ERROR();
+            munmap(mmw, ass);
+            close(acr_exec_file);
+            acr_exec_file = -1;
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM, se);
+            return NULL;
+        }
+    }
+#else
+    mmw = mmap(0, ass, PROT_READ | PROT_WRITE | PROT_EXEC,
+               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+    if (mmw) {
+        EXEC_PAGE_OFF(mmw, ass) = (ptrdiff_t)mmx;
+        /* Create the Pointer class with default cleanup.
+         */
+        ptr = ACR_PointerCreate(_E, mmw, ass, execmem_pointer_cleanup);
+        if (!ptr) {
+            munmap(mmw, ass);
+            if (mmx)
+                munmap(mmx, ass);
+        }
+    }
+    else
+        ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM, ACR_GET_OS_ERROR());
+    
+    return ptr;
+}
+
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, exec0)(ACR_JNISTDARGS,
+                                                         jobject src)
+{
+    jobject po;
+    size_t  sl;
+    void   *dp;
+    char   *sp = (char *)ACR_PointerGet(_E, src, &sl);
+
+    UNREFERENCED_O;
+
+    dp = (void *)(EXEC_PAGE_OFF(sp, sl));
+    if (dp)
+        po = ACR_PointerCreate(_E, dp, sl, NULL);
+    else
+        po = ACR_PointerCreate(_E, sp, sl, NULL);
+    return po;
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/linux/execmem.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/execmem.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/execmem.c?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/execmem.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/execmem.c Fri Jun 19 
06:48:37 2009
@@ -53,21 +53,19 @@
     }
 }
 
-ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, malloc)(ACR_JNISTDARGS,
-                                                          jlong siz)
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, malloc0)(ACR_JNISTDARGS,
+                                                           jlong siz)
 {
     jobject ptr = NULL;
     void   *mem;
     acr_size_t ass = (acr_size_t)ACR_ALIGN(siz, acr_page_size);
 
     UNREFERENCED_O;
-    if (siz < 1L) {
-        ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINVAL, 0);
-        return NULL;
-    }
 #ifdef ACR_USE_MMAP
     mem = mmap(0, ass, PROT_READ | PROT_WRITE | PROT_EXEC,
                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    if (mem == NULL)
+        ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM, 
ACR_GET_OS_ERROR());    
 #else
     mem = ACR_Malloc(_E, THROW_NMARK, ass);
 #endif
@@ -85,3 +83,13 @@
     }
     return ptr;
 }
+
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, exec0)(ACR_JNISTDARGS,
+                                                         jobject src)
+{
+    size_t  sl;
+    void   *sp = ACR_PointerGet(_E, src, &sl);
+
+    UNREFERENCED_O;
+    return ACR_PointerCreate(_E, sp, sl, NULL);
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/execmem.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/execmem.c?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/execmem.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/execmem.c Fri Jun 19 
06:48:37 2009
@@ -37,18 +37,14 @@
     }
 }
 
-ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, malloc)(ACR_JNISTDARGS,
-                                                          jlong siz)
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, malloc0)(ACR_JNISTDARGS,
+                                                           jlong siz)
 {
     jobject ptr = NULL;
     void   *mem;
     acr_size_t ass = (acr_size_t)ACR_ALIGN(siz, acr_page_size);
 
     UNREFERENCED_O;
-    if (siz < 1L) {
-        ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINVAL, 0);
-        return NULL;
-    }
     mem = VirtualAlloc(NULL, ass,
                        MEM_COMMIT | MEM_RESERVE,
                        PAGE_EXECUTE_READWRITE);
@@ -60,5 +56,17 @@
             VirtualFree(mem, 0, MEM_RELEASE);
         }
     }
+    else
+        ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENOMEM, ACR_GET_OS_ERROR());
     return ptr;
 }
+
+ACR_JNI_EXPORT_DECLARE(jobject, ExecutableMemory, exec0)(ACR_JNISTDARGS,
+                                                         jobject src)
+{
+    size_t  sl;
+    void   *sp = ACR_PointerGet(_E, src, &sl);
+
+    UNREFERENCED_O;
+    return ACR_PointerCreate(_E, sp, sl, NULL);
+}

Modified: 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java?rev=786391&r1=786390&r2=786391&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
 Fri Jun 19 06:48:37 2009
@@ -110,6 +110,18 @@
         p.free();
     }
 
+    public void testExecutableExec()
+        throws Throwable
+    {
+        Pointer w = ExecutableMemory.malloc(1000);
+        assertNotNull("ExecutableWritePointer", w);
+        w.poke(999, 23);
+        Pointer x = ExecutableMemory.getExecutablePage(w);
+        assertNotNull("ExecutableExecPointer", x);
+        assertEquals("Value", 23, x.peek(999));
+        w.free();
+    }
+
     public void testSlice()
         throws Throwable
     {
@@ -191,9 +203,12 @@
         assertNotNull("Array", b);
         try {
             char[] c = Memory.toCharArray(p, 0, 501);
-            fail("Missing IndexOutOfBoundsException");
+            fail("Exception not thrown");
         } catch (IndexOutOfBoundsException ix) {
             // Succedded.
+        } catch (Exception ex) {
+            // Succedded.
+            fail("Missing IndexOutOfBoundsException");
         }
         p.free();
     }


Reply via email to