Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c
32288 views
1
/*
2
* Copyright (c) 2005, 2017, 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
30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <unistd.h>
35
#include <signal.h>
36
#include <dirent.h>
37
#include <ctype.h>
38
#include <sys/types.h>
39
#include <sys/socket.h>
40
#include <sys/stat.h>
41
#include <sys/syslimits.h>
42
#include <sys/un.h>
43
#include <fcntl.h>
44
45
#include "sun_tools_attach_BsdVirtualMachine.h"
46
47
#define RESTARTABLE(_cmd, _result) do { \
48
do { \
49
_result = _cmd; \
50
} while((_result == -1) && (errno == EINTR)); \
51
} while(0)
52
53
/*
54
* Class: sun_tools_attach_BsdVirtualMachine
55
* Method: socket
56
* Signature: ()I
57
*/
58
JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_socket
59
(JNIEnv *env, jclass cls)
60
{
61
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
62
if (fd == -1) {
63
JNU_ThrowIOExceptionWithLastError(env, "socket");
64
}
65
return (jint)fd;
66
}
67
68
/*
69
* Class: sun_tools_attach_BsdVirtualMachine
70
* Method: connect
71
* Signature: (ILjava/lang/String;)I
72
*/
73
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_connect
74
(JNIEnv *env, jclass cls, jint fd, jstring path)
75
{
76
jboolean isCopy;
77
const char* p = GetStringPlatformChars(env, path, &isCopy);
78
if (p != NULL) {
79
struct sockaddr_un addr;
80
int err = 0;
81
82
addr.sun_family = AF_UNIX;
83
strcpy(addr.sun_path, p);
84
85
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
86
err = errno;
87
}
88
89
if (isCopy) {
90
JNU_ReleaseStringPlatformChars(env, path, p);
91
}
92
93
/*
94
* If the connect failed then we throw the appropriate exception
95
* here (can't throw it before releasing the string as can't call
96
* JNI with pending exception)
97
*/
98
if (err != 0) {
99
if (err == ENOENT) {
100
JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL);
101
} else {
102
char* msg = strdup(strerror(err));
103
JNU_ThrowIOException(env, msg);
104
if (msg != NULL) {
105
free(msg);
106
}
107
}
108
}
109
}
110
}
111
112
/*
113
* Class: sun_tools_attach_BsdVirtualMachine
114
* Method: sendQuitTo
115
* Signature: (I)V
116
*/
117
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_sendQuitTo
118
(JNIEnv *env, jclass cls, jint pid)
119
{
120
if (kill((pid_t)pid, SIGQUIT)) {
121
JNU_ThrowIOExceptionWithLastError(env, "kill");
122
}
123
}
124
125
/*
126
* Class: sun_tools_attach_BsdVirtualMachine
127
* Method: checkPermissions
128
* Signature: (Ljava/lang/String;)V
129
*/
130
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_checkPermissions
131
(JNIEnv *env, jclass cls, jstring path)
132
{
133
jboolean isCopy;
134
const char* p = GetStringPlatformChars(env, path, &isCopy);
135
if (p != NULL) {
136
struct stat sb;
137
uid_t uid, gid;
138
int res;
139
140
/*
141
* Check that the path is owned by the effective uid/gid of this
142
* process. Also check that group/other access is not allowed.
143
*/
144
uid = geteuid();
145
gid = getegid();
146
147
res = stat(p, &sb);
148
if (res != 0) {
149
/* save errno */
150
res = errno;
151
}
152
153
if (res == 0) {
154
char msg[100];
155
jboolean isError = JNI_FALSE;
156
if (sb.st_uid != uid) {
157
jio_snprintf(msg, sizeof(msg)-1,
158
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
159
isError = JNI_TRUE;
160
} else if (sb.st_gid != gid) {
161
jio_snprintf(msg, sizeof(msg)-1,
162
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
163
isError = JNI_TRUE;
164
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
165
jio_snprintf(msg, sizeof(msg)-1,
166
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
167
isError = JNI_TRUE;
168
}
169
if (isError) {
170
char buf[256];
171
jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
172
JNU_ThrowIOException(env, buf);
173
}
174
} else {
175
char* msg = strdup(strerror(res));
176
JNU_ThrowIOException(env, msg);
177
if (msg != NULL) {
178
free(msg);
179
}
180
}
181
182
if (isCopy) {
183
JNU_ReleaseStringPlatformChars(env, path, p);
184
}
185
}
186
}
187
188
/*
189
* Class: sun_tools_attach_BsdVirtualMachine
190
* Method: close
191
* Signature: (I)V
192
*/
193
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_close
194
(JNIEnv *env, jclass cls, jint fd)
195
{
196
int res;
197
RESTARTABLE(close(fd), res);
198
}
199
200
/*
201
* Class: sun_tools_attach_BsdVirtualMachine
202
* Method: read
203
* Signature: (I[BI)I
204
*/
205
JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_read
206
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen)
207
{
208
unsigned char buf[128];
209
size_t len = sizeof(buf);
210
ssize_t n;
211
212
size_t remaining = (size_t)(baLen - off);
213
if (len > remaining) {
214
len = remaining;
215
}
216
217
RESTARTABLE(read(fd, buf, len), n);
218
if (n == -1) {
219
JNU_ThrowIOExceptionWithLastError(env, "read");
220
} else {
221
if (n == 0) {
222
n = -1; // EOF
223
} else {
224
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
225
}
226
}
227
return n;
228
}
229
230
/*
231
* Class: sun_tools_attach_BsdVirtualMachine
232
* Method: write
233
* Signature: (I[B)V
234
*/
235
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_write
236
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint bufLen)
237
{
238
size_t remaining = bufLen;
239
do {
240
unsigned char buf[128];
241
size_t len = sizeof(buf);
242
int n;
243
244
if (len > remaining) {
245
len = remaining;
246
}
247
(*env)->GetByteArrayRegion(env, ba, off, len, (jbyte *)buf);
248
249
RESTARTABLE(write(fd, buf, len), n);
250
if (n > 0) {
251
off += n;
252
remaining -= n;
253
} else {
254
JNU_ThrowIOExceptionWithLastError(env, "write");
255
return;
256
}
257
258
} while (remaining > 0);
259
}
260
261
/*
262
* Class: sun_tools_attach_BSDVirtualMachine
263
* Method: createAttachFile
264
* Signature: (Ljava.lang.String;)V
265
*/
266
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_createAttachFile(JNIEnv *env, jclass cls, jstring path)
267
{
268
const char* _path;
269
jboolean isCopy;
270
int fd, rc;
271
272
_path = GetStringPlatformChars(env, path, &isCopy);
273
if (_path == NULL) {
274
JNU_ThrowIOException(env, "Must specify a path");
275
return;
276
}
277
278
RESTARTABLE(open(_path, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR), fd);
279
if (fd == -1) {
280
/* release p here before we throw an I/O exception */
281
if (isCopy) {
282
JNU_ReleaseStringPlatformChars(env, path, _path);
283
}
284
JNU_ThrowIOExceptionWithLastError(env, "open");
285
return;
286
}
287
288
RESTARTABLE(chown(_path, geteuid(), getegid()), rc);
289
290
RESTARTABLE(close(fd), rc);
291
292
/* release p here */
293
if (isCopy) {
294
JNU_ReleaseStringPlatformChars(env, path, _path);
295
}
296
}
297
298
/*
299
* Class: sun_tools_attach_BSDVirtualMachine
300
* Method: getTempDir
301
* Signature: (V)Ljava.lang.String;
302
*/
303
JNIEXPORT jstring JNICALL Java_sun_tools_attach_BsdVirtualMachine_getTempDir(JNIEnv *env, jclass cls)
304
{
305
// This must be hard coded because it's the system's temporary
306
// directory not the java application's temp directory, ala java.io.tmpdir.
307
308
#ifdef __APPLE__
309
// macosx has a secure per-user temporary directory
310
static char *temp_path = NULL;
311
char temp_path_storage[PATH_MAX];
312
if (temp_path == NULL) {
313
int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX);
314
if (pathSize == 0 || pathSize > PATH_MAX) {
315
strlcpy(temp_path_storage, "/tmp", sizeof(temp_path_storage));
316
}
317
temp_path = temp_path_storage;
318
}
319
return JNU_NewStringPlatform(env, temp_path);
320
#else /* __APPLE__ */
321
return (*env)->NewStringUTF(env, "/tmp");
322
#endif /* __APPLE__ */
323
}
324
325