8197387: jcmd started by "root" must be allowed to access all VM processes
Reviewed-by: sspitsyn, stuefe
This commit is contained in:
parent
dd3d24341b
commit
a2a5e85195
@ -386,11 +386,10 @@ AixAttachOperation* AixAttachListener::dequeue() {
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
uid_t euid = geteuid();
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (cred_info.euid != euid || cred_info.egid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.euid, cred_info.egid, euid, egid);
|
||||
if (!os::Posix::matches_effective_uid_and_gid_or_root(cred_info.euid, cred_info.egid)) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)",
|
||||
cred_info.euid, cred_info.egid, geteuid(), getegid());
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -548,8 +547,8 @@ bool AttachListener::is_init_trigger() {
|
||||
}
|
||||
if (ret == 0) {
|
||||
// simple check to avoid starting the attach mechanism when
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
// a bogus non-root user creates the file
|
||||
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
|
||||
init();
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
|
@ -357,11 +357,10 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
uid_t euid = geteuid();
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (puid != euid || pgid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid, euid, egid);
|
||||
if (!os::Posix::matches_effective_uid_and_gid_or_root(puid, pgid)) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid,
|
||||
geteuid(), getegid());
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -513,8 +512,8 @@ bool AttachListener::is_init_trigger() {
|
||||
}
|
||||
if (ret == 0) {
|
||||
// simple check to avoid starting the attach mechanism when
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
// a bogus non-root user creates the file
|
||||
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
|
||||
init();
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
|
@ -357,11 +357,10 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() {
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
uid_t euid = geteuid();
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (cred_info.uid != euid || cred_info.gid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.uid, cred_info.gid, euid, egid);
|
||||
if (!os::Posix::matches_effective_uid_and_gid_or_root(cred_info.uid, cred_info.gid)) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)",
|
||||
cred_info.uid, cred_info.gid, geteuid(), getegid());
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -518,8 +517,8 @@ bool AttachListener::is_init_trigger() {
|
||||
}
|
||||
if (ret == 0) {
|
||||
// simple check to avoid starting the attach mechanism when
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
// a bogus non-root user creates the file
|
||||
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
|
||||
init();
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
|
@ -51,6 +51,8 @@
|
||||
#endif
|
||||
#define IS_VALID_PID(p) (p > 0 && p < MAX_PID)
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
@ -1454,6 +1456,18 @@ size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_s
|
||||
return stack_size;
|
||||
}
|
||||
|
||||
bool os::Posix::is_root(uid_t uid){
|
||||
return ROOT_UID == uid;
|
||||
}
|
||||
|
||||
bool os::Posix::matches_effective_uid_or_root(uid_t uid) {
|
||||
return is_root(uid) || geteuid() == uid;
|
||||
}
|
||||
|
||||
bool os::Posix::matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid) {
|
||||
return is_root(uid) || (geteuid() == uid && getegid() == gid);
|
||||
}
|
||||
|
||||
Thread* os::ThreadCrashProtection::_protected_thread = NULL;
|
||||
os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;
|
||||
volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0;
|
||||
|
@ -106,6 +106,16 @@ public:
|
||||
// On error, it will return NULL and set errno. The content of 'outbuf' is undefined.
|
||||
// On truncation error ('outbuf' too small), it will return NULL and set errno to ENAMETOOLONG.
|
||||
static char* realpath(const char* filename, char* outbuf, size_t outbuflen);
|
||||
|
||||
// Returns true if given uid is root.
|
||||
static bool is_root(uid_t uid);
|
||||
|
||||
// Returns true if given uid is effective or root uid.
|
||||
static bool matches_effective_uid_or_root(uid_t uid);
|
||||
|
||||
// Returns true if either given uid is effective uid and given gid is
|
||||
// effective gid, or if given uid is root.
|
||||
static bool matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid);
|
||||
};
|
||||
|
||||
// On POSIX platforms the signal handler is global so we just do the write.
|
||||
|
@ -213,16 +213,12 @@ static int check_credentials() {
|
||||
return -1; // unable to get them, deny
|
||||
}
|
||||
|
||||
// get our euid/eguid (probably could cache these)
|
||||
uid_t euid = geteuid();
|
||||
gid_t egid = getegid();
|
||||
|
||||
// get euid/egid from ucred_free
|
||||
uid_t ucred_euid = ucred_geteuid(cred_info);
|
||||
gid_t ucred_egid = ucred_getegid(cred_info);
|
||||
|
||||
// check that the effective uid/gid matches
|
||||
if (ucred_euid == euid && ucred_egid == egid) {
|
||||
if (os::Posix::matches_effective_uid_and_gid_or_root(ucred_euid, ucred_egid)) {
|
||||
ret = 0; // allow
|
||||
}
|
||||
|
||||
@ -664,8 +660,8 @@ bool AttachListener::is_init_trigger() {
|
||||
}
|
||||
if (ret == 0) {
|
||||
// simple check to avoid starting the attach mechanism when
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
// a bogus non-root user creates the file
|
||||
if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
|
||||
init();
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
|
@ -46,6 +46,8 @@
|
||||
} while(0)
|
||||
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: socket
|
||||
@ -153,11 +155,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
if (res == 0) {
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
if (sb.st_uid != uid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"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) {
|
||||
} else if (sb.st_gid != gid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
|
@ -44,6 +44,8 @@
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
/*
|
||||
* Declare library specific JNI_Onload entry if static build
|
||||
*/
|
||||
@ -156,11 +158,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
if (res == 0) {
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
if (sb.st_uid != uid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"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) {
|
||||
} else if (sb.st_gid != gid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
|
@ -46,6 +46,8 @@
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
/*
|
||||
* Declare library specific JNI_Onload entry if static build
|
||||
*/
|
||||
@ -158,11 +160,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
if (res == 0) {
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
if (sb.st_uid != uid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"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) {
|
||||
} else if (sb.st_gid != gid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
@ -122,11 +124,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
if (res == 0) {
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
if (sb.st_uid != uid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"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) {
|
||||
} else if (sb.st_gid != gid && uid != ROOT_UID) {
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user