From 37862f19861c8618281da2377281411c61cb733f Mon Sep 17 00:00:00 2001 From: aph Date: Fri, 3 Apr 2020 14:14:26 +0100 Subject: [PATCH] 8076475: Misuses of strncpy/strncat Summary: Various small fixes around strncpy and strncat Reviewed-by: andrew --- agent/src/os/bsd/libproc_impl.c | 7 ++++++- agent/src/os/linux/libproc_impl.c | 7 ++++++- src/os/bsd/dtrace/libjvm_db.c | 19 ++++++++++--------- src/os/bsd/vm/decoder_machO.cpp | 1 + src/os/solaris/dtrace/libjvm_db.c | 19 ++++++++++--------- src/share/tools/hsdis/hsdis.c | 1 + src/share/vm/compiler/compileBroker.hpp | 3 ++- src/share/vm/compiler/disassembler.cpp | 1 + src/share/vm/runtime/arguments.cpp | 17 ++++++----------- src/share/vm/utilities/ostream.cpp | 12 ++++++++---- src/share/vm/utilities/vmError.cpp | 9 +-------- 11 files changed, 52 insertions(+), 44 deletions(-) diff --git a/agent/src/os/bsd/libproc_impl.c b/agent/src/os/bsd/libproc_impl.c index 78da80617..b8ba361b8 100644 --- a/agent/src/os/bsd/libproc_impl.c +++ b/agent/src/os/bsd/libproc_impl.c @@ -215,7 +215,12 @@ lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, return NULL; } - strncpy(newlib->name, libname, sizeof(newlib->name)); + if (strlen(libname) >= sizeof(newlib->name)) { + print_debug("libname %s too long\n", libname); + return NULL; + } + strcpy(newlib->name, libname); + newlib->base = base; if (fd == -1) { diff --git a/agent/src/os/linux/libproc_impl.c b/agent/src/os/linux/libproc_impl.c index ca791c95d..73a15ce35 100644 --- a/agent/src/os/linux/libproc_impl.c +++ b/agent/src/os/linux/libproc_impl.c @@ -159,7 +159,12 @@ lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, return NULL; } - strncpy(newlib->name, libname, sizeof(newlib->name)); + if (strlen(libname) >= sizeof(newlib->name)) { + print_debug("libname %s too long\n", libname); + return NULL; + } + strcpy(newlib->name, libname); + newlib->base = base; if (fd == -1) { diff --git a/src/os/bsd/dtrace/libjvm_db.c b/src/os/bsd/dtrace/libjvm_db.c index 169a0e93c..b55900a9b 100644 --- a/src/os/bsd/dtrace/libjvm_db.c +++ b/src/os/bsd/dtrace/libjvm_db.c @@ -543,13 +543,14 @@ name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t siz CHECK_FAIL(err); result[0] = '\0'; - strncat(result, klassString, size); - size -= strlen(klassString); - strncat(result, ".", size); - size -= 1; - strncat(result, nameString, size); - size -= strlen(nameString); - strncat(result, signatureString, size); + if (snprintf(result, size, + "%s.%s%s", + klassString, + nameString, + signatureString) >= size) { + // truncation + goto fail; + } if (nameString != NULL) free(nameString); if (klassString != NULL) free(klassString); @@ -1056,9 +1057,9 @@ name_for_nmethod(jvm_agent_t* J, CHECK_FAIL(err); } if (deoptimized) { - strncat(result + 1, " [deoptimized frame]; ", size-1); + strncat(result, " [deoptimized frame]; ", size - strlen(result) - 1); } else { - strncat(result + 1, " [compiled] ", size-1); + strncat(result, " [compiled] ", size - strlen(result) - 1); } if (debug) fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n", diff --git a/src/os/bsd/vm/decoder_machO.cpp b/src/os/bsd/vm/decoder_machO.cpp index 6ef6314a1..5026ea834 100644 --- a/src/os/bsd/vm/decoder_machO.cpp +++ b/src/os/bsd/vm/decoder_machO.cpp @@ -97,6 +97,7 @@ bool MachODecoder::decode(address addr, char *buf, char * symname = mach_find_in_stringtable((char*) ((uintptr_t)mach_base + stroff), strsize, found_strx); if (symname) { strncpy(buf, symname, buflen); + buf[buflen - 1] = '\0'; return true; } DEBUG_ONLY(tty->print_cr("no string or null string found.")); diff --git a/src/os/solaris/dtrace/libjvm_db.c b/src/os/solaris/dtrace/libjvm_db.c index a3830145c..1d2369b25 100644 --- a/src/os/solaris/dtrace/libjvm_db.c +++ b/src/os/solaris/dtrace/libjvm_db.c @@ -543,13 +543,14 @@ name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t siz CHECK_FAIL(err); result[0] = '\0'; - strncat(result, klassString, size); - size -= strlen(klassString); - strncat(result, ".", size); - size -= 1; - strncat(result, nameString, size); - size -= strlen(nameString); - strncat(result, signatureString, size); + if (snprintf(result, size, + "%s.%s%s", + klassString, + nameString, + signatureString) >= size) { + // truncation + goto fail; + } if (nameString != NULL) free(nameString); if (klassString != NULL) free(klassString); @@ -1056,9 +1057,9 @@ name_for_nmethod(jvm_agent_t* J, CHECK_FAIL(err); } if (deoptimized) { - strncat(result + 1, " [deoptimized frame]; ", size-1); + strncat(result, " [deoptimized frame]; ", size - strlen(result) - 1); } else { - strncat(result + 1, " [compiled] ", size-1); + strncat(result, " [compiled] ", size - strlen(result) - 1); } if (debug) fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n", diff --git a/src/share/tools/hsdis/hsdis.c b/src/share/tools/hsdis/hsdis.c index 7bef1040f..1907d479e 100644 --- a/src/share/tools/hsdis/hsdis.c +++ b/src/share/tools/hsdis/hsdis.c @@ -438,6 +438,7 @@ static void parse_caller_options(struct hsdis_app_data* app_data, const char* ca } p = q; } + *iop = '\0'; } static void print_help(struct hsdis_app_data* app_data, diff --git a/src/share/vm/compiler/compileBroker.hpp b/src/share/vm/compiler/compileBroker.hpp index ad37ff173..16e0ba3aa 100644 --- a/src/share/vm/compiler/compileBroker.hpp +++ b/src/share/vm/compiler/compileBroker.hpp @@ -173,7 +173,8 @@ class CompilerCounters : public CHeapObj { // these methods should be called in a thread safe context void set_current_method(const char* method) { - strncpy(_current_method, method, (size_t)cmname_buffer_length); + strncpy(_current_method, method, (size_t)cmname_buffer_length-1); + _current_method[cmname_buffer_length-1] = '\0'; if (UsePerfData) _perf_current_method->set_value(method); } diff --git a/src/share/vm/compiler/disassembler.cpp b/src/share/vm/compiler/disassembler.cpp index 93cd9e854..e7b32cd6b 100644 --- a/src/share/vm/compiler/disassembler.cpp +++ b/src/share/vm/compiler/disassembler.cpp @@ -295,6 +295,7 @@ address decode_env::handle_event(const char* event, address arg) { strlen((const char*)arg) > sizeof(buffer) - 1) { // Only print this when the mach changes strncpy(buffer, (const char*)arg, sizeof(buffer) - 1); + buffer[sizeof(buffer) - 1] = '\0'; output()->print_cr("[Disassembling for mach='%s']", arg); } } else if (match(event, "format bytes-per-line")) { diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp index 574122253..be3cc3923 100644 --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -3476,8 +3476,7 @@ void Arguments::fix_appclasspath() { src ++; } - char* copy = AllocateHeap(strlen(src) + 1, mtInternal); - strncpy(copy, src, strlen(src) + 1); + char* copy = os::strdup(src, mtInternal); // trim all trailing empty paths for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) { @@ -3856,18 +3855,14 @@ static char* get_shared_archive_path() { if (end != NULL) *end = '\0'; size_t jvm_path_len = strlen(jvm_path); size_t file_sep_len = strlen(os::file_separator()); - shared_archive_path = NEW_C_HEAP_ARRAY(char, jvm_path_len + - file_sep_len + 20, mtInternal); + const size_t len = jvm_path_len + file_sep_len + 20; + shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtInternal); if (shared_archive_path != NULL) { - strncpy(shared_archive_path, jvm_path, jvm_path_len + 1); - strncat(shared_archive_path, os::file_separator(), file_sep_len); - strncat(shared_archive_path, "classes.jsa", 11); + jio_snprintf(shared_archive_path, len, "%s%sclasses.jsa", + jvm_path, os::file_separator()); } } else { - shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(SharedArchiveFile) + 1, mtInternal); - if (shared_archive_path != NULL) { - strncpy(shared_archive_path, SharedArchiveFile, strlen(SharedArchiveFile) + 1); - } + shared_archive_path = os::strdup(SharedArchiveFile, mtInternal); } return shared_archive_path; } diff --git a/src/share/vm/utilities/ostream.cpp b/src/share/vm/utilities/ostream.cpp index df115b396..fc17aeb04 100644 --- a/src/share/vm/utilities/ostream.cpp +++ b/src/share/vm/utilities/ostream.cpp @@ -344,15 +344,19 @@ void stringStream::write(const char* s, size_t len) { assert(rm == NULL || Thread::current()->current_resource_mark() == rm, "stringStream is re-allocated with a different ResourceMark"); buffer = NEW_RESOURCE_ARRAY(char, end); - strncpy(buffer, oldbuf, buffer_pos); + if (buffer_pos > 0) { + memcpy(buffer, oldbuf, buffer_pos); + } buffer_length = end; } } // invariant: buffer is always null-terminated guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); - buffer[buffer_pos + write_len] = 0; - strncpy(buffer + buffer_pos, s, write_len); - buffer_pos += write_len; + if (write_len > 0) { + buffer[buffer_pos + write_len] = 0; + memcpy(buffer + buffer_pos, s, write_len); + buffer_pos += write_len; + } // Note that the following does not depend on write_len. // This means that position and count get updated diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp index f883cfeab..e5aad6ff2 100644 --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -455,14 +455,7 @@ void VMError::report(outputStream* st) { #else const char *file = _filename; #endif - size_t len = strlen(file); - size_t buflen = sizeof(buf); - - strncpy(buf, file, buflen); - if (len + 10 < buflen) { - sprintf(buf + len, ":%d", _lineno); - } - st->print(" (%s)", buf); + st->print(" (%s:%d)", file, _lineno); } else { st->print(" (0x%x)", _id); } -- GitLab