/* * Class: sun_tools_attach_BSDVirtualMachine * Method: createAttachFile * Signature: (Ljava.lang.String;)V */ JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_createAttachFile(JNIEnv *env, jclass cls, jstring path) { const char* _path; jboolean isCopy; int fd, rc; _path = GetStringPlatformChars(env, path, &isCopy); if (_path == NULL) { JNU_ThrowIOException(env, "Must specify a path"); return; } RESTARTABLE(open(_path, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR), fd); if (fd == -1) { /* release p here before we throw an I/O exception */ if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, _path); } JNU_ThrowIOExceptionWithLastError(env, "open"); return; } RESTARTABLE(chown(_path, geteuid(), getegid()), rc); RESTARTABLE(close(fd), rc); /* release p here */ if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, _path); } }
/* * Class: sun_tools_attach_VirtualMachineImpl * Method: open * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_open (JNIEnv *env, jclass cls, jstring path) { jboolean isCopy; const char* p = GetStringPlatformChars(env, path, &isCopy); if (p == NULL) { return 0; } else { int fd; int err = 0; fd = open(p, O_RDWR); if (fd == -1) { err = errno; } if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, p); } if (fd == -1) { if (err == ENOENT) { JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL); } else { char* msg = strdup(strerror(err)); JNU_ThrowIOException(env, msg); if (msg != NULL) { free(msg); } } } return fd; } }
/* * Class: sun_tools_attach_VirtualMachineImpl * Method: checkPermissions * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions (JNIEnv *env, jclass cls, jstring path) { jboolean isCopy; const char* p = GetStringPlatformChars(env, path, &isCopy); if (p != NULL) { struct stat64 sb; uid_t uid, gid; int res; /* * Check that the path is owned by the effective uid/gid of this * process. Also check that group/other access is not allowed. */ uid = geteuid(); gid = getegid(); res = stat64(p, &sb); if (res != 0) { /* save errno */ res = errno; } if (res == 0) { char msg[100]; jboolean isError = JNI_FALSE; if (sb.st_uid != uid) { jio_snprintf(msg, sizeof(msg)-1, "file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid); isError = JNI_TRUE; } else if (sb.st_gid != gid) { jio_snprintf(msg, sizeof(msg)-1, "file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid); isError = JNI_TRUE; } else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) { jio_snprintf(msg, sizeof(msg)-1, "file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777); isError = JNI_TRUE; } if (isError) { char buf[256]; jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg); JNU_ThrowIOException(env, buf); } } else { char* msg = strdup(strerror(res)); JNU_ThrowIOException(env, msg); if (msg != NULL) { free(msg); } } if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, p); } } }
/* * Class: sun_tools_attach_LinuxVirtualMachine * Method: checkPermissions * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_tools_attach_LinuxVirtualMachine_checkPermissions (JNIEnv *env, jclass cls, jstring path) { jboolean isCopy; const char* p = GetStringPlatformChars(env, path, &isCopy); if (p != NULL) { struct stat64 sb; uid_t uid, gid; int res; /* * Check that the path is owned by the effective uid/gid of this * process. Also check that group/other access is not allowed. */ uid = geteuid(); gid = getegid(); res = stat64(p, &sb); if (res != 0) { /* save errno */ res = errno; } /* release p here before we throw an I/O exception */ if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, p); } if (res == 0) { if ( (sb.st_uid != uid) || (sb.st_gid != gid) || ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) ) { JNU_ThrowIOException(env, "well-known file is not secure"); } } else { char* msg = strdup(strerror(res)); JNU_ThrowIOException(env, msg); if (msg != NULL) { free(msg); } } } }
/* * Class: sun_tools_attach_VirtualMachineImpl * Method: connect * Signature: (ILjava/lang/String;)I */ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect (JNIEnv *env, jclass cls, jint fd, jstring path) { jboolean isCopy; const char* p = GetStringPlatformChars(env, path, &isCopy); if (p != NULL) { struct sockaddr_un addr; int err = 0; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; /* strncpy is safe because addr.sun_path was zero-initialized before. */ strncpy(addr.sun_path, p, sizeof(addr.sun_path) - 1); if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { err = errno; } if (isCopy) { JNU_ReleaseStringPlatformChars(env, path, p); } /* * If the connect failed then we throw the appropriate exception * here (can't throw it before releasing the string as can't call * JNI with pending exception) */ if (err != 0) { if (err == ENOENT) { JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL); } else { char* msg = strdup(strerror(err)); JNU_ThrowIOException(env, msg); if (msg != NULL) { free(msg); } } } } }