Skip to content

Commit a2a5e85

Browse files
author
Daniil Titov
committed
8197387: jcmd started by "root" must be allowed to access all VM processes
Reviewed-by: sspitsyn, stuefe
1 parent dd3d243 commit a2a5e85

10 files changed

Lines changed: 58 additions & 33 deletions

File tree

src/hotspot/os/aix/attachListener_aix.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,10 @@ AixAttachOperation* AixAttachListener::dequeue() {
386386
::close(s);
387387
continue;
388388
}
389-
uid_t euid = geteuid();
390-
gid_t egid = getegid();
391389

392-
if (cred_info.euid != euid || cred_info.egid != egid) {
393-
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.euid, cred_info.egid, euid, egid);
390+
if (!os::Posix::matches_effective_uid_and_gid_or_root(cred_info.euid, cred_info.egid)) {
391+
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)",
392+
cred_info.euid, cred_info.egid, geteuid(), getegid());
394393
::close(s);
395394
continue;
396395
}
@@ -548,8 +547,8 @@ bool AttachListener::is_init_trigger() {
548547
}
549548
if (ret == 0) {
550549
// simple check to avoid starting the attach mechanism when
551-
// a bogus user creates the file
552-
if (st.st_uid == geteuid()) {
550+
// a bogus non-root user creates the file
551+
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
553552
init();
554553
log_trace(attach)("Attach triggered by %s", fn);
555554
return true;

src/hotspot/os/bsd/attachListener_bsd.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,10 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
357357
::close(s);
358358
continue;
359359
}
360-
uid_t euid = geteuid();
361-
gid_t egid = getegid();
362360

363-
if (puid != euid || pgid != egid) {
364-
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid, euid, egid);
361+
if (!os::Posix::matches_effective_uid_and_gid_or_root(puid, pgid)) {
362+
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid,
363+
geteuid(), getegid());
365364
::close(s);
366365
continue;
367366
}
@@ -513,8 +512,8 @@ bool AttachListener::is_init_trigger() {
513512
}
514513
if (ret == 0) {
515514
// simple check to avoid starting the attach mechanism when
516-
// a bogus user creates the file
517-
if (st.st_uid == geteuid()) {
515+
// a bogus non-root user creates the file
516+
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
518517
init();
519518
log_trace(attach)("Attach triggered by %s", fn);
520519
return true;

src/hotspot/os/linux/attachListener_linux.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,10 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() {
357357
::close(s);
358358
continue;
359359
}
360-
uid_t euid = geteuid();
361-
gid_t egid = getegid();
362360

363-
if (cred_info.uid != euid || cred_info.gid != egid) {
364-
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.uid, cred_info.gid, euid, egid);
361+
if (!os::Posix::matches_effective_uid_and_gid_or_root(cred_info.uid, cred_info.gid)) {
362+
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)",
363+
cred_info.uid, cred_info.gid, geteuid(), getegid());
365364
::close(s);
366365
continue;
367366
}
@@ -518,8 +517,8 @@ bool AttachListener::is_init_trigger() {
518517
}
519518
if (ret == 0) {
520519
// simple check to avoid starting the attach mechanism when
521-
// a bogus user creates the file
522-
if (st.st_uid == geteuid()) {
520+
// a bogus non-root user creates the file
521+
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
523522
init();
524523
log_trace(attach)("Attach triggered by %s", fn);
525524
return true;

src/hotspot/os/posix/os_posix.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
#endif
5252
#define IS_VALID_PID(p) (p > 0 && p < MAX_PID)
5353

54+
#define ROOT_UID 0
55+
5456
#ifndef MAP_ANONYMOUS
5557
#define MAP_ANONYMOUS MAP_ANON
5658
#endif
@@ -1454,6 +1456,18 @@ size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_s
14541456
return stack_size;
14551457
}
14561458

1459+
bool os::Posix::is_root(uid_t uid){
1460+
return ROOT_UID == uid;
1461+
}
1462+
1463+
bool os::Posix::matches_effective_uid_or_root(uid_t uid) {
1464+
return is_root(uid) || geteuid() == uid;
1465+
}
1466+
1467+
bool os::Posix::matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid) {
1468+
return is_root(uid) || (geteuid() == uid && getegid() == gid);
1469+
}
1470+
14571471
Thread* os::ThreadCrashProtection::_protected_thread = NULL;
14581472
os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;
14591473
volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0;

src/hotspot/os/posix/os_posix.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ class Posix {
106106
// On error, it will return NULL and set errno. The content of 'outbuf' is undefined.
107107
// On truncation error ('outbuf' too small), it will return NULL and set errno to ENAMETOOLONG.
108108
static char* realpath(const char* filename, char* outbuf, size_t outbuflen);
109+
110+
// Returns true if given uid is root.
111+
static bool is_root(uid_t uid);
112+
113+
// Returns true if given uid is effective or root uid.
114+
static bool matches_effective_uid_or_root(uid_t uid);
115+
116+
// Returns true if either given uid is effective uid and given gid is
117+
// effective gid, or if given uid is root.
118+
static bool matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid);
109119
};
110120

