Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.attach/aix/native/libattach/VirtualMachineImpl.c
40957 views
1
/*
2
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2015, 2018 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
#include "jni_util.h"
28
29
#include <sys/socket.h>
30
#include <sys/stat.h>
31
#include <sys/types.h>
32
#include <sys/un.h>
33
#include <errno.h>
34
#include <signal.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
40
#include "sun_tools_attach_VirtualMachineImpl.h"
41
42
#define RESTARTABLE(_cmd, _result) do { \
43
do { \
44
_result = _cmd; \
45
} while((_result == -1) && (errno == EINTR)); \
46
} while(0)
47
48
49
#define ROOT_UID 0
50
51
/*
52
* Class: sun_tools_attach_VirtualMachineImpl
53
* Method: socket
54
* Signature: ()I
55
*/
56
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_socket
57
(JNIEnv *env, jclass cls)
58
{
59
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
60
if (fd == -1) {
61
JNU_ThrowIOExceptionWithLastError(env, "socket");
62
}
63
return (jint)fd;
64
}
65
66
/*
67
* Class: sun_tools_attach_VirtualMachineImpl
68
* Method: connect
69
* Signature: (ILjava/lang/String;)I
70
*/
71
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
72
(JNIEnv *env, jclass cls, jint fd, jstring path)
73
{
74
jboolean isCopy;
75
const char* p = GetStringPlatformChars(env, path, &isCopy);
76
if (p != NULL) {
77
struct sockaddr_un addr;
78
int err = 0;
79
80
memset(&addr, 0, sizeof(addr));
81
addr.sun_family = AF_UNIX;
82
/* strncpy is safe because addr.sun_path was zero-initialized before. */
83
strncpy(addr.sun_path, p, sizeof(addr.sun_path) - 1);
84
/* We must call bind with the actual socketaddr length. This is obligatory for AS400. */
85
if (connect(fd, (struct sockaddr*)&addr, SUN_LEN(&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_VirtualMachineImpl
114
* Method: sendQuitTo
115
* Signature: (I)V
116
*/
117
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_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_VirtualMachineImpl
127
* Method: checkPermissions
128
* Signature: (Ljava/lang/String;)V
129
*/
130
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_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 stat64 sb;
137
uid_t uid, gid;
138
int res;
139
140
memset(&sb, 0, sizeof(struct stat64));
141
142
/*
143
* Check that the path is owned by the effective uid/gid of this
144
* process. Also check that group/other access is not allowed.
145
*/
146
uid = geteuid();
147
gid = getegid();
148
149
res = stat64(p, &sb);
150
if (res != 0) {
151
/* save errno */
152
res = errno;
153
}
154
155
if (res == 0) {
156
char msg[100];
157
jboolean isError = JNI_FALSE;
158
if (sb.st_uid != uid && uid != ROOT_UID) {
159
snprintf(msg, sizeof(msg),
160
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
161
isError = JNI_TRUE;
162
} else if (sb.st_gid != gid && uid != ROOT_UID) {
163
snprintf(msg, sizeof(msg),
164
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
165
isError = JNI_TRUE;
166
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
167
snprintf(msg, sizeof(msg),
168
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
169
isError = JNI_TRUE;
170
}
171
if (isError) {
172
char buf[256];
173
snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg);
174
JNU_ThrowIOException(env, buf);
175
}
176
} else {
177
char* msg = strdup(strerror(res));
178
JNU_ThrowIOException(env, msg);
179
if (msg != NULL) {
180
free(msg);
181
}
182
}
183
184
if (isCopy) {
185
JNU_ReleaseStringPlatformChars(env, path, p);
186
}
187
}
188
}
189
190
/*
191
* Class: sun_tools_attach_VirtualMachineImpl
192
* Method: close
193
* Signature: (I)V
194
*/
195
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close
196
(JNIEnv *env, jclass cls, jint fd)
197
{
198
int res;
199
shutdown(fd, SHUT_RDWR);
200
RESTARTABLE(close(fd), res);
201
}
202
203
/*
204
* Class: sun_tools_attach_VirtualMachineImpl
205
* Method: read
206
* Signature: (I[BI)I
207
*/
208
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_read
209
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen)
210
{
211
unsigned char buf[128];
212
size_t len = sizeof(buf);
213
ssize_t n;
214
215
size_t remaining = (size_t)(baLen - off);
216
if (len > remaining) {
217
len = remaining;
218
}
219
220
RESTARTABLE(read(fd, buf, len), n);
221
if (n == -1) {
222
JNU_ThrowIOExceptionWithLastError(env, "read");
223
} else {
224
if (n == 0) {
225
n = -1; // EOF
226
} else {
227
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
228
}
229
}
230
return n;
231
}
232
233
/*
234
* Class: sun_tools_attach_VirtualMachineImpl
235
* Method: write
236
* Signature: (I[B)V
237
*/
238
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_write
239
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint bufLen)
240
{
241
size_t remaining = bufLen;
242
do {
243
unsigned char buf[128];
244
size_t len = sizeof(buf);
245
int n;
246
247
if (len > remaining) {
248
len = remaining;
249
}
250
(*env)->GetByteArrayRegion(env, ba, off, len, (jbyte *)buf);
251
252
RESTARTABLE(write(fd, buf, len), n);
253
if (n > 0) {
254
off += n;
255
remaining -= n;
256
} else {
257
JNU_ThrowIOExceptionWithLastError(env, "write");
258
return;
259
}
260
261
} while (remaining > 0);
262
}
263
264