8299665: /proc/self/stat parsing in libmanagement broken by execname with spaces

Reviewed-by: sspitsyn, amenkov
This commit is contained in:
Kevin Walls 2023-05-26 10:51:39 +00:00
parent c494770ca0
commit 17ef8a44a9
4 changed files with 36 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,8 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <pthread.h> #include <pthread.h>
#include <inttypes.h> #include <inttypes.h>
#include "management_ext.h"
#include "com_sun_management_internal_OperatingSystemImpl.h" #include "com_sun_management_internal_OperatingSystemImpl.h"
#include <assert.h> #include <assert.h>
@ -331,6 +333,26 @@ double get_process_load() {
return u + s; return u + s;
} }
static long read_vmem_usage(const char *procfile, unsigned long *vsize) {
int n = read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", vsize);
if (n != 1) {
return -1;
} else {
return *vsize;
}
}
JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0
(JNIEnv *env, jobject mbean)
{
unsigned long vsize;
if (read_vmem_usage("/proc/self/stat", &vsize) == -1) {
throw_internal_error(env, "Unable to get virtual memory usage");
}
return (jlong) vsize;
}
JNIEXPORT jdouble JNICALL JNIEXPORT jdouble JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0
(JNIEnv *env, jobject dummy) (JNIEnv *env, jobject dummy)

View File

@ -35,6 +35,13 @@ const JmmInterface* jmm_interface_management_ext = NULL;
static JavaVM* jvm = NULL; static JavaVM* jvm = NULL;
jint jmm_version_management_ext = 0; jint jmm_version_management_ext = 0;
void throw_internal_error(JNIEnv* env, const char* msg) {
char errmsg[128];
snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg);
JNU_ThrowInternalError(env, errmsg);
}
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
DEF_JNI_OnLoad(JavaVM *vm, void *reserved) { DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env; JNIEnv* env;

View File

@ -37,4 +37,6 @@
extern const JmmInterface* jmm_interface_management_ext; extern const JmmInterface* jmm_interface_management_ext;
extern jint jmm_version_management_ext; extern jint jmm_version_management_ext;
void throw_internal_error(JNIEnv* env, const char* msg);
#endif #endif

View File

@ -82,13 +82,6 @@ static jlong page_size = 0;
#define closedir closedir64 #define closedir closedir64
#endif #endif
static void throw_internal_error(JNIEnv* env, const char* msg) {
char errmsg[128];
snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg);
JNU_ThrowInternalError(env, errmsg);
}
// true = get available swap in bytes // true = get available swap in bytes
// false = get total swap in bytes // false = get total swap in bytes
static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) { static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) {
@ -129,29 +122,13 @@ Java_com_sun_management_internal_OperatingSystemImpl_initialize0
page_size = sysconf(_SC_PAGESIZE); page_size = sysconf(_SC_PAGESIZE);
} }
// Linux-specific implementation is in UnixOperatingSystem.c
#if !defined(__linux__)
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0
(JNIEnv *env, jobject mbean) (JNIEnv *env, jobject mbean)
{ {
#if defined(__linux__) #if defined(__APPLE__)
FILE *fp;
unsigned long vsize = 0;
if ((fp = fopen("/proc/self/stat", "r")) == NULL) {
throw_internal_error(env, "Unable to open /proc/self/stat");
return -1;
}
// Ignore everything except the vsize entry
if (fscanf(fp, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", &vsize) == EOF) {
throw_internal_error(env, "Unable to get virtual memory usage");
fclose(fp);
return -1;
}
fclose(fp);
return (jlong)vsize;
#elif defined(__APPLE__)
struct task_basic_info t_info; struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
@ -168,6 +145,7 @@ Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySi
return (64 * MB); return (64 * MB);
#endif #endif
} }
#endif
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0 Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0