rev 17671 : 8186665: [aix] buffer overflow in Java_java_nio_MappedByteBuffer_isLoaded0
Reviewed-by: alanb

   1 /*
   2  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni.h"
  27 #include "jni_util.h"
  28 #include "jvm.h"
  29 #include "jlong.h"
  30 #include "java_nio_MappedByteBuffer.h"
  31 #include <assert.h>
  32 #include <sys/mman.h>
  33 #include <stddef.h>
  34 #include <stdlib.h>
  35 
  36 #ifdef _AIX
  37 #include <unistd.h>
  38 #endif
  39 
  40 
  41 #ifdef _AIX
  42 static long calculate_number_of_pages_in_range(void* address, size_t len, size_t pagesize) {
  43     uintptr_t address_unaligned = (uintptr_t) address;
  44     uintptr_t address_aligned = address_unaligned & (~(pagesize - 1));
  45     size_t len2 = len + (address_unaligned - address_aligned);
  46     long numPages = (len2 + pagesize - 1) / pagesize;
  47     return len2 + pagesize - 1 / pagesize;
  48 }
  49 #endif
  50 
  51 /* Output type for mincore(2) */
  52 #ifdef __linux__
  53 typedef unsigned char mincore_vec_t;
  54 #else
  55 typedef char mincore_vec_t;
  56 #endif
  57 
  58 JNIEXPORT jboolean JNICALL
  59 Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address,
  60                                          jlong len, jint numPages)
  61 {
  62     jboolean loaded = JNI_TRUE;
  63     int result = 0;
  64     int i = 0;
  65     void *a = (void *) jlong_to_ptr(address);
  66     mincore_vec_t* vec = NULL;
  67 
  68 #ifdef _AIX
  69     /* See JDK-8186665 */
  70     size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
  71     if ((long)pagesize == -1) {
  72         return JNI_FALSE;
  73     }
  74     numPages = (jint) calculate_number_of_pages_in_range(a, len, pagesize);
  75 #endif
  76 
  77     /* Include space for one sentinel byte at the end of the buffer
  78      * to catch overflows. */
  79     vec = (mincore_vec_t*) malloc(numPages + 1);
  80 
  81     if (vec == NULL) {
  82         JNU_ThrowOutOfMemoryError(env, NULL);
  83         return JNI_FALSE;
  84     }
  85 
  86     vec[numPages] = '\x7f'; /* Write sentinel. */
  87     result = mincore(a, (size_t)len, vec);
  88     assert(vec[numPages] == '\x7f'); /* Check sentinel. */
  89 
  90     if (result == -1) {
  91         JNU_ThrowIOExceptionWithLastError(env, "mincore failed");
  92         free(vec);
  93         return JNI_FALSE;
  94     }
  95 
  96     for (i=0; i<numPages; i++) {
  97         if (vec[i] == 0) {
  98             loaded = JNI_FALSE;
  99             break;
 100         }
 101     }
 102     free(vec);
 103     return loaded;
 104 }
 105 
 106 
 107 JNIEXPORT void JNICALL
 108 Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address,
 109                                      jlong len)
 110 {
 111     char *a = (char *)jlong_to_ptr(address);
 112     int result = madvise((caddr_t)a, (size_t)len, MADV_WILLNEED);
 113     if (result == -1) {
 114         JNU_ThrowIOExceptionWithLastError(env, "madvise failed");
 115     }
 116 }
 117 
 118 
 119 JNIEXPORT void JNICALL
 120 Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo,
 121                                       jlong address, jlong len)
 122 {
 123     void* a = (void *)jlong_to_ptr(address);
 124     int result = msync(a, (size_t)len, MS_SYNC);
 125     if (result == -1) {
 126         JNU_ThrowIOExceptionWithLastError(env, "msync failed");
 127     }
 128 }
--- EOF ---