111121
// On POSIX platforms the signal handler is global so we just do the write.

src/hotspot/os/solaris/attachListener_solaris.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,12 @@ static int check_credentials() {
213213
return -1; // unable to get them, deny
214214
}
215215

216-
// get our euid/eguid (probably could cache these)
217-
uid_t euid = geteuid();
218-
gid_t egid = getegid();
219-
220216
// get euid/egid from ucred_free
221217
uid_t ucred_euid = ucred_geteuid(cred_info);
222218
gid_t ucred_egid = ucred_getegid(cred_info);
223219

224220
// check that the effective uid/gid matches
225-
if (ucred_euid == euid && ucred_egid == egid) {
221+
if (os::Posix::matches_effective_uid_and_gid_or_root(ucred_euid, ucred_egid)) {
226222
ret = 0; // allow
227223
}
228224

@@ -664,8 +660,8 @@ bool AttachListener::is_init_trigger() {
664660
}
665661
if (ret == 0) {
666662
// simple check to avoid starting the attach mechanism when
667-
// a bogus user creates the file
668-
if (st.st_uid == geteuid()) {
663+
// a bogus non-root user creates the file
664+
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
669665
init();
670666
log_trace(attach)("Attach triggered by %s", fn);
671667
return true;

src/jdk.attach/aix/native/libattach/VirtualMachineImpl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
} while(0)
4747

4848

49+
#define ROOT_UID 0
50+
4951
/*
5052
* Class: sun_tools_attach_VirtualMachineImpl
5153
* Method: socket
@@ -153,11 +155,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
153155
if (res == 0) {
154156
char msg[100];
155157
jboolean isError = JNI_FALSE;
156-
if (sb.st_uid != uid) {
158+
if (sb.st_uid != uid && uid != ROOT_UID) {
157159
snprintf(msg, sizeof(msg),
158160
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
159161
isError = JNI_TRUE;
160-
} else if (sb.st_gid != gid) {
162+
} else if (sb.st_gid != gid && uid != ROOT_UID) {
161163
snprintf(msg, sizeof(msg),
162164
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
163165
isError = JNI_TRUE;

src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
} while((_result == -1) && (errno == EINTR)); \
4545
} while(0)
4646

47+
#define ROOT_UID 0
48+
4749
/*
4850
* Declare library specific JNI_Onload entry if static build
4951
*/
@@ -156,11 +158,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
156158
if (res == 0) {
157159
char msg[100];
158160
jboolean isError = JNI_FALSE;
159-
if (sb.st_uid != uid) {
161+
if (sb.st_uid != uid && uid != ROOT_UID) {
160162
snprintf(msg, sizeof(msg),
161163
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
162164
isError = JNI_TRUE;
163-
} else if (sb.st_gid != gid) {
165+
} else if (sb.st_gid != gid && uid != ROOT_UID) {
164166
snprintf(msg, sizeof(msg),
165167
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
166168
isError = JNI_TRUE;

src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
} while((_result == -1) && (errno == EINTR)); \
4747
} while(0)
4848

49+
#define ROOT_UID 0
50+
4951
/*
5052
* Declare library specific JNI_Onload entry if static build
5153
*/
@@ -158,11 +160,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
158160
if (res == 0) {
159161
char msg[100];
160162
jboolean isError = JNI_FALSE;
161-
if (sb.st_uid != uid) {
163+
if (sb.st_uid != uid && uid != ROOT_UID) {
162164
snprintf(msg, sizeof(msg),
163165
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
164166
isError = JNI_TRUE;
165-
} else if (sb.st_gid != gid) {
167+
} else if (sb.st_gid != gid && uid != ROOT_UID) {
166168
snprintf(msg, sizeof(msg),
167169
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
168170
isError = JNI_TRUE;

src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
#include "sun_tools_attach_VirtualMachineImpl.h"
4040

41+
#define ROOT_UID 0
42+
4143
#define RESTARTABLE(_cmd, _result) do { \
4244
do { \
4345
_result = _cmd; \
@@ -122,11 +124,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
122124
if (res == 0) {
123125
char msg[100];
124126
jboolean isError = JNI_FALSE;
125-
if (sb.st_uid != uid) {
127+
if (sb.st_uid != uid && uid != ROOT_UID) {
126128
snprintf(msg, sizeof(msg),
127129
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
128130
isError = JNI_TRUE;
129-
} else if (sb.st_gid != gid) {
131+
} else if (sb.st_gid != gid && uid != ROOT_UID) {
130132
snprintf(msg, sizeof(msg),
131133
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
132134
isError = JNI_TRUE;

0 commit comments

Comments
 (0)