Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c
32288 views
/*1* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "jni.h"26#include "jni_util.h"27#include "jvm.h"2829#include <stdio.h>30#include <stdlib.h>31#include <string.h>32#include <errno.h>33#include <unistd.h>34#include <signal.h>35#include <dirent.h>36#include <ctype.h>37#include <sys/types.h>38#include <sys/socket.h>39#include <sys/stat.h>40#include <sys/syslimits.h>41#include <sys/un.h>42#include <fcntl.h>4344#include "sun_tools_attach_BsdVirtualMachine.h"4546#define RESTARTABLE(_cmd, _result) do { \47do { \48_result = _cmd; \49} while((_result == -1) && (errno == EINTR)); \50} while(0)5152/*53* Class: sun_tools_attach_BsdVirtualMachine54* Method: socket55* Signature: ()I56*/57JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_socket58(JNIEnv *env, jclass cls)59{60int fd = socket(PF_UNIX, SOCK_STREAM, 0);61if (fd == -1) {62JNU_ThrowIOExceptionWithLastError(env, "socket");63}64return (jint)fd;65}6667/*68* Class: sun_tools_attach_BsdVirtualMachine69* Method: connect70* Signature: (ILjava/lang/String;)I71*/72JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_connect73(JNIEnv *env, jclass cls, jint fd, jstring path)74{75jboolean isCopy;76const char* p = GetStringPlatformChars(env, path, &isCopy);77if (p != NULL) {78struct sockaddr_un addr;79int err = 0;8081addr.sun_family = AF_UNIX;82strcpy(addr.sun_path, p);8384if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {85err = errno;86}8788if (isCopy) {89JNU_ReleaseStringPlatformChars(env, path, p);90}9192/*93* If the connect failed then we throw the appropriate exception94* here (can't throw it before releasing the string as can't call95* JNI with pending exception)96*/97if (err != 0) {98if (err == ENOENT) {99JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL);100} else {101char* msg = strdup(strerror(err));102JNU_ThrowIOException(env, msg);103if (msg != NULL) {104free(msg);105}106}107}108}109}110111/*112* Class: sun_tools_attach_BsdVirtualMachine113* Method: sendQuitTo114* Signature: (I)V115*/116JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_sendQuitTo117(JNIEnv *env, jclass cls, jint pid)118{119if (kill((pid_t)pid, SIGQUIT)) {120JNU_ThrowIOExceptionWithLastError(env, "kill");121}122}123124/*125* Class: sun_tools_attach_BsdVirtualMachine126* Method: checkPermissions127* Signature: (Ljava/lang/String;)V128*/129JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_checkPermissions130(JNIEnv *env, jclass cls, jstring path)131{132jboolean isCopy;133const char* p = GetStringPlatformChars(env, path, &isCopy);134if (p != NULL) {135struct stat sb;136uid_t uid, gid;137int res;138139/*140* Check that the path is owned by the effective uid/gid of this141* process. Also check that group/other access is not allowed.142*/143uid = geteuid();144gid = getegid();145146res = stat(p, &sb);147if (res != 0) {148/* save errno */149res = errno;150}151152if (res == 0) {153char msg[100];154jboolean isError = JNI_FALSE;155if (sb.st_uid != uid) {156jio_snprintf(msg, sizeof(msg)-1,157"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);158isError = JNI_TRUE;159} else if (sb.st_gid != gid) {160jio_snprintf(msg, sizeof(msg)-1,161"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);162isError = JNI_TRUE;163} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {164jio_snprintf(msg, sizeof(msg)-1,165"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);166isError = JNI_TRUE;167}168if (isError) {169char buf[256];170jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);171JNU_ThrowIOException(env, buf);172}173} else {174char* msg = strdup(strerror(res));175JNU_ThrowIOException(env, msg);176if (msg != NULL) {177free(msg);178}179}180181if (isCopy) {182JNU_ReleaseStringPlatformChars(env, path, p);183}184}185}186187/*188* Class: sun_tools_attach_BsdVirtualMachine189* Method: close190* Signature: (I)V191*/192JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_close193(JNIEnv *env, jclass cls, jint fd)194{195int res;196RESTARTABLE(close(fd), res);197}198199/*200* Class: sun_tools_attach_BsdVirtualMachine201* Method: read202* Signature: (I[BI)I203*/204JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_read205(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen)206{207unsigned char buf[128];208size_t len = sizeof(buf);209ssize_t n;210211size_t remaining = (size_t)(baLen - off);212if (len > remaining) {213len = remaining;214}215216RESTARTABLE(read(fd, buf, len), n);217if (n == -1) {218JNU_ThrowIOExceptionWithLastError(env, "read");219} else {220if (n == 0) {221n = -1; // EOF222} else {223(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));224}225}226return n;227}228229/*230* Class: sun_tools_attach_BsdVirtualMachine231* Method: write232* Signature: (I[B)V233*/234JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_write235(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint bufLen)236{237size_t remaining = bufLen;238do {239unsigned char buf[128];240size_t len = sizeof(buf);241int n;242243if (len > remaining) {244len = remaining;245}246(*env)->GetByteArrayRegion(env, ba, off, len, (jbyte *)buf);247248RESTARTABLE(write(fd, buf, len), n);249if (n > 0) {250off += n;251remaining -= n;252} else {253JNU_ThrowIOExceptionWithLastError(env, "write");254return;255}256257} while (remaining > 0);258}259260/*261* Class: sun_tools_attach_BSDVirtualMachine262* Method: createAttachFile263* Signature: (Ljava.lang.String;)V264*/265JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_createAttachFile(JNIEnv *env, jclass cls, jstring path)266{267const char* _path;268jboolean isCopy;269int fd, rc;270271_path = GetStringPlatformChars(env, path, &isCopy);272if (_path == NULL) {273JNU_ThrowIOException(env, "Must specify a path");274return;275}276277RESTARTABLE(open(_path, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR), fd);278if (fd == -1) {279/* release p here before we throw an I/O exception */280if (isCopy) {281JNU_ReleaseStringPlatformChars(env, path, _path);282}283JNU_ThrowIOExceptionWithLastError(env, "open");284return;285}286287RESTARTABLE(chown(_path, geteuid(), getegid()), rc);288289RESTARTABLE(close(fd), rc);290291/* release p here */292if (isCopy) {293JNU_ReleaseStringPlatformChars(env, path, _path);294}295}296297/*298* Class: sun_tools_attach_BSDVirtualMachine299* Method: getTempDir300* Signature: (V)Ljava.lang.String;301*/302JNIEXPORT jstring JNICALL Java_sun_tools_attach_BsdVirtualMachine_getTempDir(JNIEnv *env, jclass cls)303{304// This must be hard coded because it's the system's temporary305// directory not the java application's temp directory, ala java.io.tmpdir.306307#ifdef __APPLE__308// macosx has a secure per-user temporary directory309static char *temp_path = NULL;310char temp_path_storage[PATH_MAX];311if (temp_path == NULL) {312int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX);313if (pathSize == 0 || pathSize > PATH_MAX) {314strlcpy(temp_path_storage, "/tmp", sizeof(temp_path_storage));315}316temp_path = temp_path_storage;317}318return JNU_NewStringPlatform(env, temp_path);319#else /* __APPLE__ */320return (*env)->NewStringUTF(env, "/tmp");321#endif /* __APPLE__ */322}323324325